Skip to content

Commit 68e9c5d

Browse files
Vijayakannandavem330
authored andcommitted
net: stmmac: add ethtool per-queue statistic framework
Adding generic ethtool per-queue statistic framework to display the statistics for each rx/tx queue. In future, users can avail it to add more per-queue specific counters. Number of rx/tx queues displayed is depending on the available rx/tx queues in that particular MAC config and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined in the driver. Ethtool per-queue statistic display will look like below, when users start adding more counters. Example: q0_tx_statA: q0_tx_statB: q0_tx_statC: | q0_tx_statX: . . . qMAX_tx_statA: qMAX_tx_statB: qMAX_tx_statC: | qMAX_tx_statX: q0_rx_statA: q0_rx_statB: q0_rx_statC: | q0_rx_statX: . . . qMAX_rx_statA: qMAX_rx_statB: qMAX_rx_statC: | qMAX_rx_statX: In addition, this patch has the support on displaying the number of packets received and transmitted per queue. Signed-off-by: Vijayakannan Ayyathurai <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1975df8 commit 68e9c5d

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

drivers/net/ethernet/stmicro/stmmac/common.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@
5858
#undef FRAME_FILTER_DEBUG
5959
/* #define FRAME_FILTER_DEBUG */
6060

61+
struct stmmac_txq_stats {
62+
unsigned long tx_pkt_n;
63+
};
64+
65+
struct stmmac_rxq_stats {
66+
unsigned long rx_pkt_n;
67+
};
68+
6169
/* Extra statistic and debug information exposed by ethtool */
6270
struct stmmac_extra_stats {
6371
/* Transmit errors */
@@ -189,6 +197,9 @@ struct stmmac_extra_stats {
189197
unsigned long mtl_est_hlbf;
190198
unsigned long mtl_est_btre;
191199
unsigned long mtl_est_btrlm;
200+
/* per queue statistics */
201+
struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
202+
struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
192203
};
193204

194205
/* Safety Feature statistics exposed by ethtool */

drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,16 @@ static const struct stmmac_stats stmmac_mmc[] = {
261261
};
262262
#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)
263263

264+
static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = {
265+
"tx_pkt_n",
266+
#define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string)
267+
};
268+
269+
static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = {
270+
"rx_pkt_n",
271+
#define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string)
272+
};
273+
264274
static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
265275
struct ethtool_drvinfo *info)
266276
{
@@ -510,6 +520,31 @@ stmmac_set_pauseparam(struct net_device *netdev,
510520
}
511521
}
512522

523+
static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
524+
{
525+
u32 tx_cnt = priv->plat->tx_queues_to_use;
526+
u32 rx_cnt = priv->plat->rx_queues_to_use;
527+
int q, stat;
528+
char *p;
529+
530+
for (q = 0; q < tx_cnt; q++) {
531+
p = (char *)priv + offsetof(struct stmmac_priv,
532+
xstats.txq_stats[q].tx_pkt_n);
533+
for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
534+
*data++ = (*(u64 *)p);
535+
p += sizeof(u64 *);
536+
}
537+
}
538+
for (q = 0; q < rx_cnt; q++) {
539+
p = (char *)priv + offsetof(struct stmmac_priv,
540+
xstats.rxq_stats[q].rx_pkt_n);
541+
for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
542+
*data++ = (*(u64 *)p);
543+
p += sizeof(u64 *);
544+
}
545+
}
546+
}
547+
513548
static void stmmac_get_ethtool_stats(struct net_device *dev,
514549
struct ethtool_stats *dummy, u64 *data)
515550
{
@@ -560,16 +595,21 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
560595
data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==
561596
sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
562597
}
598+
stmmac_get_per_qstats(priv, &data[j]);
563599
}
564600

565601
static int stmmac_get_sset_count(struct net_device *netdev, int sset)
566602
{
567603
struct stmmac_priv *priv = netdev_priv(netdev);
604+
u32 tx_cnt = priv->plat->tx_queues_to_use;
605+
u32 rx_cnt = priv->plat->rx_queues_to_use;
568606
int i, len, safety_len = 0;
569607

570608
switch (sset) {
571609
case ETH_SS_STATS:
572-
len = STMMAC_STATS_LEN;
610+
len = STMMAC_STATS_LEN +
611+
STMMAC_TXQ_STATS * tx_cnt +
612+
STMMAC_RXQ_STATS * rx_cnt;
573613

574614
if (priv->dma_cap.rmon)
575615
len += STMMAC_MMC_STATS_LEN;
@@ -592,6 +632,28 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
592632
}
593633
}
594634

635+
static void stmmac_get_qstats_string(struct stmmac_priv *priv, u8 *data)
636+
{
637+
u32 tx_cnt = priv->plat->tx_queues_to_use;
638+
u32 rx_cnt = priv->plat->rx_queues_to_use;
639+
int q, stat;
640+
641+
for (q = 0; q < tx_cnt; q++) {
642+
for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
643+
snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,
644+
stmmac_qstats_tx_string[stat]);
645+
data += ETH_GSTRING_LEN;
646+
}
647+
}
648+
for (q = 0; q < rx_cnt; q++) {
649+
for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
650+
snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,
651+
stmmac_qstats_rx_string[stat]);
652+
data += ETH_GSTRING_LEN;
653+
}
654+
}
655+
}
656+
595657
static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
596658
{
597659
int i;
@@ -622,6 +684,7 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
622684
ETH_GSTRING_LEN);
623685
p += ETH_GSTRING_LEN;
624686
}
687+
stmmac_get_qstats_string(priv, p);
625688
break;
626689
case ETH_SS_TEST:
627690
stmmac_selftest_get_strings(priv, p);

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,6 +2500,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
25002500
} else {
25012501
priv->dev->stats.tx_packets++;
25022502
priv->xstats.tx_pkt_n++;
2503+
priv->xstats.txq_stats[queue].tx_pkt_n++;
25032504
}
25042505
if (skb)
25052506
stmmac_get_tx_hwtstamp(priv, p, skb);
@@ -5000,6 +5001,9 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
50005001

50015002
stmmac_finalize_xdp_rx(priv, xdp_status);
50025003

5004+
priv->xstats.rx_pkt_n += count;
5005+
priv->xstats.rxq_stats[queue].rx_pkt_n += count;
5006+
50035007
if (xsk_uses_need_wakeup(rx_q->xsk_pool)) {
50045008
if (failure || stmmac_rx_dirty(priv, queue) > 0)
50055009
xsk_set_rx_need_wakeup(rx_q->xsk_pool);
@@ -5287,6 +5291,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
52875291
stmmac_rx_refill(priv, queue);
52885292

52895293
priv->xstats.rx_pkt_n += count;
5294+
priv->xstats.rxq_stats[queue].rx_pkt_n += count;
52905295

52915296
return count;
52925297
}

0 commit comments

Comments
 (0)