r8169: add 64bit statistics.
authorJunchang Wang <junchangwang@gmail.com>
Sun, 4 Mar 2012 22:30:32 +0000 (23:30 +0100)
committerFrancois Romieu <romieu@fr.zoreil.com>
Mon, 5 Mar 2012 23:23:51 +0000 (00:23 +0100)
Switch to use ndo_get_stats64 to get 64bit statistics.
Two sync entries are used (one for Rx and one for Tx).

Signed-off-by: Junchang Wang <junchangwang@gmail.com>
Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
drivers/net/ethernet/realtek/r8169.c

index fbd855b..a4d7674 100644 (file)
@@ -675,6 +675,12 @@ enum rtl_flag {
        RTL_FLAG_MAX
 };
 
+struct rtl8169_stats {
+       u64                     packets;
+       u64                     bytes;
+       struct u64_stats_sync   syncp;
+};
+
 struct rtl8169_private {
        void __iomem *mmio_addr;        /* memory map physical address */
        struct pci_dev *pci_dev;
@@ -687,6 +693,8 @@ struct rtl8169_private {
        u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
        u32 dirty_rx;
        u32 dirty_tx;
+       struct rtl8169_stats rx_stats;
+       struct rtl8169_stats tx_stats;
        struct TxDesc *TxDescArray;     /* 256-aligned Tx descriptor ring */
        struct RxDesc *RxDescArray;     /* 256-aligned Rx descriptor ring */
        dma_addr_t TxPhyAddr;
@@ -775,7 +783,9 @@ static void rtl_hw_start(struct net_device *dev);
 static int rtl8169_close(struct net_device *dev);
 static void rtl_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
-static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
+static struct rtnl_link_stats64 *rtl8169_get_stats64(struct net_device *dev,
+                                                   struct rtnl_link_stats64
+                                                   *stats);
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
 static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct napi_struct *napi, int budget);
@@ -3521,7 +3531,7 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
 static const struct net_device_ops rtl8169_netdev_ops = {
        .ndo_open               = rtl8169_open,
        .ndo_stop               = rtl8169_close,
-       .ndo_get_stats          = rtl8169_get_stats,
+       .ndo_get_stats64        = rtl8169_get_stats64,
        .ndo_start_xmit         = rtl8169_start_xmit,
        .ndo_tx_timeout         = rtl8169_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
@@ -5658,8 +5668,10 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
                rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
                                     tp->TxDescArray + entry);
                if (status & LastFrag) {
-                       dev->stats.tx_packets++;
-                       dev->stats.tx_bytes += tx_skb->skb->len;
+                       u64_stats_update_begin(&tp->tx_stats.syncp);
+                       tp->tx_stats.packets++;
+                       tp->tx_stats.bytes += tx_skb->skb->len;
+                       u64_stats_update_end(&tp->tx_stats.syncp);
                        dev_kfree_skb(tx_skb->skb);
                        tx_skb->skb = NULL;
                }
@@ -5807,8 +5819,10 @@ process_pkt:
 
                        napi_gro_receive(&tp->napi, skb);
 
-                       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);
                }
 
                /* Work around for AMD plateform. */
@@ -6069,21 +6083,38 @@ static void rtl_set_rx_mode(struct net_device *dev)
        RTL_W32(RxConfig, tmp);
 }
 
-/**
- *  rtl8169_get_stats - Get rtl8169 read/write statistics
- *  @dev: The Ethernet Device to get statistics for
- *
- *  Get TX/RX statistics for rtl8169
- */
-static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *
+rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
+       unsigned int start;
 
        if (netif_running(dev))
                rtl8169_rx_missed(dev, ioaddr);
 
-       return &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));
+
+       stats->rx_dropped       = dev->stats.rx_dropped;
+       stats->tx_dropped       = dev->stats.tx_dropped;
+       stats->rx_length_errors = dev->stats.rx_length_errors;
+       stats->rx_errors        = dev->stats.rx_errors;
+       stats->rx_crc_errors    = dev->stats.rx_crc_errors;
+       stats->rx_fifo_errors   = dev->stats.rx_fifo_errors;
+       stats->rx_missed_errors = dev->stats.rx_missed_errors;
+
+       return stats;
 }
 
 static void rtl8169_net_suspend(struct net_device *dev)