Skip to content

Commit c8eb0c3

Browse files
committed
Merge branch 'netdev-fix-repeated-netlink-messages-in-queue-dumps'
Jakub Kicinski says: ==================== netdev: fix repeated netlink messages in queue dumps Fix dump continuation for queues and queue stats in the netdev family. Because we used post-increment when saving id of dumped queue next skb would re-dump the already dumped queue. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 922b4b9 + 5712e32 commit c8eb0c3

File tree

4 files changed

+45
-28
lines changed

4 files changed

+45
-28
lines changed

net/core/netdev-genl.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -488,24 +488,21 @@ netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
488488
struct netdev_nl_dump_ctx *ctx)
489489
{
490490
int err = 0;
491-
int i;
492491

493492
if (!(netdev->flags & IFF_UP))
494493
return err;
495494

496-
for (i = ctx->rxq_idx; i < netdev->real_num_rx_queues;) {
497-
err = netdev_nl_queue_fill_one(rsp, netdev, i,
495+
for (; ctx->rxq_idx < netdev->real_num_rx_queues; ctx->rxq_idx++) {
496+
err = netdev_nl_queue_fill_one(rsp, netdev, ctx->rxq_idx,
498497
NETDEV_QUEUE_TYPE_RX, info);
499498
if (err)
500499
return err;
501-
ctx->rxq_idx = i++;
502500
}
503-
for (i = ctx->txq_idx; i < netdev->real_num_tx_queues;) {
504-
err = netdev_nl_queue_fill_one(rsp, netdev, i,
501+
for (; ctx->txq_idx < netdev->real_num_tx_queues; ctx->txq_idx++) {
502+
err = netdev_nl_queue_fill_one(rsp, netdev, ctx->txq_idx,
505503
NETDEV_QUEUE_TYPE_TX, info);
506504
if (err)
507505
return err;
508-
ctx->txq_idx = i++;
509506
}
510507

511508
return err;
@@ -671,15 +668,15 @@ netdev_nl_stats_by_queue(struct net_device *netdev, struct sk_buff *rsp,
671668
i, info);
672669
if (err)
673670
return err;
674-
ctx->rxq_idx = i++;
671+
ctx->rxq_idx = ++i;
675672
}
676673
i = ctx->txq_idx;
677674
while (ops->get_queue_stats_tx && i < netdev->real_num_tx_queues) {
678675
err = netdev_nl_stats_queue(netdev, rsp, NETDEV_QUEUE_TYPE_TX,
679676
i, info);
680677
if (err)
681678
return err;
682-
ctx->txq_idx = i++;
679+
ctx->txq_idx = ++i;
683680
}
684681

685682
ctx->rxq_idx = 0;

tools/testing/selftests/drivers/net/queues.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,28 @@
88
import glob
99

1010

11-
def sys_get_queues(ifname) -> int:
12-
folders = glob.glob(f'/sys/class/net/{ifname}/queues/rx-*')
11+
def sys_get_queues(ifname, qtype='rx') -> int:
12+
folders = glob.glob(f'/sys/class/net/{ifname}/queues/{qtype}-*')
1313
return len(folders)
1414

1515

16-
def nl_get_queues(cfg, nl):
16+
def nl_get_queues(cfg, nl, qtype='rx'):
1717
queues = nl.queue_get({'ifindex': cfg.ifindex}, dump=True)
1818
if queues:
19-
return len([q for q in queues if q['type'] == 'rx'])
19+
return len([q for q in queues if q['type'] == qtype])
2020
return None
2121

2222

2323
def get_queues(cfg, nl) -> None:
24-
queues = nl_get_queues(cfg, nl)
25-
if not queues:
26-
raise KsftSkipEx('queue-get not supported by device')
24+
snl = NetdevFamily(recv_size=4096)
2725

28-
expected = sys_get_queues(cfg.dev['ifname'])
29-
ksft_eq(queues, expected)
26+
for qtype in ['rx', 'tx']:
27+
queues = nl_get_queues(cfg, snl, qtype)
28+
if not queues:
29+
raise KsftSkipEx('queue-get not supported by device')
30+
31+
expected = sys_get_queues(cfg.dev['ifname'], qtype)
32+
ksft_eq(queues, expected)
3033

3134

3235
def addremove_queues(cfg, nl) -> None:
@@ -57,7 +60,7 @@ def addremove_queues(cfg, nl) -> None:
5760

5861

5962
def main() -> None:
60-
with NetDrvEnv(__file__, queue_count=3) as cfg:
63+
with NetDrvEnv(__file__, queue_count=100) as cfg:
6164
ksft_run([get_queues, addremove_queues], args=(cfg, NetdevFamily()))
6265
ksft_exit()
6366

tools/testing/selftests/drivers/net/stats.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,23 @@ def qstat_by_ifindex(cfg) -> None:
110110
ksft_ge(triple[1][key], triple[0][key], comment="bad key: " + key)
111111
ksft_ge(triple[2][key], triple[1][key], comment="bad key: " + key)
112112

113+
# Sanity check the dumps
114+
queues = NetdevFamily(recv_size=4096).qstats_get({"scope": "queue"}, dump=True)
115+
# Reformat the output into {ifindex: {rx: [id, id, ...], tx: [id, id, ...]}}
116+
parsed = {}
117+
for entry in queues:
118+
ifindex = entry["ifindex"]
119+
if ifindex not in parsed:
120+
parsed[ifindex] = {"rx":[], "tx": []}
121+
parsed[ifindex][entry["queue-type"]].append(entry['queue-id'])
122+
# Now, validate
123+
for ifindex, queues in parsed.items():
124+
for qtype in ['rx', 'tx']:
125+
ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
126+
comment="repeated queue keys")
127+
ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
128+
comment="missing queue keys")
129+
113130
# Test invalid dumps
114131
# 0 is invalid
115132
with ksft_raises(NlError) as cm:
@@ -158,7 +175,7 @@ def check_down(cfg) -> None:
158175

159176

160177
def main() -> None:
161-
with NetDrvEnv(__file__) as cfg:
178+
with NetDrvEnv(__file__, queue_count=100) as cfg:
162179
ksft_run([check_pause, check_fec, pkt_byte_sum, qstat_by_ifindex,
163180
check_down],
164181
args=(cfg, ))

tools/testing/selftests/net/lib/py/ynl.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@
3232
# Set schema='' to avoid jsonschema validation, it's slow
3333
#
3434
class EthtoolFamily(YnlFamily):
35-
def __init__(self):
35+
def __init__(self, recv_size=0):
3636
super().__init__((SPEC_PATH / Path('ethtool.yaml')).as_posix(),
37-
schema='')
37+
schema='', recv_size=recv_size)
3838

3939

4040
class RtnlFamily(YnlFamily):
41-
def __init__(self):
41+
def __init__(self, recv_size=0):
4242
super().__init__((SPEC_PATH / Path('rt_link.yaml')).as_posix(),
43-
schema='')
43+
schema='', recv_size=recv_size)
4444

4545

4646
class NetdevFamily(YnlFamily):
47-
def __init__(self):
47+
def __init__(self, recv_size=0):
4848
super().__init__((SPEC_PATH / Path('netdev.yaml')).as_posix(),
49-
schema='')
49+
schema='', recv_size=recv_size)
5050

5151
class NetshaperFamily(YnlFamily):
52-
def __init__(self):
52+
def __init__(self, recv_size=0):
5353
super().__init__((SPEC_PATH / Path('net_shaper.yaml')).as_posix(),
54-
schema='')
54+
schema='', recv_size=recv_size)

0 commit comments

Comments
 (0)