From: Junchang Wang Date: Mon, 5 Mar 2012 17:13:05 +0000 (+0000) Subject: 8139too: Add 64bit statistics X-Git-Tag: v2.6.39-400.9.0~423^2~19^2~11^2~3 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=40c1bd48a53046438077e4047a73eb17877158a5;p=users%2Fjedix%2Flinux-maple.git 8139too: Add 64bit statistics Switch to use ndo_get_stats64 to get 64bit statistics. Two sync entries are used (one for Rx and one for Tx). (cherry picked from commit 9184a22701ed257974e7950be11da4cbd3116c63) Signed-off-by: Junchang Wang Signed-off-by: David S. Miller Signed-off-by: Joe Jin --- diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 33b577a577c0..415ff1526616 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -564,6 +564,12 @@ struct rtl_extra_stats { unsigned long rx_lost_in_ring; }; +struct rtl8139_stats { + u64 packets; + u64 bytes; + struct u64_stats_sync syncp; +}; + struct rtl8139_private { void __iomem *mmio_addr; int drv_flags; @@ -574,11 +580,13 @@ struct rtl8139_private { unsigned char *rx_ring; unsigned int cur_rx; /* RX buf index of next pkt */ + struct rtl8139_stats rx_stats; dma_addr_t rx_ring_dma; unsigned int tx_flag; unsigned long cur_tx; unsigned long dirty_tx; + struct rtl8139_stats tx_stats; unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */ unsigned char *tx_bufs; /* Tx bounce buffer region. */ dma_addr_t tx_bufs_dma; @@ -640,7 +648,9 @@ static int rtl8139_poll(struct napi_struct *napi, int budget); static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance); static int rtl8139_close (struct net_device *dev); static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); +static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 + *stats); static void rtl8139_set_rx_mode (struct net_device *dev); static void __set_rx_mode (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev); @@ -910,7 +920,7 @@ err_out: static const struct net_device_ops rtl8139_netdev_ops = { .ndo_open = rtl8139_open, .ndo_stop = rtl8139_close, - .ndo_get_stats = rtl8139_get_stats, + .ndo_get_stats64 = rtl8139_get_stats64, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = rtl8139_set_mac_address, @@ -1776,8 +1786,10 @@ static void rtl8139_tx_interrupt (struct net_device *dev, dev->stats.tx_fifo_errors++; } dev->stats.collisions += (txstatus >> 24) & 15; - dev->stats.tx_bytes += txstatus & 0x7ff; - dev->stats.tx_packets++; + u64_stats_update_begin(&tp->tx_stats.syncp); + tp->tx_stats.packets++; + tp->tx_stats.bytes += txstatus & 0x7ff; + u64_stats_update_end(&tp->tx_stats.syncp); } dirty_tx++; @@ -1997,8 +2009,10 @@ no_early_rx: skb->protocol = eth_type_trans (skb, dev); - dev->stats.rx_bytes += pkt_size; - dev->stats.rx_packets++; + u64_stats_update_begin(&tp->rx_stats.syncp); + tp->rx_stats.packets++; + tp->rx_stats.bytes += pkt_size; + u64_stats_update_end(&tp->rx_stats.syncp); netif_receive_skb (skb); } else { @@ -2462,11 +2476,13 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } -static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) +static struct rtnl_link_stats64 * +rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { struct rtl8139_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; + unsigned int start; if (netif_running(dev)) { spin_lock_irqsave (&tp->lock, flags); @@ -2475,7 +2491,21 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) spin_unlock_irqrestore (&tp->lock, flags); } - return &dev->stats; + netdev_stats_to_stats64(stats, &dev->stats); + + do { + start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp); + stats->rx_packets = tp->rx_stats.packets; + stats->rx_bytes = tp->rx_stats.bytes; + } while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start)); + + do { + start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp); + stats->tx_packets = tp->tx_stats.packets; + stats->tx_bytes = tp->tx_stats.bytes; + } while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start)); + + return stats; } /* Set or clear the multicast filter for this adaptor.