]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
bnxt_en: Save ring statistics before reset.
authorMichael Chan <michael.chan@broadcom.com>
Sun, 16 Dec 2018 23:46:29 +0000 (18:46 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 18 Dec 2018 07:08:53 +0000 (23:08 -0800)
With the current driver, the statistics reported by .ndo_get_stats64()
are reset when the device goes down.  Store a snapshot of the
rtnl_link_stats64 before shutdown.  This snapshot is added to the
current counters in .ndo_get_stats64() so that the counters will not
get reset when the device is down.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h

index a57f4409153bd6df350af62f09216bc982c21a7a..939c22812e72a7a033ac57a034dee74963777f67 100644 (file)
@@ -8333,6 +8333,9 @@ static bool bnxt_drv_busy(struct bnxt *bp)
                test_bit(BNXT_STATE_READ_STATS, &bp->state));
 }
 
+static void bnxt_get_ring_stats(struct bnxt *bp,
+                               struct rtnl_link_stats64 *stats);
+
 static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
                             bool link_re_init)
 {
@@ -8358,6 +8361,9 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
        del_timer_sync(&bp->timer);
        bnxt_free_skbs(bp);
 
+       /* Save ring stats before shutdown */
+       if (bp->bnapi)
+               bnxt_get_ring_stats(bp, &bp->net_stats_prev);
        if (irq_re_init) {
                bnxt_free_irq(bp);
                bnxt_del_napi(bp);
@@ -8419,23 +8425,12 @@ static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return -EOPNOTSUPP;
 }
 
-static void
-bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+static void bnxt_get_ring_stats(struct bnxt *bp,
+                               struct rtnl_link_stats64 *stats)
 {
-       u32 i;
-       struct bnxt *bp = netdev_priv(dev);
+       int i;
 
-       set_bit(BNXT_STATE_READ_STATS, &bp->state);
-       /* Make sure bnxt_close_nic() sees that we are reading stats before
-        * we check the BNXT_STATE_OPEN flag.
-        */
-       smp_mb__after_atomic();
-       if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
-               clear_bit(BNXT_STATE_READ_STATS, &bp->state);
-               return;
-       }
 
-       /* TODO check if we need to synchronize with bnxt_close path */
        for (i = 0; i < bp->cp_nr_rings; i++) {
                struct bnxt_napi *bnapi = bp->bnapi[i];
                struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
@@ -8464,6 +8459,40 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 
                stats->tx_dropped += le64_to_cpu(hw_stats->tx_drop_pkts);
        }
+}
+
+static void bnxt_add_prev_stats(struct bnxt *bp,
+                               struct rtnl_link_stats64 *stats)
+{
+       struct rtnl_link_stats64 *prev_stats = &bp->net_stats_prev;
+
+       stats->rx_packets += prev_stats->rx_packets;
+       stats->tx_packets += prev_stats->tx_packets;
+       stats->rx_bytes += prev_stats->rx_bytes;
+       stats->tx_bytes += prev_stats->tx_bytes;
+       stats->rx_missed_errors += prev_stats->rx_missed_errors;
+       stats->multicast += prev_stats->multicast;
+       stats->tx_dropped += prev_stats->tx_dropped;
+}
+
+static void
+bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+{
+       struct bnxt *bp = netdev_priv(dev);
+
+       set_bit(BNXT_STATE_READ_STATS, &bp->state);
+       /* Make sure bnxt_close_nic() sees that we are reading stats before
+        * we check the BNXT_STATE_OPEN flag.
+        */
+       smp_mb__after_atomic();
+       if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
+               clear_bit(BNXT_STATE_READ_STATS, &bp->state);
+               *stats = bp->net_stats_prev;
+               return;
+       }
+
+       bnxt_get_ring_stats(bp, stats);
+       bnxt_add_prev_stats(bp, stats);
 
        if (bp->flags & BNXT_FLAG_PORT_STATS) {
                struct rx_port_stats *rx = bp->hw_rx_port_stats;
index 3c6a39d99f1ff674fa39c635c9f9dc886807b0ed..4fdfd7a87805c4ef2b4c1bd98bbd90c4001f8ecc 100644 (file)
@@ -1472,6 +1472,7 @@ struct bnxt {
        void                    *hwrm_cmd_resp_addr;
        dma_addr_t              hwrm_cmd_resp_dma_addr;
 
+       struct rtnl_link_stats64        net_stats_prev;
        struct rx_port_stats    *hw_rx_port_stats;
        struct tx_port_stats    *hw_tx_port_stats;
        struct rx_port_stats_ext        *hw_rx_port_stats_ext;