Lines Matching +full:3 +full:- +full:tuples

2 # SPDX-License-Identifier: GPL-2.0
27 if 'rss-hash-key' not in data:
29 non_zero = [x for x in data['rss-hash-key'] if x != 0]
30 ksft_eq(bool(non_zero), True, comment=f"RSS key is all zero {data['rss-hash-key']}")
34 return ethtool(f"-x {cfg.ifname} context {context}", json=True)[0]
38 stats = ip("-s -s link show dev " + cfg.ifname, json=True)[0]
51 return int(output.split()[-1])
55 features = ethtool(f"-k {cfg.ifname}", json=True)[0]
56 if not features["ntuple-filters"]["active"]:
59 … raise KsftSkipEx("Ntuple filters not enabled on the device: " + str(features["ntuple-filters"]))
75 data = [x for x in data if x['queue-type'] == "rx"]
76 max_q = max([x["queue-id"] for x in data])
79 queue_stats[q["queue-id"]] = q["rx-packets"]
80 if prev and q["queue-id"] < len(prev):
81 queue_stats[q["queue-id"]] -= prev[q["queue-id"]]
86 # params is a dict with 3 possible keys:
87 # - "target": required, which queues we expect to get iperf traffic
88 # - "empty": optional, which queues should see no traffic at all
89 # - "noise": optional, which queues we expect to see low traffic;
111 text = ethtool(f"-n {cfg.ifname} rule {rule_id}").stdout
120 if qcnt < 3:
121 KsftSkipEx("Device has fewer than 3 queues (or doesn't support queue stats)")
124 want_keys = ['rss-hash-key', 'rss-hash-function', 'rss-indirection-table']
132 key_len = len(data['rss-hash-key'])
136 ethtool(f"-X {cfg.ifname} hkey " + _rss_key_str(key))
139 ksft_eq(key, data['rss-hash-key'])
143 ethtool(f"-X {cfg.ifname} equal 3 hkey " + _rss_key_str(key))
144 reset_indir = defer(ethtool, f"-X {cfg.ifname} default")
148 ksft_eq(0, min(data['rss-indirection-table']))
149 ksft_eq(2, max(data['rss-indirection-table']))
153 ethtool(f"-X {cfg.ifname} default hkey " + _rss_key_str(key))
156 ksft_eq(0, min(data['rss-indirection-table']))
157 ksft_eq(qcnt - 1, max(data['rss-indirection-table']))
160 ethtool(f"-X {cfg.ifname} equal 2")
162 ksft_eq(0, min(data['rss-indirection-table']))
163 ksft_eq(1, max(data['rss-indirection-table']))
191 queues used in the user-set RSS config.
200 ethtool(f"-L {cfg.ifname} combined 4")
201 defer(ethtool, f"-L {cfg.ifname} combined {qcnt}")
209 ctx_id = ethtool_create(cfg, "-X", "context new")
211 defer(ethtool, f"-X {cfg.ifname} {ctx_ref} delete")
215 ksft_eq(0, min(data['rss-indirection-table']))
216 ksft_eq(3, max(data['rss-indirection-table']))
221 ethtool(f"-L {cfg.ifname} combined 5")
223 ksft_eq(0, min(data['rss-indirection-table']))
224 ksft_eq(4, max(data['rss-indirection-table']))
225 ethtool(f"-L {cfg.ifname} combined 4")
229 ethtool(f"-X {cfg.ifname} {ctx_ref} weight 1 0 0 1")
232 defer(ethtool, f"-X {cfg.ifname} default")
235 flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {ctx_id}"
236 ntuple = ethtool_create(cfg, "-N", flow)
237 defer(ethtool, f"-N {cfg.ifname} delete {ntuple}")
239 _send_traffic_check(cfg, port, ctx_ref, { 'target': (0, 3),
243 ethtool(f"-L {cfg.ifname} combined 5")
245 ksft_eq({0, 3}, set(data['rss-indirection-table']))
247 _send_traffic_check(cfg, port, ctx_ref, { 'target': (0, 3),
250 # Setting queue count to 3 should fail, queue 3 is used
252 ethtool(f"-L {cfg.ifname} combined 3")
259 ethtool(f"-L {cfg.ifname} combined 4")
260 …flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {ctx_id} action 1"
263 ntuple2 = ethtool_create(cfg, "-N", flow)
264 defer(ethtool, f"-N {cfg.ifname} delete {ntuple2}")
270 ethtool(f"-X {cfg.ifname} {ctx_ref} weight 1 0 1 0")
271 # ntuple rule therefore targets queues 1 and 3
273 ntuple2 = ethtool_create(cfg, "-N", flow)
278 defer(ethtool, f"-N {cfg.ifname} delete {ntuple2}")
281 _send_traffic_check(cfg, port, ctx_ref, { 'target': (1, 3),
283 # Setting queue count to 3 should fail, queue 3 is used
285 ethtool(f"-L {cfg.ifname} combined 3")
301 channels = cfg.ethnl.channels_get({'header': {'dev-index': cfg.ifindex}})
302 ch_max = channels['combined-max']
303 qcnt = channels['combined-count']
308 ethtool(f"-L {cfg.ifname} combined 2")
309 defer(ethtool, f"-L {cfg.ifname} combined {qcnt}")
311 ethtool(f"-X {cfg.ifname} weight 1 7")
312 defer(ethtool, f"-X {cfg.ifname} default")
314 ethtool(f"-L {cfg.ifname} combined {ch_max}")
316 ksft_eq(0, min(data['rss-indirection-table']))
317 ksft_eq(1, max(data['rss-indirection-table']))
320 data['rss-indirection-table'].count(1) /
321 data['rss-indirection-table'].count(0),
322 f"Table imbalance after resize: {data['rss-indirection-table']}")
336 key_len = len(data['rss-hash-key'])
344 ethtool(f"-X {cfg.ifname} hkey " + _rss_key_str(key))
350 ksft_lt((t1 - t0).total_seconds(), 0.2)
351 ksft_eq(errors1 - errors1, 0)
352 ksft_eq(carrier1 - carrier0, 0)
362 if 'rss-hash-key' in data:
363 key_data = _rss_key_rand(len(data['rss-hash-key']))
371 ids.append(ethtool_create(cfg, "-X", f"context new"))
372 defer(ethtool, f"-X {cfg.ifname} context {ids[-1]} delete")
374 ids.append(ethtool_create(cfg, "-X", f"context new weight 1 1"))
375 defer(ethtool, f"-X {cfg.ifname} context {ids[-1]} delete")
377 ids.append(ethtool_create(cfg, "-X", f"context new hkey {key}"))
378 defer(ethtool, f"-X {cfg.ifname} context {ids[-1]} delete")
382 ksft_pr(f"Added only {len(ids)} out of 3 contexts")
384 expect_tuples = set([(cfg.ifname, -1)] + [(cfg.ifname, ctx_id) for ctx_id in ids])
388 tuples = [(c['header']['dev-name'], c.get('context', -1)) for c in ctxs]
389 ksft_eq(len(tuples), len(set(tuples)), "duplicates in context dump")
390 ctx_tuples = set([ctx for ctx in tuples if ctx[0] == cfg.ifname])
393 # Sanity-check the results
401 "ctx1 - indir table mismatch")
403 ksft_eq(data['hkey'], bytes(key_data), "ctx2 - key mismatch")
406 ctxs = cfg.ethnl.rss_get({'header': {'dev-name': cfg.ifname}}, dump=True)
407 tuples = [(c['header']['dev-name'], c.get('context', -1)) for c in ctxs]
408 ctx_tuples = set(tuples)
409 ksft_eq(len(tuples), len(ctx_tuples), "duplicates in context dump")
413 expect_tuples.remove((cfg.ifname, -1))
415 ctxs = cfg.ethnl.rss_get({'start-context': 1}, dump=True)
416 tuples = [(c['header']['dev-name'], c.get('context', -1)) for c in ctxs]
417 ksft_eq(len(tuples), len(set(tuples)), "duplicates in context dump")
418 ctx_tuples = set([ctx for ctx in tuples if ctx[0] == cfg.ifname])
422 ctxs = cfg.ethnl.rss_get({'header': {'dev-name': cfg.ifname}, 'start-context': 1}, dump=True)
423 ctx_tuples = set([(c['header']['dev-name'], c.get('context', -1)) for c in ctxs])
432 [0 1] [2 3] [4 5] [6 7] ...
443 ksft_pr(f"Increasing queue count {qcnt} -> {2 + 2 * ctx_cnt}")
444 ethtool(f"-L {cfg.ifname} combined {2 + 2 * ctx_cnt}")
445 defer(ethtool, f"-L {cfg.ifname} combined {qcnt}")
452 ethtool(f"-X {cfg.ifname} equal 2")
453 defer(ethtool, f"-X {cfg.ifname} default")
460 ctx_id = ethtool_create(cfg, "-X", f"context new {create_cfg}")
461 defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
475 ethtool(f"-X {cfg.ifname} context {ctx_id} {want_cfg}")
480 … ksft_eq(min(data['rss-indirection-table']), 2 + i * 2, "Unexpected context cfg: " + str(data))
481 … ksft_eq(max(data['rss-indirection-table']), 2 + i * 2 + 1, "Unexpected context cfg: " + str(data))
484 … flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {ports[i]} context {ctx_id}"
485 ntuple = ethtool_create(cfg, "-N", flow)
486 defer(ethtool, f"-N {cfg.ifname} delete {ntuple}")
492 { 'target': (2+i*2, 3+i*2),
519 Contexts are removed in semi-random order, and steering re-tested
521 Test requires 3 contexts to work.
531 ksft_pr(f"Increasing queue count {qcnt} -> {2 + 2 * ctx_cnt}")
532 ethtool(f"-L {cfg.ifname} combined {2 + 2 * ctx_cnt}")
533 defer(ethtool, f"-L {cfg.ifname} combined {qcnt}")
551 'target': (2+i*2, 3+i*2),
564 ethtool(f"-X {cfg.ifname} equal 2")
565 defer(ethtool, f"-X {cfg.ifname} default")
568 ctx_id = ethtool_create(cfg, "-X", f"context new start {2 + i * 2} equal 2")
569 ctx.append(defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete"))
572 … flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {ports[i]} context {ctx_id}"
573 ntuple_id = ethtool_create(cfg, "-N", flow)
574 ntuple.append(defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}"))
587 remove_ctx(-1)
594 Use 4 queues for the main context, but only queues 2 and 3 for context 1.
604 ksft_pr(f"Increasing queue count {queue_cnt} -> 4")
605 ethtool(f"-L {cfg.ifname} combined 4")
606 defer(ethtool, f"-L {cfg.ifname} combined {queue_cnt}")
611 ethtool(f"-X {cfg.ifname} equal 4")
612 defer(ethtool, f"-X {cfg.ifname} default")
614 other_ctx = ethtool_create(cfg, "-X", "context new")
615 ethtool(f"-X {cfg.ifname} context {other_ctx} equal 4")
616 defer(ethtool, f"-X {cfg.ifname} context {other_ctx} delete")
618 ctx_id = ethtool_create(cfg, "-X", "context new")
619 ethtool(f"-X {cfg.ifname} context {ctx_id} start 2 equal 2")
620 defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
624 … flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {other_ctx}"
625 ntuple_id = ethtool_create(cfg, "-N", flow)
626 ntuple = defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")
642 flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {ctx_id}"
643 ntuple_id = ethtool_create(cfg, "-N", flow)
644 defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")
677 flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port 1234 context {ctx_id}"
678 ntuple_id = ethtool_create(cfg, "-N", flow)
679 ethtool(f"-N {cfg.ifname} delete {ntuple_id}")
686 Test that deletion returns -EBUSY when an rss context is being used
693 ctx_id = ethtool_create(cfg, "-X", "context new")
694 ctx_deleter = defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
698 flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {ctx_id}"
699 ntuple_id = ethtool_create(cfg, "-N", flow)
700 defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")
702 # attempt to delete in-use context
722 ksft_pr(f"Increasing queue count {queue_cnt} -> 4")
723 ethtool(f"-L {cfg.ifname} combined 4")
724 defer(ethtool, f"-L {cfg.ifname} combined {queue_cnt}")
729 ethtool(f"-X {cfg.ifname} equal 1")
730 defer(ethtool, f"-X {cfg.ifname} default")
733 ctx_id = ethtool_create(cfg, "-X", "context new equal 2")
734 defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
738 …flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port} context {ctx_id} action 2"
740 ntuple_id = ethtool_create(cfg, "-N", flow)
743 defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")
745 _send_traffic_check(cfg, port, f"context {ctx_id}", { 'target': (2, 3),
750 def main() -> None: