Re: [PATCH net-next] net: bcmgenet: Track per TX/RX rings statistics

2017-03-21 Thread David Miller
From: Florian Fainelli 
Date: Thu, 16 Mar 2017 10:27:08 -0700

> __bcmgenet_tx_reclaim() is currently summing TX bytes/packets in a way
> that is not SMP friendly, mutliples CPUs could run
> __bcmgenet_tx_reclaim() independently and still update stats->tx_bytes
> and stats->tx_packets, cloberring the other CPUs statistics.
> 
> Fix this by tracking per RX and TX rings the number of bytes, packets,
> dropped and errors statistics, and provide a bcmgenet_get_stats()
> function which aggregates everything and returns a consistent output.
> 
> Signed-off-by: Florian Fainelli 

Applied, thanks.


[PATCH net-next] net: bcmgenet: Track per TX/RX rings statistics

2017-03-16 Thread Florian Fainelli
__bcmgenet_tx_reclaim() is currently summing TX bytes/packets in a way
that is not SMP friendly, mutliples CPUs could run
__bcmgenet_tx_reclaim() independently and still update stats->tx_bytes
and stats->tx_packets, cloberring the other CPUs statistics.

Fix this by tracking per RX and TX rings the number of bytes, packets,
dropped and errors statistics, and provide a bcmgenet_get_stats()
function which aggregates everything and returns a consistent output.

Signed-off-by: Florian Fainelli 
---
Eric,

The patch was originally from you, can you add your SoB to this if you
agree with that?

Thank you!

 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 77 +++---
 drivers/net/ethernet/broadcom/genet/bcmgenet.h |  6 ++
 2 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 44f9c0a1f85d..f493276d432a 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -707,6 +707,19 @@ struct bcmgenet_stats {
.reg_offset = offset, \
 }
 
+#define STAT_GENET_Q(num) \
+   STAT_GENET_SOFT_MIB("txq" __stringify(num) "_packets", \
+   tx_rings[num].packets), \
+   STAT_GENET_SOFT_MIB("txq" __stringify(num) "_bytes", \
+   tx_rings[num].bytes), \
+   STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_bytes", \
+   rx_rings[num].bytes),\
+   STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_packets", \
+   rx_rings[num].packets), \
+   STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_errors", \
+   rx_rings[num].errors), \
+   STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_dropped", \
+   rx_rings[num].dropped)
 
 /* There is a 0xC gap between the end of RX and beginning of TX stats and then
  * between the end of TX stats and the beginning of the RX RUNT
@@ -801,6 +814,12 @@ static const struct bcmgenet_stats 
bcmgenet_gstrings_stats[] = {
STAT_GENET_SOFT_MIB("alloc_rx_buff_failed", mib.alloc_rx_buff_failed),
STAT_GENET_SOFT_MIB("rx_dma_failed", mib.rx_dma_failed),
STAT_GENET_SOFT_MIB("tx_dma_failed", mib.tx_dma_failed),
+   /* Per TX queues */
+   STAT_GENET_Q(0),
+   STAT_GENET_Q(1),
+   STAT_GENET_Q(2),
+   STAT_GENET_Q(3),
+   STAT_GENET_Q(16),
 };
 
 #define BCMGENET_STATS_LEN ARRAY_SIZE(bcmgenet_gstrings_stats)
@@ -1298,8 +1317,8 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
ring->free_bds += txbds_processed;
ring->c_index = c_index;
 
-   dev->stats.tx_packets += pkts_compl;
-   dev->stats.tx_bytes += bytes_compl;
+   ring->packets += pkts_compl;
+   ring->bytes += bytes_compl;
 
netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue),
  pkts_compl, bytes_compl);
@@ -1694,8 +1713,7 @@ static unsigned int bcmgenet_desc_rx(struct 
bcmgenet_rx_ring *ring,
   DMA_P_INDEX_DISCARD_CNT_MASK;
if (discards > ring->old_discards) {
discards = discards - ring->old_discards;
-   dev->stats.rx_missed_errors += discards;
-   dev->stats.rx_errors += discards;
+   ring->errors += discards;
ring->old_discards += discards;
 
/* Clear HW register when we reach 75% of maximum 0x */
@@ -1718,7 +1736,7 @@ static unsigned int bcmgenet_desc_rx(struct 
bcmgenet_rx_ring *ring,
skb = bcmgenet_rx_refill(priv, cb);
 
if (unlikely(!skb)) {
-   dev->stats.rx_dropped++;
+   ring->dropped++;
goto next;
}
 
@@ -1746,7 +1764,7 @@ static unsigned int bcmgenet_desc_rx(struct 
bcmgenet_rx_ring *ring,
if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
netif_err(priv, rx_status, dev,
  "dropping fragmented packet!\n");
-   dev->stats.rx_errors++;
+   ring->errors++;
dev_kfree_skb_any(skb);
goto next;
}
@@ -1795,8 +1813,8 @@ static unsigned int bcmgenet_desc_rx(struct 
bcmgenet_rx_ring *ring,
 
/*Finish setting up the received SKB and send it to the kernel*/
skb->protocol = eth_type_trans(skb, priv->dev);
-   dev->stats.rx_packets++;
-   dev->stats.rx_bytes += len;
+   ring->packets++;
+   ring->bytes += len;
if (dma_flag & DMA_RX_MULT)
dev->stats.multicast++;
 
@@ -3134,6 +3152,48 @@ static int bcmgenet_set_mac_addr(struct net_device *dev, 
void *p)
return 0;
 }
 
+static struct net_device_stats *bcmgenet_get_stats(struct net_device