Skip to content

Commit 8f20a2b

Browse files
Mohsin BashirPaolo Abeni
authored andcommitted
eth: fbnic: add coverage for hw queue stats
This patch provides support for hardware queue stats and covers packet errors for RX-DMA engine, RCQ drops and BDQ drops. The packet errors are also aggregated with the `rx_errors` stats in the `rtnl_link_stats` as well as with the `hw_drops` in the queue API. The RCQ and BDQ drops are aggregated with `rx_over_errors` in the `rtnl_link_stats` as well as with the `hw_drop_overruns` in the queue API. ethtool -S eth0 | grep -E 'rde' rde_0_pkt_err: 0 rde_0_pkt_cq_drop: 0 rde_0_pkt_bdq_drop: 0 --- --- rde_127_pkt_err: 0 rde_127_pkt_cq_drop: 0 rde_127_pkt_bdq_drop: 0 Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Mohsin Bashir <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 9f61eb2 commit 8f20a2b

File tree

6 files changed

+156
-8
lines changed

6 files changed

+156
-8
lines changed

Documentation/networking/device_drivers/ethernet/meta/fbnic.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ RPC (Rx parser)
4444
- ``rpc_out_of_hdr_err``: frames where header was larger than parsable region
4545
- ``ovr_size_err``: oversized frames
4646

47+
Hardware Queues
48+
~~~~~~~~~~~~~~~
49+
50+
1. RX DMA Engine:
51+
52+
- ``rde_[i]_pkt_err``: packets with MAC EOP, RPC parser, RXB truncation, or RDE frame truncation errors. These error are flagged in the packet metadata because of cut-through support but the actual drop happens once PCIE/RDE is reached.
53+
- ``rde_[i]_pkt_cq_drop``: packets dropped because RCQ is full
54+
- ``rde_[i]_pkt_bdq_drop``: packets dropped because HPQ or PPQ ran out of host buffer
55+
4756
PCIe
4857
~~~~
4958

drivers/net/ethernet/meta/fbnic/fbnic_csr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,12 @@ enum {
864864
#define FBNIC_QUEUE_TWQ1_BAL 0x022 /* 0x088 */
865865
#define FBNIC_QUEUE_TWQ1_BAH 0x023 /* 0x08c */
866866

867+
/* Tx Work Queue Statistics Registers */
868+
#define FBNIC_QUEUE_TWQ0_PKT_CNT 0x062 /* 0x188 */
869+
#define FBNIC_QUEUE_TWQ0_ERR_CNT 0x063 /* 0x18c */
870+
#define FBNIC_QUEUE_TWQ1_PKT_CNT 0x072 /* 0x1c8 */
871+
#define FBNIC_QUEUE_TWQ1_ERR_CNT 0x073 /* 0x1cc */
872+
867873
/* Tx Completion Queue Registers */
868874
#define FBNIC_QUEUE_TCQ_CTL 0x080 /* 0x200 */
869875
#define FBNIC_QUEUE_TCQ_CTL_RESET CSR_BIT(0)
@@ -953,6 +959,12 @@ enum {
953959
FBNIC_QUEUE_RDE_CTL1_PAYLD_PACK_RSS = 2,
954960
};
955961

962+
/* Rx Per CQ Statistics Counters */
963+
#define FBNIC_QUEUE_RDE_PKT_CNT 0x2a2 /* 0xa88 */
964+
#define FBNIC_QUEUE_RDE_PKT_ERR_CNT 0x2a3 /* 0xa8c */
965+
#define FBNIC_QUEUE_RDE_CQ_DROP_CNT 0x2a4 /* 0xa90 */
966+
#define FBNIC_QUEUE_RDE_BDQ_DROP_CNT 0x2a5 /* 0xa94 */
967+
956968
/* Rx Interrupt Manager Registers */
957969
#define FBNIC_QUEUE_RIM_CTL 0x2c0 /* 0xb00 */
958970
#define FBNIC_QUEUE_RIM_CTL_MSIX_MASK CSR_GENMASK(7, 0)

drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,20 @@ static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
3939
};
4040

4141
#define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
42-
#define FBNIC_HW_STATS_LEN FBNIC_HW_FIXED_STATS_LEN
42+
43+
#define FBNIC_HW_Q_STAT(name, stat) \
44+
FBNIC_STAT_FIELDS(fbnic_hw_q_stats, name, stat.value)
45+
46+
static const struct fbnic_stat fbnic_gstrings_hw_q_stats[] = {
47+
FBNIC_HW_Q_STAT("rde_%u_pkt_err", rde_pkt_err),
48+
FBNIC_HW_Q_STAT("rde_%u_pkt_cq_drop", rde_pkt_cq_drop),
49+
FBNIC_HW_Q_STAT("rde_%u_pkt_bdq_drop", rde_pkt_bdq_drop),
50+
};
51+
52+
#define FBNIC_HW_Q_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_q_stats)
53+
#define FBNIC_HW_STATS_LEN \
54+
(FBNIC_HW_FIXED_STATS_LEN + \
55+
FBNIC_HW_Q_STATS_LEN * FBNIC_MAX_QUEUES)
4356

4457
static void
4558
fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
@@ -300,29 +313,57 @@ fbnic_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
300313

301314
static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
302315
{
303-
int i;
316+
const struct fbnic_stat *stat;
317+
int i, idx;
304318

305319
switch (sset) {
306320
case ETH_SS_STATS:
307-
for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
321+
for (i = 0; i < FBNIC_HW_FIXED_STATS_LEN; i++)
308322
ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
323+
324+
for (idx = 0; idx < FBNIC_MAX_QUEUES; idx++) {
325+
stat = fbnic_gstrings_hw_q_stats;
326+
327+
for (i = 0; i < FBNIC_HW_Q_STATS_LEN; i++, stat++)
328+
ethtool_sprintf(&data, stat->string, idx);
329+
}
309330
break;
310331
}
311332
}
312333

334+
static void fbnic_report_hw_stats(const struct fbnic_stat *stat,
335+
const void *base, int len, u64 **data)
336+
{
337+
while (len--) {
338+
u8 *curr = (u8 *)base + stat->offset;
339+
340+
**data = *(u64 *)curr;
341+
342+
stat++;
343+
(*data)++;
344+
}
345+
}
346+
313347
static void fbnic_get_ethtool_stats(struct net_device *dev,
314348
struct ethtool_stats *stats, u64 *data)
315349
{
316350
struct fbnic_net *fbn = netdev_priv(dev);
317-
const struct fbnic_stat *stat;
351+
struct fbnic_dev *fbd = fbn->fbd;
318352
int i;
319353

320354
fbnic_get_hw_stats(fbn->fbd);
321355

322-
for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
323-
stat = &fbnic_gstrings_hw_stats[i];
324-
data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
356+
spin_lock(&fbd->hw_stats_lock);
357+
fbnic_report_hw_stats(fbnic_gstrings_hw_stats, &fbd->hw_stats,
358+
FBNIC_HW_FIXED_STATS_LEN, &data);
359+
360+
for (i = 0; i < FBNIC_MAX_QUEUES; i++) {
361+
const struct fbnic_hw_q_stats *hw_q = &fbd->hw_stats.hw_q[i];
362+
363+
fbnic_report_hw_stats(fbnic_gstrings_hw_q_stats, hw_q,
364+
FBNIC_HW_Q_STATS_LEN, &data);
325365
}
366+
spin_unlock(&fbd->hw_stats_lock);
326367
}
327368

328369
static int fbnic_get_sset_count(struct net_device *dev, int sset)

drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,54 @@ static void fbnic_get_rpc_stats32(struct fbnic_dev *fbd,
117117
&rpc->ovr_size_err);
118118
}
119119

120+
static void fbnic_reset_hw_rxq_stats(struct fbnic_dev *fbd,
121+
struct fbnic_hw_q_stats *hw_q)
122+
{
123+
int i;
124+
125+
for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
126+
u32 base = FBNIC_QUEUE(i);
127+
128+
fbnic_hw_stat_rst32(fbd,
129+
base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
130+
&hw_q->rde_pkt_err);
131+
fbnic_hw_stat_rst32(fbd,
132+
base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
133+
&hw_q->rde_pkt_cq_drop);
134+
fbnic_hw_stat_rst32(fbd,
135+
base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
136+
&hw_q->rde_pkt_bdq_drop);
137+
}
138+
}
139+
140+
static void fbnic_get_hw_rxq_stats32(struct fbnic_dev *fbd,
141+
struct fbnic_hw_q_stats *hw_q)
142+
{
143+
int i;
144+
145+
for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
146+
u32 base = FBNIC_QUEUE(i);
147+
148+
fbnic_hw_stat_rd32(fbd,
149+
base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
150+
&hw_q->rde_pkt_err);
151+
fbnic_hw_stat_rd32(fbd,
152+
base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
153+
&hw_q->rde_pkt_cq_drop);
154+
fbnic_hw_stat_rd32(fbd,
155+
base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
156+
&hw_q->rde_pkt_bdq_drop);
157+
}
158+
}
159+
160+
void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
161+
struct fbnic_hw_q_stats *hw_q)
162+
{
163+
spin_lock(&fbd->hw_stats_lock);
164+
fbnic_get_hw_rxq_stats32(fbd, hw_q);
165+
spin_unlock(&fbd->hw_stats_lock);
166+
}
167+
120168
static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd,
121169
struct fbnic_pcie_stats *pcie)
122170
{
@@ -205,13 +253,15 @@ void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
205253
{
206254
spin_lock(&fbd->hw_stats_lock);
207255
fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
256+
fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q);
208257
fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
209258
spin_unlock(&fbd->hw_stats_lock);
210259
}
211260

212261
static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
213262
{
214263
fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc);
264+
fbnic_get_hw_rxq_stats32(fbd, fbd->hw_stats.hw_q);
215265
}
216266

217267
void fbnic_get_hw_stats32(struct fbnic_dev *fbd)

drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ struct fbnic_rpc_stats {
4343
struct fbnic_stat_counter tcp_opt_err, out_of_hdr_err, ovr_size_err;
4444
};
4545

46+
struct fbnic_hw_q_stats {
47+
struct fbnic_stat_counter rde_pkt_err;
48+
struct fbnic_stat_counter rde_pkt_cq_drop;
49+
struct fbnic_stat_counter rde_pkt_bdq_drop;
50+
};
51+
4652
struct fbnic_pcie_stats {
4753
struct fbnic_stat_counter ob_rd_tlp, ob_rd_dword;
4854
struct fbnic_stat_counter ob_wr_tlp, ob_wr_dword;
@@ -56,12 +62,15 @@ struct fbnic_pcie_stats {
5662
struct fbnic_hw_stats {
5763
struct fbnic_mac_stats mac;
5864
struct fbnic_rpc_stats rpc;
65+
struct fbnic_hw_q_stats hw_q[FBNIC_MAX_QUEUES];
5966
struct fbnic_pcie_stats pcie;
6067
};
6168

6269
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset);
6370

6471
void fbnic_reset_hw_stats(struct fbnic_dev *fbd);
72+
void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
73+
struct fbnic_hw_q_stats *hw_q);
6574
void fbnic_get_hw_stats32(struct fbnic_dev *fbd);
6675
void fbnic_get_hw_stats(struct fbnic_dev *fbd);
6776

drivers/net/ethernet/meta/fbnic/fbnic_netdev.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,15 @@ static int fbnic_hwtstamp_set(struct net_device *netdev,
403403
static void fbnic_get_stats64(struct net_device *dev,
404404
struct rtnl_link_stats64 *stats64)
405405
{
406+
u64 rx_bytes, rx_packets, rx_dropped = 0, rx_errors = 0;
406407
u64 tx_bytes, tx_packets, tx_dropped = 0;
407-
u64 rx_bytes, rx_packets, rx_dropped = 0;
408408
struct fbnic_net *fbn = netdev_priv(dev);
409+
struct fbnic_dev *fbd = fbn->fbd;
409410
struct fbnic_queue_stats *stats;
410411
unsigned int start, i;
412+
u64 rx_over = 0;
413+
414+
fbnic_get_hw_stats(fbd);
411415

412416
stats = &fbn->tx_stats;
413417

@@ -444,9 +448,22 @@ static void fbnic_get_stats64(struct net_device *dev,
444448
rx_packets = stats->packets;
445449
rx_dropped = stats->dropped;
446450

451+
spin_lock(&fbd->hw_stats_lock);
452+
for (i = 0; i < fbd->max_num_queues; i++) {
453+
/* Report packets dropped due to CQ/BDQ being full/empty */
454+
rx_over += fbd->hw_stats.hw_q[i].rde_pkt_cq_drop.value;
455+
rx_over += fbd->hw_stats.hw_q[i].rde_pkt_bdq_drop.value;
456+
457+
/* Report packets with errors */
458+
rx_errors += fbd->hw_stats.hw_q[i].rde_pkt_err.value;
459+
}
460+
spin_unlock(&fbd->hw_stats_lock);
461+
447462
stats64->rx_bytes = rx_bytes;
448463
stats64->rx_packets = rx_packets;
449464
stats64->rx_dropped = rx_dropped;
465+
stats64->rx_over_errors = rx_over;
466+
stats64->rx_errors = rx_errors;
450467

451468
for (i = 0; i < fbn->num_rx_queues; i++) {
452469
struct fbnic_ring *rxr = fbn->rx[i];
@@ -486,6 +503,7 @@ static void fbnic_get_queue_stats_rx(struct net_device *dev, int idx,
486503
{
487504
struct fbnic_net *fbn = netdev_priv(dev);
488505
struct fbnic_ring *rxr = fbn->rx[idx];
506+
struct fbnic_dev *fbd = fbn->fbd;
489507
struct fbnic_queue_stats *stats;
490508
u64 bytes, packets, alloc_fail;
491509
u64 csum_complete, csum_none;
@@ -509,6 +527,15 @@ static void fbnic_get_queue_stats_rx(struct net_device *dev, int idx,
509527
rx->alloc_fail = alloc_fail;
510528
rx->csum_complete = csum_complete;
511529
rx->csum_none = csum_none;
530+
531+
fbnic_get_hw_q_stats(fbd, fbd->hw_stats.hw_q);
532+
533+
spin_lock(&fbd->hw_stats_lock);
534+
rx->hw_drop_overruns = fbd->hw_stats.hw_q[idx].rde_pkt_cq_drop.value +
535+
fbd->hw_stats.hw_q[idx].rde_pkt_bdq_drop.value;
536+
rx->hw_drops = fbd->hw_stats.hw_q[idx].rde_pkt_err.value +
537+
rx->hw_drop_overruns;
538+
spin_unlock(&fbd->hw_stats_lock);
512539
}
513540

514541
static void fbnic_get_queue_stats_tx(struct net_device *dev, int idx,

0 commit comments

Comments
 (0)