Commit 3f1af485 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'bnxt_en-fix-rss-context-and-ntuple-filter-issues'

Michael Chan says:

====================
bnxt_en: Fix RSS context and ntuple filter issues

The first patch fixes the problem of ifup failing if one or more RSS
contexts were previously created.  The 2nd patch fixes ntuple filter
deletion errors in ifdown state.  The last patch adds self tests to
cover these failure cases.
====================

Link: https://patch.msgid.link/20260219185313.2682148-1-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 470c7ca2 ce5a0f46
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -6240,6 +6240,9 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
	int rc;

	set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state);
	if (!test_bit(BNXT_STATE_OPEN, &bp->state))
		return 0;

	rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE);
	if (rc)
		return rc;
@@ -10889,13 +10892,11 @@ void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
	struct bnxt_ntuple_filter *ntp_fltr;
	int i;

	if (netif_running(bp->dev)) {
	bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
	for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
		if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
			bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
	}
	}
	if (!all)
		return;

+98 −2
Original line number Diff line number Diff line
@@ -4,13 +4,15 @@
import datetime
import random
import re
import time
from lib.py import ksft_run, ksft_pr, ksft_exit
from lib.py import ksft_eq, ksft_ne, ksft_ge, ksft_in, ksft_lt, ksft_true, ksft_raises
from lib.py import NetDrvEpEnv
from lib.py import EthtoolFamily, NetdevFamily
from lib.py import KsftSkipEx, KsftFailEx
from lib.py import ksft_disruptive
from lib.py import rand_port
from lib.py import ethtool, ip, defer, GenerateTraffic, CmdExitFailure
from lib.py import cmd, ethtool, ip, defer, GenerateTraffic, CmdExitFailure, wait_file


def _rss_key_str(key):
@@ -809,6 +811,98 @@ def test_rss_default_context_rule(cfg):
                          'noise' : (0, 1) })


@ksft_disruptive
def test_rss_context_persist_ifupdown(cfg, pre_down=False):
    """
    Test that RSS contexts and their associated ntuple filters persist across
    an interface down/up cycle.

    """

    require_ntuple(cfg)

    qcnt = len(_get_rx_cnts(cfg))
    if qcnt < 6:
        try:
            ethtool(f"-L {cfg.ifname} combined 6")
            defer(ethtool, f"-L {cfg.ifname} combined {qcnt}")
        except Exception as exc:
            raise KsftSkipEx("Not enough queues for the test") from exc

    ethtool(f"-X {cfg.ifname} equal 2")
    defer(ethtool, f"-X {cfg.ifname} default")

    ifup = defer(ip, f"link set dev {cfg.ifname} up")
    if pre_down:
        ip(f"link set dev {cfg.ifname} down")

    try:
        ctx1_id = ethtool_create(cfg, "-X", "context new start 2 equal 2")
        defer(ethtool, f"-X {cfg.ifname} context {ctx1_id} delete")
    except CmdExitFailure as exc:
        raise KsftSkipEx("Create context not supported with interface down") from exc

    ctx2_id = ethtool_create(cfg, "-X", "context new start 4 equal 2")
    defer(ethtool, f"-X {cfg.ifname} context {ctx2_id} delete")

    port_ctx2 = rand_port()
    flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port_ctx2} context {ctx2_id}"
    ntuple_id = ethtool_create(cfg, "-N", flow)
    defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")

    if not pre_down:
        ip(f"link set dev {cfg.ifname} down")
    ifup.exec()

    wait_file(f"/sys/class/net/{cfg.ifname}/carrier",
        lambda x: x.strip() == "1", deadline=20)

    remote_addr = cfg.remote_addr_v[cfg.addr_ipver]
    for _ in range(10):
        if cmd(f"ping -c 1 -W 1 {remote_addr}", fail=False).ret == 0:
            break
        time.sleep(1)
    else:
        raise KsftSkipEx("Cannot reach remote host after interface up")

    ctxs = cfg.ethnl.rss_get({'header': {'dev-name': cfg.ifname}}, dump=True)

    data1 = [c for c in ctxs if c.get('context') == ctx1_id]
    ksft_eq(len(data1), 1, f"Context {ctx1_id} should persist after ifup")

    data2 = [c for c in ctxs if c.get('context') == ctx2_id]
    ksft_eq(len(data2), 1, f"Context {ctx2_id} should persist after ifup")

    _ntuple_rule_check(cfg, ntuple_id, ctx2_id)

    cnts = _get_rx_cnts(cfg)
    GenerateTraffic(cfg).wait_pkts_and_stop(20000)
    cnts = _get_rx_cnts(cfg, prev=cnts)

    main_traffic = sum(cnts[0:2])
    ksft_ge(main_traffic, 18000, f"Main context traffic distribution: {cnts}")
    ksft_lt(sum(cnts[2:6]), 500, f"Other context queues should be mostly empty: {cnts}")

    _send_traffic_check(cfg, port_ctx2, f"context {ctx2_id}",
                        {'target': (4, 5),
                         'noise': (0, 1),
                         'empty': (2, 3)})


def test_rss_context_persist_create_and_ifdown(cfg):
    """
    Create RSS contexts then cycle the interface down and up.
    """
    test_rss_context_persist_ifupdown(cfg, pre_down=False)


def test_rss_context_persist_ifdown_and_create(cfg):
    """
    Bring interface down first, then create RSS contexts and bring up.
    """
    test_rss_context_persist_ifupdown(cfg, pre_down=True)


def main() -> None:
    with NetDrvEpEnv(__file__, nsim_test=False) as cfg:
        cfg.context_cnt = None
@@ -823,7 +917,9 @@ def main() -> None:
                  test_rss_context_out_of_order, test_rss_context4_create_with_cfg,
                  test_flow_add_context_missing,
                  test_delete_rss_context_busy, test_rss_ntuple_addition,
                  test_rss_default_context_rule],
                  test_rss_default_context_rule,
                  test_rss_context_persist_create_and_ifdown,
                  test_rss_context_persist_ifdown_and_create],
                 args=(cfg, ))
    ksft_exit()