From nobody Fri Oct 2 05:28:19 2026 Received: from mail-ot1-f52.google.com (mail-ot1-f52.google.com [209.85.210.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 584433C3442 for ; Wed, 5 Aug 2026 03:09:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899384; cv=none; b=U+lyFhyIC8SnGq8YsfBZHhpfX/Ixyi4kezS/0lKodaXT0Ru3dGsUQ0XxFOTHvgv5tLa9ysgPIGkg0gUVO7WDVHIyGZhigTz6GJcS/NbalLRajqDyw5qZwxj40M255IMhiYIqMHwowvPKyKL3yuMwu9xs+mgk5Y0MW2AY7iwzCsE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899384; c=relaxed/simple; bh=bFLblOr7/KRtDWGaNUQ/oxXl5YkPdtI2jyGgXHP9qko=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t8FIcxHdz5h9aJDq9Z5Qaj0xHBpG8NQPjZd1tNlU5QwIplnlPPN/bWRumK52MA/CZhHRkI0A7SjshF0mJ3z4LLfhLSirRmTpKrmzqvtZuZrTEsjRTDb/+dpYWNpCwy4e2rWjBLI0Ka1Xxpgt5t4w/AaSjpHNKZYfHEpYg0do5bc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rO+WoNmf; arc=none smtp.client-ip=209.85.210.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rO+WoNmf" Received: by mail-ot1-f52.google.com with SMTP id 46e09a7af769-7e9ecd7216cso354515a34.3 for ; Tue, 04 Aug 2026 20:09:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899382; x=1786504182; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OtqhiQPtfLx478uCqIbccXvcoISzUjC+Hx+PXZFH8QM=; b=rO+WoNmfbg0eSFcqarVT07ZnGLu6pD6yC1N0OTL/t0F3Y7jdtHE0In3ZtCtdToQO4P KQXJOiuep2BUB0C/a0TWfV5+ZIgyLbq2qlWKCD6Da3sYkZWgysGzj++RuX4OSMtHLxjD 3SlsVzmiFm7FGjN4v4BVY1l3KdXLpCVe1C0iaVmEtB2cRwyVPQxSmU+bYwJwLSyJmKb3 3y1XgzI8eCQHC90I7kGHygNGyx/N5H4FSczJaBt4rh8fHK99PdoQlVSdAl3OMKi/XJJB kO/zdJ6rllJeOFL8QVFmkt7POl9/Ngx0m68ETKxeKHR+c9/fAhH4XxQeSTT+M9W7mzdg gF0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899382; x=1786504182; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OtqhiQPtfLx478uCqIbccXvcoISzUjC+Hx+PXZFH8QM=; b=pDmk9Nn7hNARwpPTsVmgjTseCnXxlrbddqSSgXizQgYMotQ71k03fJG+W73pUtZUG2 5a7ObnUHtMMjdiHnsF33zlJFV2jlfgr5GmsT87Ij+6sZiZIj8A+TI4mQziGFioBOlr9Z jRFzI8M7JJMBGk/8H0PC6QjgD9tnvq7Z9qPjbO1a9CSJ3RWqOmly2NYHBDYipu5/ZFBx K6N9yjZhq+MUxKeJZVdJPmJpp2AURalwKvHBU6eKxZeVcqiHUwMMrPQhUoXbWarqWbb3 +kr2yvYFz9MJuz3iOhdUpHZFr1wJ0HDJIS4DE960Rz5LbF/1vCngHHZIQcVWNn+Ykfpc 8+CA== X-Forwarded-Encrypted: i=1; AHgh+Rr2+Qn15aZqUgJU5msEJtbwJWkASnVnuc+SGwzrxGrgNMnsAxmviNk+jg6nOvD75iJaTL/ICxu+j6pItdo=@vger.kernel.org X-Gm-Message-State: AOJu0YyG8zoBkcMOvzp/SxZMJyTt1aCF6t/+T505Rg34GTOO8dgZUF9G dMuGI+iyTKk54Xck17V8dMbhCxAvJPKuTe9jgJIGGmrubchyb+naW9rb X-Gm-Gg: AR+sD11N18Wjbul5d8Wm9BK5v7/Oyiei45Ki17JgIRTlXyROF396g99QUvV2C8AHncd VPJBMFZwyZf50GabTH8xaJyC8dCGqVWylxoEThtsU3nZkmG4ka+cPwtKRiX0r5ztWxz9qoq9jfn 8rYVyCNlS+ffM3bkBM27zoQn2zzqblj6gi8DZx53McetEPGn8LF8psHJ/oLK7XoBHjx6Ru+cE1/ mrVDZkug2cOMul/2d7qi91nicpSoHiRh2OdqIl4r1QEmCKFkZBWfMBR8Hwe1sLRVG/MECXCKqXU A8D//mSkei10Mmi8ZylGYM0q5cF5ZfjUel76qP2wu3mSThWyNi4ANCDh5UcKm4NWcFK3ZaWsW4k JbflBnKHhNWk8AUjfFFQ9fRunhs8gJwLKHaWYtyCiyUezCv2l3xnAcWmNNa8yH7K/p/NMH4tjQO DywNHueMpBazscm+V1rmnnRK/rKpoDQE0zbKEsd0WgPsLm3aO6BFZY5k6x X-Received: by 2002:a05:6830:2116:b0:7d7:ed69:81b2 with SMTP id 46e09a7af769-7f1e5d0f2e8mr2759082a34.5.1785899382203; Tue, 04 Aug 2026 20:09:42 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:a::]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f1df2fd11dsm2032300a34.5.2026.08.04.20.09.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:41 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 01/14] selftests: net: shaper: Drop redundant command timeouts Date: Tue, 4 Aug 2026 20:09:23 -0700 Message-ID: <20260805030936.1092907-2-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Commit 57bb59ab6fa3 ("selftests: net: bump default cmd() timeout to 20 seconds") raised the default cmd() timeout to 20 seconds, so the explicit timeout=3D10 passed to the ethtool channel commands in queue_update() is now redundant and, in fact, shorter than the default. Drop it and rely on the default timeout. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index e39d270e688d..c80a4bf8cc05 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -388,7 +388,7 @@ def queue_update(cfg, nl_shaper) -> None: 'bw-max': (i + 1) * 1000}) # Delete a channel, with no shapers configured on top of the related # queue: no changes expected - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 3", timeout=3D10) + cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 3") shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, @@ -408,7 +408,7 @@ def queue_update(cfg, nl_shaper) -> None: =20 # Delete a channel, with a shaper configured on top of the related # queue: the shaper must be deleted, too - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 2", timeout=3D10) + cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 2") =20 shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, @@ -423,7 +423,7 @@ def queue_update(cfg, nl_shaper) -> None: 'bw-max': 2000}]) =20 # Restore the original channels number, no expected changes - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} {cfg.nr_queues}", t= imeout=3D10) + cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} {cfg.nr_queues}") shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f170.google.com (mail-oi1-f170.google.com [209.85.167.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52BFE3C0A0E for ; Wed, 5 Aug 2026 03:09:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899390; cv=none; b=AErNqAzSqro21J9+Gdk9Bblh6s7Wnt6FX/dYcC4VHeC8KV25vu1EEqWUtB4zTs4qAmJxAju4Q9Bxu3xNLpV8ZMYnHla3ouC07ZI8w3gF8zRDibg0+Wjx5/KfY1aU1I15Ik6JjOdSvMRix9ekxcfB8QG3+PnnKtEM9Sm1B9qDd4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899390; c=relaxed/simple; bh=rVcVd3C3n+Q0mPC6lk/W4y9JERWfHLNkhFct7QT2Nq0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X4rvYQuci/MvNElS8fhHWOBze5NG2AkNL4lUPGgilNmxVdwv3hDKwHSAP3N8oMQ27BwKK0oTZi+4Z7uUy2EOzZBeGpNBO1Ufn2Gfrdj3XMasIwqfQ2LnUtuzHMmiTcCJHolTDLMt82OafueYoJcWp8JBjnRxEBwyvtwa9wT4XAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZHuapcYM; arc=none smtp.client-ip=209.85.167.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZHuapcYM" Received: by mail-oi1-f170.google.com with SMTP id 5614622812f47-495b27007d0so340490b6e.1 for ; Tue, 04 Aug 2026 20:09:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899385; x=1786504185; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=TNgnmn2b+Vqb757WTvKl3lRNBm9PUuScJQ0FPRh8Z4E=; b=ZHuapcYM53FQY1mprUSQ8NQCexXrXWFPzKjxcsNuMdEY1rmOF093QxExwWf3e+jVYC e3J46hOug+ngs9vVHqgD0Q4B4HlpLD3CXF14RTIlHrE3VjMM/rREuTwN9cryljYZdfTC 9UkdED6F2sdMOZ38uv8CNtLBOKNSfl5tHcj5OStFU4QHlWeqgyFP0oUA/UWSMdxOsrZa TB0juBvXAEnH4QsyqVV8n1GZTOOCoWRLWHjvKNHCrzMoMaClO+TWpX8jqQezG64HJ45a 2ZUgTRd3pwr6dS8OuKtW6KF1cMnBotja8qk/aApZQq9gZe6MpeOoLOLhAiCGLJq+5FPV InQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899385; x=1786504185; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=TNgnmn2b+Vqb757WTvKl3lRNBm9PUuScJQ0FPRh8Z4E=; b=mMn3qew4aVKdC1mU69/Z8ie/6Vco/POZh/aItw3HvAnBudU+WvzSYRWBUQiVHSA1yk IGJXCPuNKbnzkgwFRK0VnwxnT7zpj5QHExsffnCLxdNfpv7nAuMAzCKN7ltDxjg8KUov GMcYN1Hz6x8nq/oimN1cBrQbRu75m1b5Z29F1IQG+Lhtx2jewKg9nDLAJ4guafVR+mGC FlFkiJlE1054Tm+yGCmt/UndnrrugaouLV2jugZ57N7GAjDy0l3Pg/fVUw7/zHbCYwiN 5BCd+ITqUxg8NymPwudoyj+6EEVdz1+Rnvk9fbOaxrFc+AJu+GmFtRRpsZ017rGMVjNu vXBw== X-Forwarded-Encrypted: i=1; AHgh+RoNbsh0CKxrHecyiFY5aw6joDzc41bkc+ks+lNiOJPdf+3JvbVn5SZQzn8i3ORPK+Kb4F+3K+8RiGSQcC0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxw+KIxrJFy2vr7Td5J8ALxTLT/BvU1KunAH76pIdf9lBXhqNGV vIyvK8TgBB7YlSq4nLevNo096Kuwb0WUKuqDgmZpar0Tp9E7R1v9exXn X-Gm-Gg: AR+sD11I/EW3YgIO1beHC6tOFl1xQFcB819nPdHSEcXI75elKTuGvNG8hTN8LVa4KQ2 O2zRUbj+7dxvfLw3EYEFVlVHD9LKF0j8wfkJ+FPk/qimwrnIp6GN89KRyOAk+WnnDF6EbwrvpKN 3jYjRy33DSg2ApzI4O2b6jASExXjnXUU7Y5ih73jICcWniDYjHJGACEOaPp4ablPwtccEnSBKCj OSIEFl9aq69OKdE2mFyDWTfwcmMW0PDhyjb1so3UeJ8h0W72+Bbgee1Gn6ufFD/Rp2320M8myzp i0mG1Ijio1LGBQb06aLHgMbbTl3MaUy+19j1vIywNZ3WIOf1ErxUGNx/7TEftUZa/srTQuv+ix/ dzM2/W6vI6dhAXCvDU+48qkn8D/pYZJEAIpBtOMQybhCVkV20hF9gY25AfdtCQ2t+CzKh3u/n2w qZFRBZNWfAMWEi9kkYFVZEQpyFnAKVeb4hYiuR5mwbDizCd0+/6x/oysz5vg== X-Received: by 2002:a05:6808:118c:b0:497:df42:1e05 with SMTP id 5614622812f47-4afade463b8mr2002026b6e.8.1785899385498; Tue, 04 Aug 2026 20:09:45 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:59::]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4afae45b630sm1066020b6e.1.2026.08.04.20.09.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:44 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 02/14] selftests: net: shaper: Prepare helpers for group tests Date: Tue, 4 Aug 2026 20:09:24 -0700 Message-ID: <20260805030936.1092907-3-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir dup_leaves expects the kernel to reject a group request that lists the same queue twice. When that rejection does not happen, ksft_raises only records a failed check and leaves cm.exception as None, so the following errno check raises AttributeError. Worse, the accepted group request leaves a node shaper and queue 0 behind, which makes later tests fail for an unrelated reason. Handle the negative test explicitly instead. If group fails, verify that the errno is EINVAL and return. If group succeeds, delete the node returned by the operation and queue 0 before reporting the failure. Give the duplicate leaves different weights so the request still contains two distinct leaf entries while exercising duplicate handle validation. This also introduces _delete_shaper(), cached _cap_get(), and _require_caps() helpers as preparation for the following shaper group tests. The follow-on tests need the same capability checks for node and queue scope support. Keeping that logic in one place avoids repeating raw EOPNOTSUPP handling in each test. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 145 +++++++++++------- 1 file changed, 86 insertions(+), 59 deletions(-) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index c80a4bf8cc05..1954f3263f25 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -2,13 +2,52 @@ # SPDX-License-Identifier: GPL-2.0 =20 import errno +import glob =20 from lib.py import ksft_run, ksft_exit -from lib.py import ksft_eq, ksft_raises, ksft_true, KsftSkipEx +from lib.py import ksft_eq, ksft_true, ksft_raises, KsftSkipEx from lib.py import EthtoolFamily, NetshaperFamily from lib.py import NetDrvEnv from lib.py import NlError -from lib.py import cmd +from lib.py import cmd, defer + +def _delete_shaper(cfg, nl_shaper, handle) -> None: + """ Delete the shaper identified by handle, ignoring a missing-shaper = error. """ + try: + nl_shaper.delete({'ifindex': cfg.ifindex, + 'handle': handle}) + except NlError as e: + if e.error !=3D errno.ENOENT: + raise + +def _require_queues(cfg, count): + """ Return the netdev TX queue count, skipping the test if fewer than = count exist. """ + qcnt =3D len(glob.glob(f"/sys/class/net/{cfg.ifname}/queues/tx-*")) + if qcnt < count: + raise KsftSkipEx(f"netdev has {qcnt} queues, {count} required") + return qcnt + +def _cap_get(cfg, nl_shaper, scope): + """ Return the shaper capabilities for the given scope, caching them o= n cfg. """ + if not hasattr(cfg, 'cap_cache'): + cfg.cap_cache =3D {} + if scope not in cfg.cap_cache: + cfg.cap_cache[scope] =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, + 'scope': scope}) + + return cfg.cap_cache[scope] + +def _require_caps(cfg, nl_shaper, scope, caps, msg) -> None: + """ Skip the test unless the given scope advertises all the required c= aps. """ + try: + supported =3D _cap_get(cfg, nl_shaper, scope) + except NlError as e: + if e.error =3D=3D errno.EOPNOTSUPP: + raise KsftSkipEx(f"{scope} scope shapers not supported by the = device") + raise + + if not set(caps).issubset(supported): + raise KsftSkipEx(msg) =20 def get_shapers(cfg, nl_shaper) -> None: try: @@ -44,17 +83,8 @@ def set_qshapers(cfg, nl_shaper) -> None: if not 'support-bw-max' in caps or not 'support-metric-bps' in caps: raise KsftSkipEx("device does not support queue scope shapers with= bw_max and metric bps") =20 - cfg.queues =3D True; - netnl =3D EthtoolFamily() - channels =3D netnl.channels_get({'header': {'dev-index': cfg.ifindex}}) - if channels['combined-count'] =3D=3D 0: - cfg.rx_type =3D 'rx' - cfg.nr_queues =3D channels['rx-count'] - else: - cfg.rx_type =3D 'combined' - cfg.nr_queues =3D channels['combined-count'] - if cfg.nr_queues < 3: - raise KsftSkipEx(f"device does not support enough queues min 3 fou= nd {cfg.nr_queues}") + _require_queues(cfg, 3) + cfg.queues =3D True =20 nl_shaper.set({'ifindex': cfg.ifindex, 'handle': {'scope': 'queue', 'id': 1}, @@ -140,8 +170,7 @@ def del_nshapers(cfg, nl_shaper) -> None: def basic_groups(cfg, nl_shaper) -> None: if not cfg.netdev: raise KsftSkipEx("netdev shaper not supported by the device") - if cfg.nr_queues < 3: - raise KsftSkipEx(f"netdev does not have enough queues min 3 report= ed {cfg.nr_queues}") + _require_queues(cfg, 3) =20 try: caps =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, @@ -186,28 +215,14 @@ def basic_groups(cfg, nl_shaper) -> None: 'handle': {'scope': 'netdev'}}) =20 def qgroups(cfg, nl_shaper) -> None: - if cfg.nr_queues < 4: - raise KsftSkipEx(f"netdev does not have enough queues min 4 report= ed {cfg.nr_queues}") - try: - caps =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, - 'scope':'node'}) - except NlError as e: - if e.error =3D=3D 95: - raise KsftSkipEx("shapers not supported by the device") - raise - if not 'support-bw-max' in caps or not 'support-metric-bps' in caps: - raise KsftSkipEx("device does not support node scope shapers with = bw_max and metric bps") - try: - caps =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, - 'scope':'queue'}) - except NlError as e: - if e.error =3D=3D 95: - raise KsftSkipEx("shapers not supported by the device") - raise - if not 'support-nesting' in caps or not 'support-weight' in caps or no= t 'support-metric-bps' in caps: - raise KsftSkipEx("device does not support nested queue scope s= hapers with weight") + _require_queues(cfg, 4) + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps'], + "device does not support node scope shapers with bw_max = and metric bps") + _require_caps(cfg, nl_shaper, 'queue', + ['support-nesting', 'support-weight'], + "device does not support nested queue scope shapers with= weight") =20 - cfg.groups =3D True; node_handle =3D nl_shaper.group({ 'ifindex': cfg.ifindex, 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, @@ -285,17 +300,12 @@ def qgroups(cfg, nl_shaper) -> None: ksft_eq(len(shapers), 0) =20 def delegation(cfg, nl_shaper) -> None: - if not cfg.groups: - raise KsftSkipEx("device does not support node scope") - try: - caps =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, - 'scope':'node'}) - except NlError as e: - if e.error =3D=3D 95: - raise KsftSkipEx("node scope shapers not supported by the devi= ce") - raise - if not 'support-nesting' in caps: - raise KsftSkipEx("device does not support node scope shapers nesti= ng") + _require_queues(cfg, 4) + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support node scope shapers with bw_max,= metric bps and nesting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") =20 node_handle =3D nl_shaper.group({ 'ifindex': cfg.ifindex, @@ -376,19 +386,24 @@ def delegation(cfg, nl_shaper) -> None: ksft_eq(len(shapers), 0) =20 def queue_update(cfg, nl_shaper) -> None: - if cfg.nr_queues < 4: - raise KsftSkipEx(f"netdev does not have enough queues min 4 report= ed {cfg.nr_queues}") + nq =3D _require_queues(cfg, 4) if not cfg.queues: raise KsftSkipEx("device does not support queue scope") =20 + netnl =3D EthtoolFamily() + channels =3D netnl.channels_get({'header': {'dev-index': cfg.ifindex}}) + ch_type =3D 'combined' if channels['combined-count'] else 'tx' + for i in range(3): nl_shaper.set({'ifindex': cfg.ifindex, 'handle': {'scope': 'queue', 'id': i}, 'metric': 'bps', 'bw-max': (i + 1) * 1000}) + defer(cmd, f"ethtool -L {cfg.dev['ifname']} {ch_type} {nq}") + # Delete a channel, with no shapers configured on top of the related # queue: no changes expected - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 3") + cmd(f"ethtool -L {cfg.dev['ifname']} {ch_type} 3") shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, @@ -408,7 +423,7 @@ def queue_update(cfg, nl_shaper) -> None: =20 # Delete a channel, with a shaper configured on top of the related # queue: the shaper must be deleted, too - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} 2") + cmd(f"ethtool -L {cfg.dev['ifname']} {ch_type} 2") =20 shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, @@ -423,7 +438,7 @@ def queue_update(cfg, nl_shaper) -> None: 'bw-max': 2000}]) =20 # Restore the original channels number, no expected changes - cmd(f"ethtool -L {cfg.dev['ifname']} {cfg.rx_type} {cfg.nr_queues}") + cmd(f"ethtool -L {cfg.dev['ifname']} {ch_type} {nq}") shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, @@ -443,25 +458,37 @@ def queue_update(cfg, nl_shaper) -> None: =20 def dup_leaves(cfg, nl_shaper) -> None: """ Ensure that the kernel rejects duplicate leaves. """ - if not cfg.groups: - raise KsftSkipEx("device does not support node scope") + _require_caps(cfg, nl_shaper, 'node', ['support-bw-max', 'support-metr= ic-bps'], + "device does not support node scope shapers with bw_max = and metric bps") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") =20 + node_handle =3D None with ksft_raises(NlError) as cm: - nl_shaper.group({ + node_handle =3D nl_shaper.group({ 'ifindex': cfg.ifindex, - 'leaves':[{'handle': {'scope': 'queue', 'id': 0}}, - {'handle': {'scope': 'queue', 'id': 0}}], + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 0}, + 'weight': 2}], 'handle': {'scope':'node'}, 'metric': 'bps', 'bw-max': 10000}) + + # Clean up in case the kernel wrongly accepted the request. + if node_handle: + _delete_shaper(cfg, nl_shaper, node_handle['handle']) + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + + # ksft_raises() has already recorded the failure if nothing was raised. + if cm.exception is None: + return ksft_eq(cm.exception.error, errno.EINVAL) =20 def main() -> None: with NetDrvEnv(__file__, queue_count=3D4) as cfg: cfg.queues =3D False cfg.netdev =3D False - cfg.groups =3D False - cfg.nr_queues =3D 0 ksft_run([get_shapers, get_caps, set_qshapers, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-ot1-f48.google.com (mail-ot1-f48.google.com [209.85.210.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 789F33C1406 for ; Wed, 5 Aug 2026 03:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899392; cv=none; b=tXyf533nqtlp8a+psEGi6gg7fb8LkMwbmkE35IgnBuhsskoRdMyW38K28Sa96YBc/YuYrz32ybfBwbIuCF9Zt6hFx3/nnxCN8pnQSz5/1XFFk+Iwmg6cfHTLbKmuJY5MkKpA8KGqJFC1aeX+NioJOMFHbJtvxGjW5WTWl1Kr6nw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899392; c=relaxed/simple; bh=XRFbGwBPH+VhcUUJQun7WEUilFRIAXetdV49cKT2ZsY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k/zuseh+RQMGOXNS89zHV1uuSr7M+f4VL13EgH5ut0hzLksv6X8VuTNT6cQTv5lYpE0cLUY2b1tQyovoTysCUUqhnBjmbl/rbFYj91iUtGdmmExHB9qnBoHv9Vuv5+pNNaIUIZ7WmLb6g0tZDl0QoJhr9VXdZS1wLko2SV+pkcM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=a02UEEks; arc=none smtp.client-ip=209.85.210.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a02UEEks" Received: by mail-ot1-f48.google.com with SMTP id 46e09a7af769-7eb4d532e65so281529a34.0 for ; Tue, 04 Aug 2026 20:09:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899388; x=1786504188; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kHy5sGAOZy1JqOYJk5ores2aowoHjNjgJFZMFnGPHyE=; b=a02UEEksFWf7VoDG6peKCswahEDu+Wxlm73XYa/rya/kgotgyu+48nd4LcTn+5fHAg 3QeQTwesRn+/azVHmspQsD4sX7qYmsHxrfBYO6AgmCt4SzJxzRX8zy4rldbFkrqpMao3 Z+ledxb8IW+POtEO6Mq7PXPsAfChCzGc3oTpadsAcdHT4MtUXpHvi+6w47uTB+8Ll87g pIC9H0dsABLeGdL7VuKrtis5dcygVumpQNuJbcirb1KaV0s6J9V3QTr8DxVZh1hnyWic CKBI4XaCs7Pn+2FFR4wNLnYh0Oad+Xwg02MFJ662PcuMflD+CbCa9QmI1daY5lC4w5Ta Dl6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899388; x=1786504188; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kHy5sGAOZy1JqOYJk5ores2aowoHjNjgJFZMFnGPHyE=; b=ZP7tS/5aitIfFyh0joqb/0ow8upU7k1vy+0rps/7sZaJ7jAsgNA+I8Ptz0sChyWalF h42ZEJ7qqm91CtmCyuhzshltjaLIP5s0YH4n6eWjjyL5OKRamsv1BFyqCgfNBULwIoT4 BECOCZploj3ELcA/lsNlaDTJfSljROxVa5LTXkUGSe3Zw23P71ibEoN1zwMXpoxCKwAP 05V0lsHtATxlRhLeptUEEPFqlAnZDkqmc8kLuH+sFAHStlE5YyOpDKe2RehkNW2fHwxe HKONGVbzUQAbNOa2VH/5GA9z7pabinnh1McyfEiZsmEH7f/jP7bv/bPDLbby6AKmRLvm lpUg== X-Forwarded-Encrypted: i=1; AHgh+RoFmRqqeDK0Q7YHD8v+sXx2W2WAN+B+7p4pZyKIkPB4C3pkzyM3uf8wnnpEaN8ibYhuTFEbs5epzmy0ABk=@vger.kernel.org X-Gm-Message-State: AOJu0YzmiNq1yZRYmOH7CmQhTfIZ9LeV64uWRcGfQyNvUgZ6ugtTNn0U a54jOAC97dh67oSGrexxMxyhAdD30eGHY51LwMASfIeGjET4IUhitMRr X-Gm-Gg: AR+sD12slS5r16c92tKoY5zjtC55exL65HRTO1riz1Xtqif8a8PLE4Pt4tzxJA/783i 4qKaitAZ5uheeUY3SZT85GgIKcubyWC0c+ZbZji4vc2CWpwUzTvcP9NnErKj4OdqWP6j8KDRSqS cVcxuM3bncEK9OAIG8h8ztyivDEL05hTJdyyOvus9o6bnK4exJ6mlMP1Px0Aw3cjPuFTrsq6rIf niQg2QkeutaeLDtjW/cpueb5buQXdOdgv2KzMMekaCjkbn1Gctz4WtpKFdtM6i616/Diz8LV5zv 4qoAQBpB4gM0H12ILOH+y4AYblZBdPg612wReOnhhu/T1cqk3AaG/jVXvHPxLHbIJGRvm1/B4mR 5zsZ37cMA+AC0ouK1vE9xk2A+Z2W3rfXK+vsQ2t2SdiyLHxwGLYCLkH3NDXew7rQM8iinWubFhx mu+YK9VpMSDS8WtWkivulR9Y4NmazKCOahhSajBV31Ky+BkN44Fjcnc/78uA== X-Received: by 2002:a05:6820:f012:b0:6ae:87e3:e306 with SMTP id 006d021491bc7-6ae96ecc5e5mr1905385eaf.20.1785899388158; Tue, 04 Aug 2026 20:09:48 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:46::]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f1df5a4f9bsm2087653a34.23.2026.08.04.20.09.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:47 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 03/14] selftests: net: shaper: Decouple basic_groups from netdev rate limiting Date: Tue, 4 Aug 2026 20:09:25 -0700 Message-ID: <20260805030936.1092907-4-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Decouple basic_groups from the set_nshapers test dependency. The test was gated on cfg.netdev which is set by set_nshapers. Replace with direct capability checks: netdev scope support (required for grouping under netdev handle) and queue scope nesting + weight. Remove bw-max and metric from the .group call so the test validates pure queue grouping without rate limiting. The rate-limited variant is restored in the following patch, which adds a dedicated basic_groups_with_rate test. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 1954f3263f25..45a4bf42995e 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -168,19 +168,11 @@ def del_nshapers(cfg, nl_shaper) -> None: ksft_eq(len(shapers), 0) =20 def basic_groups(cfg, nl_shaper) -> None: - if not cfg.netdev: - raise KsftSkipEx("netdev shaper not supported by the device") _require_queues(cfg, 3) =20 - try: - caps =3D nl_shaper.cap_get({'ifindex': cfg.ifindex, - 'scope':'queue'}) - except NlError as e: - if e.error =3D=3D 95: - raise KsftSkipEx("shapers not supported by the device") - raise - if not 'support-weight' in caps: - raise KsftSkipEx("device does not support queue scope shapers with= weight") + _require_caps(cfg, nl_shaper, 'netdev', [], "netdev scope not supporte= d by the device") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "queue scope not supported with nesting and weight") =20 node_handle =3D nl_shaper.group({ 'ifindex': cfg.ifindex, @@ -188,31 +180,31 @@ def basic_groups(cfg, nl_shaper) -> None: 'weight': 1}, {'handle': {'scope': 'queue', 'id': 2}, 'weight': 2}], - 'handle': {'scope':'netdev'}, - 'metric': 'bps', - 'bw-max': 10000}) + 'handle': {'scope':'netdev'}}) ksft_eq(node_handle, {'ifindex': cfg.ifindex, 'handle': {'scope': 'netdev'}}) =20 + del_node =3D defer(_delete_shaper, cfg, nl_shaper, {'scope': 'netdev'}) + del_queues =3D [defer(_delete_shaper, cfg, nl_shaper, + {'scope': 'queue', 'id': qid}) + for qid in (1, 2)] + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, 'handle': {'scope': 'queue', 'id': 1}}) ksft_eq(shaper, {'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, 'handle': {'scope': 'queue', 'id': 1}, 'weight': 1 }) + for dq in del_queues: + dq.exec() =20 - nl_shaper.delete({'ifindex': cfg.ifindex, - 'handle': {'scope': 'queue', 'id': 2}}) - nl_shaper.delete({'ifindex': cfg.ifindex, - 'handle': {'scope': 'queue', 'id': 1}}) - - # Deleting all the leaves shaper does not affect the node one - # when the latter has 'netdev' scope. shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) - ksft_eq(len(shapers), 1) + ksft_eq(shapers, [{'ifindex': cfg.ifindex, + 'handle': {'scope': 'netdev'}}]) =20 - nl_shaper.delete({'ifindex': cfg.ifindex, - 'handle': {'scope': 'netdev'}}) + del_node.exec() + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) =20 def qgroups(cfg, nl_shaper) -> None: _require_queues(cfg, 4) --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oo1-f52.google.com (mail-oo1-f52.google.com [209.85.161.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 954143C3F7C for ; Wed, 5 Aug 2026 03:09:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899394; cv=none; b=nNt9w0k3TruNobX8LRMsy2ric5HVNSLbShadfOdpfiPgnbyCV2fAbrENp09HfpUYKwMYz7RerZLCP/LEZqTHSPE4NrpuMjGxhsSduOtlC4MmIPuxw8+/7sxfSaoU7TG6uRhqrcRwDvxhlmZGXEcdso9gRv5NnZi+Bo/xKA4+UXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899394; c=relaxed/simple; bh=PE7ifyCGoFgRy7ddoLf7ecEm718DOJWN2jboMYBlwCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=minQpGoPE4H1ttaV0LPF/UPJFd0pxZCKaNkjVcaWlfYEeZk3qmMAuuRRxY0B+HGH8X/ntRX2tOm5MAfwIrOy6xaae52jXD6YDvt/xjdn5TF+tnPUA0Gf6hO+c6/xP/UFZjqEW3M5hBeGo3HyWCB3wJIwdavevqHAxlDNaguuhCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HBb7gtoj; arc=none smtp.client-ip=209.85.161.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HBb7gtoj" Received: by mail-oo1-f52.google.com with SMTP id 006d021491bc7-6ae5baaef5dso483684eaf.1 for ; Tue, 04 Aug 2026 20:09:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899391; x=1786504191; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Lf+95Lv9aBLdQ2fxeuuLQftB8DvcOe6MQ4BDksXA8qc=; b=HBb7gtojsfYlAkR1l0hQQZN5GlTdFPTu30bKeB6GWNVz7aYoEdx2pleAntMWnkYOZo fXrVRSixOCjqGcA3orqqd2VjtkaICVXB8CG7tvNKt+g5WgCwjUJFwwCR5V8hkFJxEJjZ uAUA2GIqwITDBtTNSn7arbs8hB+XezdcDpBdvW1gmSd7gTqYo9fDr+jEws/OC3JOgnhe W+qMBjLf9vqv2G9E+9NODTkQ5xLToGSPZz8Il5sCPYctaxErHc8uyaPKa5FVi2MpZ1o2 aPhjEbKF8gdEYd9duNFBVpiy/sgVKJ5OA30H4Z9+cDPzxWrjXpbr6k9AjEDEEe8qwpC1 snGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899391; x=1786504191; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Lf+95Lv9aBLdQ2fxeuuLQftB8DvcOe6MQ4BDksXA8qc=; b=imgO/gyL2t2cUfmhAX17L49M9mbit0O2Rd2xBHT3Gae52fnztZGzGEDnn4gKbhORB4 W0i2rYY7Y+GpI3n2rrG3Lhd0W0ljgYk7IZDtOwR/t5ELFghmo0eT1J0602xX6Hjuj2/3 rtHP1b0CfI3m/akmt1ciIRJ5dyWuNJo+caHr30fMGawpxp85xSEY0je/DFShXxZZKQ7c djDjl6/Vw1TXpEq4h0Cu5xyUuLjDdJG/oiFKBQ8keBJ8MfLc/mQAJZ1oIyZuxOiVxC1Q Liuq3ydVw9N2k1xBn5OzcvFf8WG/S/dGGJBQW8wCgeBxD5/lZCzuQiri3DEYVVom0zzT JgXg== X-Forwarded-Encrypted: i=1; AHgh+RrI7TXlJqj9FK6LQfi6qkNgsq8AB3PiilDuqcJONP6H1GUQe+6dcxrwgKcCrxkZ7cKfV5wjzmMcXBVm8lI=@vger.kernel.org X-Gm-Message-State: AOJu0YwGS25GhP6qniAnbvzbWzzFvf6oZTtRVsgaa10gTHzKChEvuuqP QhQl+FceupQI/iASBvjOLYiFeRiHgo9jc8/OXazigiW9wOzl8YPZdBo9 X-Gm-Gg: AR+sD12BMUHnQXui6d4IcjOJ7ziqR2B8ej+6SPks52Aw2KXs9BxEho/kdxeg7RadSDF 6pz8aQ2U6ZTDDc4oFSJnOWeHpU32GOEmEo2kNkNRdkU3nJ8mpREoaZaooYK9N+Zv15UIHQvwvh8 FtxMpIqCiHvqjwnLeZb+nt1TNbvsGAQLwzwjfufL814Wq8VQK5jbQsHZFn1q5X3imMxryqP36Sz qw5cn7Q88f23eQBD/86bPBrva24/HXxVYSpnr0V1I9cftuG0EJ6G/4NGvPbdOorE3UuNL1y3g61 5djGXDs+77CHCwvNKeziIwfVT5t3aa8MFgLnPMQ+tFKm25Tu3NaLPXnL/SokwlhBQawhA7WyGDC ljxNcOVjLiR65O+lMvYoEQ6EeKMJXKRZpKcyMV5FpiyzMV8E7lN4RGQ7jUW8akE8LmIG4CUZHIG fDUGtfkwGwgCFgNszbyP04PPs/zqt5q2Qp2Ofljepm3ihS2UeBRexlKwc9 X-Received: by 2002:a4a:edca:0:b0:6ae:7f68:22f3 with SMTP id 006d021491bc7-6ae82a9ea9amr7666929eaf.16.1785899391072; Tue, 04 Aug 2026 20:09:51 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:8::]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f1df5a4f9bsm2087676a34.23.2026.08.04.20.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:50 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 04/14] selftests: net: shaper: Add basic_groups_with_rate test Date: Tue, 4 Aug 2026 20:09:26 -0700 Message-ID: <20260805030936.1092907-5-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add a test that groups queues under the netdev parent with rate limiting enabled. Extract the common group-under-netdev flow into _group_under_netdev helper to share with basic_groups. The test independently checks for netdev scope bw_max and metric capabilities before proceeding, and verifies that the netdev shaper persists after leaf deletion. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 83 +++++++++++++++---- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 45a4bf42995e..168a8dd057e5 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -167,20 +167,25 @@ def del_nshapers(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 -def basic_groups(cfg, nl_shaper) -> None: - _require_queues(cfg, 3) - - _require_caps(cfg, nl_shaper, 'netdev', [], "netdev scope not supporte= d by the device") - _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], - "queue scope not supported with nesting and weight") - - node_handle =3D nl_shaper.group({ - 'ifindex': cfg.ifindex, - 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, - 'weight': 1}, - {'handle': {'scope': 'queue', 'id': 2}, - 'weight': 2}], - 'handle': {'scope':'netdev'}}) +def _group_under_netdev(cfg, nl_shaper, bw_max=3DNone): + r"""Group queues under a netdev-scope node; caller owns node teardown. + + netdev netdev + / \ del Q1,Q2 + Q1 Q2 -------> (netdev node persists) + """ + group_args =3D { + 'ifindex': cfg.ifindex, + 'leaves': [{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 2}, + 'weight': 2}], + 'handle': {'scope': 'netdev'}} + if bw_max: + group_args['metric'] =3D 'bps' + group_args['bw-max'] =3D bw_max + + node_handle =3D nl_shaper.group(group_args) ksft_eq(node_handle, {'ifindex': cfg.ifindex, 'handle': {'scope': 'netdev'}}) =20 @@ -194,10 +199,29 @@ def basic_groups(cfg, nl_shaper) -> None: ksft_eq(shaper, {'ifindex': cfg.ifindex, 'parent': {'scope': 'netdev'}, 'handle': {'scope': 'queue', 'id': 1}, - 'weight': 1 }) + 'weight': 1}) for dq in del_queues: dq.exec() =20 + # Caller owns the node teardown so it can verify the netdev-scope node + # survives leaf deletion before removing it. + return del_node + +def basic_groups(cfg, nl_shaper) -> None: + r"""Group queues under a netdev-scope node, then tear it down. + + netdev + / \ + Q1 Q2 + """ + _require_queues(cfg, 3) + + _require_caps(cfg, nl_shaper, 'netdev', [], "netdev scope not supporte= d by the device") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "queue scope not supported with nesting and weight") + + del_node =3D _group_under_netdev(cfg, nl_shaper) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(shapers, [{'ifindex': cfg.ifindex, 'handle': {'scope': 'netdev'}}]) @@ -206,6 +230,34 @@ def basic_groups(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def basic_groups_with_rate(cfg, nl_shaper) -> None: + r"""Rate-limited netdev-scope node outlives deletion of its leaves. + + netdev[10kbps] netdev[10kbps] + / \ del Q1,Q2 + Q1 Q2 -------> (node persists) + """ + bw_max =3D 10000 + + _require_queues(cfg, 3) + + _require_caps(cfg, nl_shaper, 'netdev', ['support-bw-max', 'support-me= tric-bps'], + "device does not support netdev scope rate limiting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support queue scope shapers with nestin= g and weight") + + del_node =3D _group_under_netdev(cfg, nl_shaper, bw_max=3Dbw_max) + + # Deleting all the leaves shaper does not affect the node one + # when the latter has 'netdev' scope. + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(shapers, [{'ifindex': cfg.ifindex, + 'handle': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': bw_max}]) + + del_node.exec() + def qgroups(cfg, nl_shaper) -> None: _require_queues(cfg, 4) _require_caps(cfg, nl_shaper, 'node', @@ -488,6 +540,7 @@ def main() -> None: set_nshapers, del_nshapers, basic_groups, + basic_groups_with_rate, qgroups, delegation, dup_leaves, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f178.google.com (mail-oi1-f178.google.com [209.85.167.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7966B3C73C9 for ; Wed, 5 Aug 2026 03:09:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899397; cv=none; b=oTx3F9N4dU/HduWcduBVHuWExqEgh16SsyxYD28sHNQzwovce8ihz9r/Zee7Ojyshdz8mVtzkaqmmB+QXcRqBl2QdDQ1CgWiWb1NheLn3/atvCuN/VOJcFPdIvWmKmWS/sdyj4BJQtDNegrI6aVMPJhpEXbAt1o+vh3DR8bXe9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899397; c=relaxed/simple; bh=5YihlMOGgWUO8737n2nBj1ciLX9CpcxUKVEkBqi2ZII=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QiX6uWLczcUdeR/+N+YgaXSGBxyyoGgY7d+hySvKCMcwMJq7DB7qcIn+H/8aM7N1Tmz6IH8qKLmn8AvWev1rbPp2eHufCcxaYyMRK7LBF1ZuB0+68fWOUVlG6IlEC/Litt1th8WS9ZmLyr2juKClTj1J7qY0J2XJue0NfaRH1ys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VJfolTUH; arc=none smtp.client-ip=209.85.167.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VJfolTUH" Received: by mail-oi1-f178.google.com with SMTP id 5614622812f47-49ff971e903so1050279b6e.0 for ; Tue, 04 Aug 2026 20:09:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899394; x=1786504194; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=aYN4g/UA+fKUF44O4j859tRSP2FM/5WK3MFhT5M1mR8=; b=VJfolTUHlG+QC7gslElgB7YP2wzkss++2izA4vCSlS3zTyay0IgDXHvJlSNJllLapP 3ffoQ4+nj2FCNOGXVHSRRho+YSWCT5aDuC+B/phWehZUQzLStFQDvs42+Idk1orNQS5c ILODu9WA8jaB3G5yIujiGr2VvYTuApgEEKJiEavN6bjubzKv3XhW3sXNy7ngLHPfnelJ kfwoGDOk1o9nVlqtgyc0oBbKCOWgy7vBj7jvopMNo+DBsCi06TAsLh61MHSmXijcuTu2 XEyFPxbY4faLr1RLfWp0LRLa3gBlzOYkHmeXvRcp5sn0jiV2onGIkCCL920E6eJayCYI I3lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899394; x=1786504194; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=aYN4g/UA+fKUF44O4j859tRSP2FM/5WK3MFhT5M1mR8=; b=rUheUeRPOyYU/3BsgkerUvhcazu09w1exbkXLJwFbsYGnRmgog71tQRBvGFIF6yeey Wn8JK0+ZJPMlP8XY02vjvdX275VAlA1LvO7ErjV5yzYozWBZkMKi4pTlksnV61flyf+/ t8m6+z8gigMIf7IV8zckdPPNO6fJoiD1KMk5K6Fbn6BxkAKa1s1XAXSJ3SRa6qOAbdqB 3cQeP5DA1NL7TJoaiQo4S6+RiiBlTq26M1FwyCnX8Sf09RK4VInR4JAQbWd4yM00XuH5 H5Hdy3QiU8pKOLncpxKc0AG1EQ5wjSl8dkRcuJ7fyrUm0DpY01Ed8FQUHbmAT6ALj8mg IcAA== X-Forwarded-Encrypted: i=1; AHgh+RraOcH1MV6JX9rcl5kEli/YW0Uz1yV/8kPLd4h9iPyO6bR/7uiyx7Rgze5pugpoHioFuc844rC7y3Dpur4=@vger.kernel.org X-Gm-Message-State: AOJu0YzkgS5eOxS3C8l6sJBqQzUR4gwuzm294MMtTk+ZVwcYPIxsGwf2 YWAuBBQ0eopWrsaWliygUcJ+/Oh3T50OKWcop+ia+LfLYsG2dv24BvbW X-Gm-Gg: AR+sD12w2+IZPvAlB3z00VGpjH5Shc8a4dAjcXhGRG1/zi4xmJXoIXlzdkjLWuL5csH CyH8EtFnJifx/pL6i2gZC5Q0DgcBz4A54/hnE/bWqvJYMpd3wyjS3SWplPCZPUbrQxid2Zc9Aju 921VZVvu/dkLkiDztcG87PMkaFbrYLhuILMPIX6jvIhlM3zwayDbt5GzEVoByFAmbPBWkM4g0wI N37VJrLpm+4cju5P/4ysgOSqxN4kvAKBpXO5+vn5HUqzmzg9ERL/6Ov8yp/z5kPPIBPVP5dD7Vs CqKsaTUZYExpclhBSFKa5kzwKIo7FtIoDaTD8+I1trSZpn2pKFw9ySL6/+scGbvtkHGSa7f/Pl2 v7rI9/KHo0jRh4EoAq5Hx54PEZHrAPe5gm15s/mhClfcboFla/PRMfPbx8bfuGEVzOFRIYaJheN O37QBdBrQU3U2IaXxNXKRuH8HU123MmQYx2eC+aIAMUoLSo3g7fPH1aRJwvQ== X-Received: by 2002:a05:6808:6c82:b0:496:117b:1f04 with SMTP id 5614622812f47-4af987d26e3mr8317618b6e.2.1785899394199; Tue, 04 Aug 2026 20:09:54 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:17::]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4afae75ce1bsm976885b6e.15.2026.08.04.20.09.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:53 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 05/14] selftests: net: shaper: Add node scope .set rate update test Date: Tue, 4 Aug 2026 20:09:27 -0700 Message-ID: <20260805030936.1092907-6-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add set_node_shaper to test updating a NODE scope shaper's rate via the .set callback. Creates a node group with bw_max=3D10000, updates to 20000 via .set, and verifies the change. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 168a8dd057e5..62ac83b7701c 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -343,6 +343,43 @@ def qgroups(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def set_node_shaper(cfg, nl_shaper) -> None: + """ Verify a node-scope shaper rate can be updated via .set. """ + _require_queues(cfg, 2) + _require_caps(cfg, nl_shaper, 'node', ['support-bw-max', 'support-metr= ic-bps'], + "device does not support node scope shapers with bw_max = and metric bps") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + node_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 10000}) + node_id =3D node_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 1}) + + # Update the node's rate via .set + nl_shaper.set({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}, + 'metric': 'bps', + 'bw-max': 20000}) + + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': 20000}) + + # Cleanup + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': 1}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def delegation(cfg, nl_shaper) -> None: _require_queues(cfg, 4) _require_caps(cfg, nl_shaper, 'node', @@ -542,6 +579,7 @@ def main() -> None: basic_groups, basic_groups_with_rate, qgroups, + set_node_shaper, delegation, dup_leaves, queue_update], --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A5E93C4172 for ; Wed, 5 Aug 2026 03:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899400; cv=none; b=T9SkkIYvfGB/F+4OTVpLJU3fWh5RThPrMfeGM4FxKM1RxJmxJaOjMmBICagUkZd6te6JRzZAbC6JLvlk39jWfQUKbWwCVVKllHJar/jWaiIJWZrfOQdmJceip1GwgTBKN3UmRKf4KMwrcYJdSHLebRmWfR+58zKOVvWFu1Qhz98= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899400; c=relaxed/simple; bh=3szltxY+VKk6xH+PjO6+PE+6DNN7VLfS1oL4wAwfWNA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g50NChgJZcwZimEizxwe5DcsX+rTx5FOs4lSlVHNuIw0ZG4p25m3XXZPHD/FawInDyxMd/WDHXqFB0SOiYD5DFQOhXXFxiQgv+UlVAOfxQTJhR1aQeQBDIR9pjHA3H6NozCA7uqsX6r8VLPKbEtQvCKP1Pkistu6JsaGnZ+Buac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JCqWzAp4; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JCqWzAp4" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-7eb4d532e65so281556a34.0 for ; Tue, 04 Aug 2026 20:09:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899397; x=1786504197; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=yx9eKdgdP27MAi2E7/idObyxLUuxucE1tvirxr3bM3A=; b=JCqWzAp47ocZjsiyfR2ehPlwiOt+9ScULRXT+VW8z0hqai+9mU+qSydfAJY+exETKP v0BnmTIEM4Puo2WrOBH0ttrWeQDUvK1SKDW3ApYV1/OBb6pqDVDF+7kwjxiEuoit4MPw SOuqghk2VseJhr/vYCr5RjeANbj1++1vn2D/5H1yNkSZu3XXICRrbLcqif8VjlDxTNnr lR6VZgkSCyiV5qYdbIEyMzBdkzNLBHdfzBg5i6HXFGmLcF26hPHY1dLNtkgVYptHX8yc 0V2n3cswvQcADzZfvXWRb6rfjMwbXldQxw8NUPnz4aoIly3VqupjjTNdE4MWdMP7f02T VlFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899397; x=1786504197; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=yx9eKdgdP27MAi2E7/idObyxLUuxucE1tvirxr3bM3A=; b=pgxEP8KquJNTsEOd0HS75aajLosV2RGCGUU/zq/czLQ7wOKgQEPbIr3LNtOeEiW9CW e/i8qDVD/l0pNRTDNDuOylsbEKI4yYRgVB45HOH5xsV5FD+Tp/CwCVdpvE/UOx2pAT7g 6Frcw9CEvvYyzj+JPtFRk6Ga1MOmUayozEGnqqKn6ehXk4Vh5plCegznJVdpLsMkejQr kO8jKtvo183XUZ/Zn2lMMpXIVbVDwwlqx6VUGgG225UBlyuT+XogP/MdT65WzED2rBYL 2PXfgeapUa2U+TKyB4jkVmuKASiWxu6NqCy1SzDAEXIrEdJcDscR6uQ22NCK4BNWF/Uz MUzw== X-Forwarded-Encrypted: i=1; AHgh+Rr2ls1Jh6mdhANLE/b9chUtQsg5OVvNiYmwIVTipu75eQU6lbTOkkJ9NFj7GhG9XU4WfElJc0MF24s2r84=@vger.kernel.org X-Gm-Message-State: AOJu0YzWWb1fbZV8bNqLQRMZwerNPn+bhV5o+e70sAzCav1qR4p2Rr77 7JgWuk8iq05gG7ksVgTY/DNaUWrdAgOARGqVHR35BwctFYhbqYqBrPR/V4HQICAY X-Gm-Gg: AR+sD11JYdn/87a19Y5BqGbBKM0m5z/6Udb5BJC7VAMDexW0BjEd19X3Vgfm/nb0y5t FKvT9swC2EqxY3k8Z7iURDLBdZRry2sOqvWlIPT5/KHwfeU7jRNaqzDxY5U6kTwBbMyPcXlCYb6 fhKJnJ9lHYOb1EfB+jxniP7xU6X+mkAy8uhjDfNc7YiUirct9DYgM5SHIye2sBaWxT5oq5Ra6hA MOvnX33dTigHkCK/XyWAD/pVy8v9ZHGRRK9NZMsTTfh8MHqA0UN/EhadfJduYK3sCccjPK3cz0t Bug3Z+pq2swL8GyFt6bjjfB1Ij1EYdvqc8RdJ0rk9h3vFFB/fU+FG8Hu7R36K4Tdra99ueyCAqL 70FTDxys7ZRMb0un1h6UmPcEsHQF60ob8v2DvqcPu+oEfWYPOsZYXqgQ9e7Ijz7xDs4TMt4YOQ5 DytljdPGNnxG3pfy3bQ1LJay43gpgCP060798rqSDlsYmMAfW95VJpc7/Vgg== X-Received: by 2002:a05:6820:1c89:b0:6a1:963d:a040 with SMTP id 006d021491bc7-6ae96c1b2famr2191220eaf.2.1785899397197; Tue, 04 Aug 2026 20:09:57 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:47::]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-6ae940782desm1636211eaf.14.2026.08.04.20.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:56 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 06/14] selftests: net: shaper: Add .group rate update test Date: Tue, 4 Aug 2026 20:09:28 -0700 Message-ID: <20260805030936.1092907-7-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add group_update_rate to test updating an existing node's rate via the .group callback. Creates a node with bw_max=3D10000, re-groups with bw_max=3D50000, and verifies the rate changed while leaves remain under the same node. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 62ac83b7701c..5eccbe437ba3 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -380,6 +380,72 @@ def set_node_shaper(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def group_update_rate(cfg, nl_shaper) -> None: + """ Verify re-grouping a node updates its rate while leaving the leave= s untouched. """ + _require_queues(cfg, 3) + _require_caps(cfg, nl_shaper, 'node', ['support-bw-max', 'support-metr= ic-bps'], + "device does not support node scope shapers with bw_max = and metric bps") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + # Create node with Q1, Q2 at bw_max=3D10000 + node_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 10000}) + node_id =3D node_handle['handle']['id'] + for i in range(1, 3): + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': i}) + + # Update rate via .group on the same node + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}], + 'handle': {'scope':'node', 'id': node_id}, + 'metric': 'bps', + 'bw-max': 50000}) + + # Verify rate updated + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': 50000}) + + # Verify leaves unchanged + shaper_q1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 1}}) + ksft_eq(shaper_q1, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}) + shaper_q2 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 2}}) + ksft_eq(shaper_q2, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}) + + # Make sure we only have 3 shapers including 2 queues and the node + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 3) + + # Cleanup + for i in range(1, 3): + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': i}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def delegation(cfg, nl_shaper) -> None: _require_queues(cfg, 4) _require_caps(cfg, nl_shaper, 'node', @@ -580,6 +646,7 @@ def main() -> None: basic_groups_with_rate, qgroups, set_node_shaper, + group_update_rate, delegation, dup_leaves, queue_update], --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oa1-f41.google.com (mail-oa1-f41.google.com [209.85.160.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 380423C10B9 for ; Wed, 5 Aug 2026 03:10:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899404; cv=none; b=IRY+Q4IEnQV5REa870eQpM35CtXYhCOSCU4x06y/k2Rj8cn8pk46coCUkj/eoTx0KFTYBRJlbiz4MKoWmBywgkzayILW32IQA8H+EuuiVsUldHPfpB71VDpjTur1c4/YjejyXZfn/E2kjAFqHZl3ZPViKE4doMX2YhR0oTk+zgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899404; c=relaxed/simple; bh=oQhugvCMYGy3aYRRfeKE10bMevHlLebPckLOxjXzNpo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GDhxl1cH/Q3Jteh9cwP8a/q/ga8iEgtNkYlsTYs5i3gFsyZg/0+KQGeUHYy86TyiZqKBhPZUhPBRkX4s7rTDcA92mgSGzU/Nr4wcXSSDhzQrSEGcsz09KVINWX2arbTyi+C2NH7xa/JD7gwshfWS9ErKGM5G180ZzP6x+PpGhko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DJInWa77; arc=none smtp.client-ip=209.85.160.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DJInWa77" Received: by mail-oa1-f41.google.com with SMTP id 586e51a60fabf-456f7012050so1313980fac.0 for ; Tue, 04 Aug 2026 20:10:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899400; x=1786504200; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=4UYo3FcDc5RU/v3Uu1cX8c+hEHFvI0I8XStdhmaMcys=; b=DJInWa77/Uhli2eS954S03nmD0TmZ6G0Oe37JhY7zFrsx8iCJixU6YL8bHH4VBL+cN nsCP9BdDvMF141zXjSAVWLAyde+GCSRF6ilHTA2uGokocFCTATJ7++30eswtXkk8tY/c j+RoGjXy9FYXk4QjmwnojJGmCfK79HqlTaWwl6CfdCaEptFgr3uorGZMCuY5puVvukbp jVd45uVCamwKKMQ2pLU/SuHJL8/m34/olsGLAPlPc0KE8tWaKMbvB613huGVUe9ro0FA DzF9gnMwJiC9iSReWwvcTOgmeTj4tXGA2hJBQpkXqdZUilnfzDL11yq1owSuk8V1PrPz 8NaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899400; x=1786504200; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=4UYo3FcDc5RU/v3Uu1cX8c+hEHFvI0I8XStdhmaMcys=; b=FTj/0EwYf/gF9YQcl/C8VFDz3OkVZm8ZphyhlRttOUFSBPuc+/IK2Qzx1BhrSBPtzd +AQ6J8lH8k430Kj1THajUlGD/ZDza83Hx/pJKgF89NtkTNZcxZ2szOgd6+Odai2NFwAE FhD5RrPapptlz3e5m0bDJopUvLvdljYvsrdCZcA4zK0TC3J5iKTHR0H+w+Rbg1JqBUvi MsmBarX0Zd7sv/NYjoBFp4VieK3FhdF76NTJTcSJuii2sLI4d3KqQNPyi0so41di2vF0 k9qCtNI4P8NwblNR30SM5BmwbiQA35WHDCtFFzdngPaCG0SDkqTtNh6/Hnb4FrDIkwsh 9oUQ== X-Forwarded-Encrypted: i=1; AHgh+Rp0Z/9TuwNQsplygopWMCecyybhgN355TlGOpLj1L5sCGnDb124n2rvYfS/wOh/dHcR30zVJmUJbxoZoZc=@vger.kernel.org X-Gm-Message-State: AOJu0YwM2HTg0nDVORr5dIGfNVPHeb/fKsBRibUXMF1MZbTTPR+m4zIn eTDpVEecbgSLdN9AJhI6SfHIf1rINgZT4CGIyb2XK48P6fdAOlyluPwL X-Gm-Gg: AR+sD12BMt93d8Ih4QO2OR+y8V9pddG/8na112KMe82WDxr8WOijawK8lGX/ztraz6q nbl+JfKGDL8or+M3pHYp82b/dQZt5aPPUERekbZDKgUcW3Se2t7X4RU1oUFS+9Rv/kWM6Xi3+rG 83P2An8Yy5Dunxjxx+UWCqMDvsQ0jvI93bJRWDzGPo0iCjrRdP+4XsKXqGFJV46EuYBG/xR4uiL E6s6Had7a6WhBGw1chT6r1TMdDGwfDc54Ytt5R6hIt57auijDqzHRdaDrWISyBvEq2KqCReTkhr 068csLgdrIXlQljG2yvHgLGX9tzEhaUu7fkE/Nk+0DBE8i8vq4MGH3fJYgGt9f11ORI5YhTEYaJ 9nvwDe8p02ITgA7mXmHMiLryQSYSLi8Vr84u+0/SbI5YUcibmbbr2jLb6KLVBM8nmgSwAEC+IRQ RNdQOgDvExaHuBZ+u8A2ezQRdt8Qqox5H9sBLTddf34YyOFQINVZwB/hU9xA== X-Received: by 2002:a4a:ec42:0:b0:6a3:4e5:5282 with SMTP id 006d021491bc7-6ae965b3107mr1310360eaf.1.1785899399868; Tue, 04 Aug 2026 20:09:59 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:39::]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-6ae93d524d3sm1576806eaf.6.2026.08.04.20.09.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:09:59 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 07/14] selftests: net: shaper: Add nested depth limit discovery test Date: Tue, 4 Aug 2026 20:09:29 -0700 Message-ID: <20260805030936.1092907-8-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add nested_depth_limit to incrementally create deeper nesting levels until the driver rejects. Reports the maximum supported nesting depth on both pass and fail. A device advertising nesting support must support at least depth 2, otherwise nesting is meaningless. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 5eccbe437ba3..3b72661202f9 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -532,6 +532,122 @@ def delegation(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def nested_depth_limit(cfg, nl_shaper) -> None: + r"""Nest nodes as deep as the device allows to find the max depth. + + netdev + | + N1 -- Q1 + | + N2 -- Q2 + | + N3 -- Q3 + : (deepen until the driver rejects) + """ + bw_max =3D 10000 + + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support node scope shapers with bw_max,= metric bps and nesting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + nq =3D _require_queues(cfg, 3) + + node_ids =3D [] + cleanups =3D [] + queue_id =3D 1 + max_depth =3D 0 + limit_err =3D None + + # Create initial node with a queue leaf + node_id =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves': [{'handle': {'scope': 'queue', 'id': queue_id}, + 'weight': 1}], + 'handle': {'scope': 'node'}, + 'metric': 'bps', + 'bw-max': bw_max})['handle']['id'] + node_ids.append(node_id) + cleanups.append(defer(_delete_shaper, cfg, nl_shaper, + {'scope': 'node', 'id': node_id})) + cleanups.append(defer(_delete_shaper, cfg, nl_shaper, + {'scope': 'queue', 'id': queue_id})) + max_depth =3D 1 + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': bw_max}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': queue_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': queue_id}, + 'weight': 1}) + queue_id +=3D 1 + + # Keep nesting deeper until the driver rejects or queues run out. + while queue_id < nq: + parent_id =3D node_ids[-1] + try: + node_id =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves': [{'handle': {'scope': 'queue', + 'id': queue_id}, + 'weight': 1}], + 'handle': {'scope': 'node'}, + 'parent': {'scope': 'node', + 'id': parent_id}, + 'metric': 'bps', + 'bw-max': bw_max})['handle']['id'] + except NlError as e: + # Only treat "cannot nest deeper" errors as the depth limit; + # drivers report it differently (EOPNOTSUPP/ENOSPC/E2BIG/EINVA= L). + # Anything else (ENOMEM, EIO, EPERM, driver bug) is a real fai= lure. + if e.error not in (errno.EOPNOTSUPP, errno.ENOSPC, + errno.E2BIG, errno.EINVAL): + raise + limit_err =3D e + break + + node_ids.append(node_id) + cleanups.append(defer(_delete_shaper, cfg, nl_shaper, + {'scope': 'node', 'id': node_id})) + cleanups.append(defer(_delete_shaper, cfg, nl_shaper, + {'scope': 'queue', 'id': queue_id})) + max_depth +=3D 1 + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}= }) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node_id}, + 'parent': {'scope': 'node', 'id': parent_id}, + 'metric': 'bps', + 'bw-max': bw_max}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', + 'id': queue_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': queue_id}, + 'weight': 1}) + queue_id +=3D 1 + + if limit_err: + print(f"# max nesting depth supported: {max_depth} (errno {limit_e= rr.error})") + else: + print(f"# max nesting depth tested: {max_depth}") + ksft_true(max_depth >=3D 2, + f"max nesting depth: {max_depth}") + + # Cleanup: exec the deferred deletes in reverse creation order, so each + # queue leaf and deeper node is removed before its parent node. + for cleanup in reversed(cleanups): + cleanup.exec() + ksft_eq(len(nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue)), 0) + def queue_update(cfg, nl_shaper) -> None: nq =3D _require_queues(cfg, 4) if not cfg.queues: @@ -648,6 +764,7 @@ def main() -> None: set_node_shaper, group_update_rate, delegation, + nested_depth_limit, dup_leaves, queue_update], args=3D(cfg, NetshaperFamily())) --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f169.google.com (mail-oi1-f169.google.com [209.85.167.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2F6F3CCA15 for ; Wed, 5 Aug 2026 03:10:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899405; cv=none; b=nPxtp/PBLhN6HN+jm0pWRkniQcga8WgNDecLZoZKxr35Rq5pHhF8rUpy+SPQO64fsvfzrLFJWTfvFyip4VmCYPNP8Bcj3ifujSJx23DawPQukjkNTmZnC06n+mVhkfReMTrYOOb5tlyEC1b2Jj5Vzc93sRM61ZBdAYbhRy8+qe8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899405; c=relaxed/simple; bh=tLELQpHtU/0IDXoPocx7/QH5OaArIrW/4on7sRVtSdE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I1SJ4YjNEsd5BhTlgU08TC9hp+3gSMSwoPnbld+q7n2y0ULgy1PpXQ/pGGefeG4hLXHe8xz851j92iDmWSDGHZgSKvIehSqFADrTtcZbJzhdXg1mVN183UuD4EEMpkPZmc5OuMR7hldizqDqyh8yyitKDu02Z6OY29xk9bVCZ3U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=oy5fcAKl; arc=none smtp.client-ip=209.85.167.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oy5fcAKl" Received: by mail-oi1-f169.google.com with SMTP id 5614622812f47-4864ebb6268so280883b6e.3 for ; Tue, 04 Aug 2026 20:10:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899403; x=1786504203; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Xek4/jAvqHeG34Edizig0yMhAwZJCf3f9l9B7GvH4hQ=; b=oy5fcAKlHORXfl9svRM6QwJpwBM5oS4h/U5zbR0Qc1HyCVo+KBrWaAG2S/Tbg1u5// Gm4Hi12HJGFHLoz/iEG7oPWFShgM1OSSCFpd5WYTFM19ZPqK/3KV5ItntahNgTUT7G4S aJair7SCYXolj9Z6fL9oNdXpTxNjBzayHxpsdKk2uV6Ssn0DF69nKL/uRLnyz9py7BjN ZmyWvanSAs1j1Y+XGeag5UbMkWAqkVOg5KffG19id8FtBtyUB4XDVxkpwhEhLw7sPFHT AV3ivCBXAOiTd+z5yLF9FERiMmiB9RkY+RZPAICVeY7hljjMfIFN4km6uVzEHE/myPYF mKpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899403; x=1786504203; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Xek4/jAvqHeG34Edizig0yMhAwZJCf3f9l9B7GvH4hQ=; b=eYF/Nnrp0W0plIzxAnmPQVmDODHlfn/tGo9zQx82xt++Q+//S1RKCAinQy6+UNy+B+ H236qsEmrF9U8a6xk5FYSCospVYRrHDNRYiJb6OLvzhnJZJIk2DucYO+olAVYYG5x4me YphsoWucPodgJ/Do5tu5mlbx6V3SOPf9M8DCv9P5rHvtB6MAmPzuEU/XkG5FzfBwC0S3 jUHAHruZtmOco6iITe6Bj9S/4y9xiscYnLqnfv8pC/m6FpFyUjOtyk+TgW+XeWXyZxSQ wPwi6R+jGu5TXTjz7Ha6GOi09oVcXbKXqGuSqL0M+bJdKgCj1Bk7fdMBfnO0KoZGBTuL kg8w== X-Forwarded-Encrypted: i=1; AHgh+RoaEu58GKKD14LRjSu9r7HpLBSmgnbXbgczHhh2KGQMBmgfxWpm0RXLY4h5wIXDJSOLU0edZ6Ac1m45JeE=@vger.kernel.org X-Gm-Message-State: AOJu0YzYTeq2Z+2E+RslnTcHgfS8q1Te/wbT22FzFWTyPfWG9x/RKAj5 fFhZvqkueVSD9k0cmgezpgHXvBNhPgvvTuBSqUTlT6BY0nufN5Sl6yBm X-Gm-Gg: AR+sD13EPYTYJz1EQAu+J5NHB2E9ozALYOIlAJwSH7C6Jc7apptOYCHammDaNfI+eAP 31uRJMV8/STRMxl1hRcDLoK0A1BQy12NCOvvONMsyjJNzsgj7okE8eyJV7efEKIpQRs1LReqAO0 K9sjQs77Vkaxw47ZeOpIUXBPBcg2rbdhgbru5Xn2xKKE1UX1ocqWA6QyTF7tlXno4tBjm/CQevL tMHnlDNo7gAvj1Bw8djd6lPyljU2mMNaXKY+xRUeMeMSEzI0xs5qEXalpQm3QljUPxoFqaSMGcw xODvrAy7g/YeTPy/0cmyxRLAC0q39vKEXDAmE8XXq+44kKxV8tze6PWXq48Sy3XoYuYohfpF/kN wz52VU89fCAi/LFqb/QEjw5gBHSG/vDSIx1hEC7VuZy0Wdsb+aoN343UeyQ9Ss9N+M3CoodVyTJ Ft6YJnjMgkiS+X6cW5Zc2DBMw13vBY3kboLWZr9CchnSeKCR4Cxl0Ar90jSZNqNMJGv0Wj X-Received: by 2002:a05:6808:50a7:b0:495:f79d:8bd5 with SMTP id 5614622812f47-4afae09f3d9mr1770859b6e.12.1785899402760; Tue, 04 Aug 2026 20:10:02 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:1f::]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4afae4fc68fsm980909b6e.8.2026.08.04.20.10.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:01 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 08/14] selftests: net: shaper: Add child node deletion reparent test Date: Tue, 4 Aug 2026 20:09:30 -0700 Message-ID: <20260805030936.1092907-9-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add delete_child_reparent to verify that deleting a child node reparents its queue leaves to the parent node. Creates a two-level hierarchy (N1 with Q1,Q2 and child N2 with Q3), deletes N2, and verifies Q3's parent becomes N1. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 3b72661202f9..1b88e183f1b9 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -648,6 +648,82 @@ def nested_depth_limit(cfg, nl_shaper) -> None: cleanup.exec() ksft_eq(len(nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue)), 0) =20 +def delete_child_reparent(cfg, nl_shaper) -> None: + r"""Deleting a child node reparents its queue leaf to the parent. + + netdev netdev + | | + N1 del N2 N1 + / | \ -----> / | \ + Q1 Q2 N2 Q1 Q2 Q3 + | + Q3 + """ + n1_bw_max =3D 10000 + n2_bw_max =3D 5000 + + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support node scope shapers with bw_max,= metric bps and nesting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + _require_queues(cfg, 4) + + # Create parent node N1 with Q1, Q2 + n1_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': n1_bw_max}) + n1_id =3D n1_handle['handle']['id'] + for i in range(1, 3): + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': i}) + + # Create child node N2 under N1 with Q3 + n2_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'parent': {'scope': 'node', 'id': n1_id}, + 'metric': 'bps', + 'bw-max': n2_bw_max}) + n2_id =3D n2_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 3}) + + # Delete child N2 - Q3 should reparent to N1 + nl_shaper.delete({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n2_id}}) + + with ksft_raises(NlError): + nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n2_id}}) + + shaper_n1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n1_id}}) + ksft_eq(shaper_n1, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n1_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': n1_bw_max}) + shaper_q3 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 3}}) + ksft_eq(shaper_q3, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n1_id}, + 'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}) + + # Cleanup + for i in range(1, 4): + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': i}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def queue_update(cfg, nl_shaper) -> None: nq =3D _require_queues(cfg, 4) if not cfg.queues: @@ -765,6 +841,7 @@ def main() -> None: group_update_rate, delegation, nested_depth_limit, + delete_child_reparent, dup_leaves, queue_update], args=3D(cfg, NetshaperFamily())) --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f169.google.com (mail-oi1-f169.google.com [209.85.167.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D50B3CE4B5 for ; Wed, 5 Aug 2026 03:10:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899408; cv=none; b=rtW84AlHhsJ1yZp/8qDvMiKuqpKGN6nh7ZdQ7bungkW1p5x4MZv0pvz1mNB+/KqGefxQL/9hd977FiGHgho+LfmesmjBHMwU5LaCHjnJkYFWLxp5NVsiJ6vtLMJ/oMVfvEa9awXi0ZX0kxjfBCgWWpt65dMV/WpMQsUnSafJ1/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899408; c=relaxed/simple; bh=Jq8G1a8IW2voSAiSYYJVtT2lfUBUkeHKC/7i6E9dQz0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K/9SMJYv5G+bZcfDzSai4HmfNyZRELsiidm3msEZexiuALgFz1hW/QR0XwyyZW+aKH9UgqXlf1C8CmluRjUz7wmBMTYIOffn22fNjQuVb4OzAU/Odpbgz7/RlUV4Bp/Z9IJo2aXDSmkA7ar7aTAg3+iu+gGkQeiijavBm54sSYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QraSKoix; arc=none smtp.client-ip=209.85.167.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QraSKoix" Received: by mail-oi1-f169.google.com with SMTP id 5614622812f47-495b250b01cso333260b6e.0 for ; Tue, 04 Aug 2026 20:10:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899405; x=1786504205; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+/4t3Qh7FD+LIP4Bq9IadDXflLYCCWPdGdCvaAGpR3A=; b=QraSKoix/3RHO0vI/Kv4Vt1lYmX9XkWKcvKDuAqUzERfNofgGgLiiHXi8TX9JNRPbb G8AXnPMRXzIG3EoftM0sfw9Xh9LLjGOrGMsM6mzT2c5oxn1ZKTREjbPFXps2SrqhqR+/ FqHfAUPAR9o9oFUpMkljYkskpdP5V+KHPtpwFdGNJPIGG6g5TgGmwGgZ6MALGOgeTDRX wNM1HDXGbnanuj6twnC/cZI2/w3k7CAcY6pFnmthGe5owOgg1G709+yDj4FIaPBP9+qQ TX67KR4AsTqgVvd2frH6MqnBzK3PQUjC8pQv5MLT9nX3G4rmRodqLUM5MQ9hU3JofFwj T46w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899405; x=1786504205; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+/4t3Qh7FD+LIP4Bq9IadDXflLYCCWPdGdCvaAGpR3A=; b=TU7Nm9s5qbU6c3cUFaIg6CrVC7PCKoAAa4IOmMmEHSZeOT5x4dM1ktZng3/npG2JUP hTlsMep08N4NwMnWqI2mkVsYM1q094fMbmsD23FT1biMbMPD61lvzjNHY4/GZDYOH+jd DK9UCcd6MtPoCWxrt8wyJUtggsf9m7nt4HmI1y/BhLffDUqtFpr/zRGvoZId9DsCaXvo eAHho6VkSSZznm84eqVDcKKsftsbOniGmifcyd/iZ6D5AgjFqNEIGYj0H4QYGykutL31 WqoNCIW20bxDDPsh3SupO6YZoHCfyh0wcpdL/bCDUo2v2o+QMxHrLcSm76gehOLP0AXN 3AqQ== X-Forwarded-Encrypted: i=1; AHgh+RoHfPumMM3xCmbWnXQYvZ49qCmvy+PG2iNTpmLbQctxBsfPCvyLmMpM2aLSDWsReLsbv+9OwqS8v9qh3wk=@vger.kernel.org X-Gm-Message-State: AOJu0YwCzUweIXNEkj2cg4Hu3Co0sNpMzDrMZAWB5n3+Brd+x+9hIaxQ VC1FAKIsbl+5h3gR1kQvNqXp+RwO/8tofUK+FVaLzsvtTRkbgW8CoeRA X-Gm-Gg: AR+sD10EB0/ua9qSSHETVWmOmBOhZ8G4UuMBc/MsYU5KcfqFcixvLg98ofsA83aXMwR YAzruwkn3SejD537ZmW9F7J9C0/NkFhZfopEwmtMGTDRyGGl5DiSi6JpZILKjEtBeewPDrtV9wr SwCE2K9QwJrl5YPqeVP+1b2wbb5myCCyHJPBvwxpy7ln7RUhyv2pOSKgVqaagRgbnxfF/dz6jb3 ioFI8eUctBBNI3GAe6RQL3C113g+C5Y1JpISJZ87aIKbur6ViRtXKdMBOZPqiDtNJhd42MOoiua j1vB/ZoDZwFW2k0VuzE9mvIHqNZ4LadpBPqeWAtnWv6kJeizfUJKJNiRlVOpta9ra+kINfw3KA8 Sh5iUthLYi7tiF4kuIV9PKj42gxTA6fT6F1Rk5H8Sg+jWv9E5+rDwq1L3boXk6S8xutQ2ezav+s IQ+fiVA+Zmz/gBeOaN2QEZpGb0F19AOK+ZWOGLj7KJTfWhKvtwCq6aSYob+A== X-Received: by 2002:a05:6808:1185:b0:4a4:934:b316 with SMTP id 5614622812f47-4afae2607a0mr1829050b6e.21.1785899405603; Tue, 04 Aug 2026 20:10:05 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:31::]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4afae75ce1bsm977189b6e.15.2026.08.04.20.10.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:04 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 09/14] selftests: net: shaper: Add queue migration between nodes test Date: Tue, 4 Aug 2026 20:09:31 -0700 Message-ID: <20260805030936.1092907-10-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add move_queue_between_nodes to verify that a queue can be moved from one node to another via re-grouping. Creates N1 with Q1,Q2 and N2 with Q3, then re-groups N2 with Q1,Q3 to steal Q1 from N1. Verifies Q1 moved to N2 and Q2 remains under N1. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 1b88e183f1b9..62c74a0c0563 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -724,6 +724,107 @@ def delete_child_reparent(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def move_queue_between_nodes(cfg, nl_shaper) -> None: + r"""Move a queue between nodes by re-grouping the destination node. + + netdev netdev + / \ .group N2 / \ + N1 N2 {Q1,Q3} N1 N2 + / \ | -------> | / \ + Q1 Q2 Q3 Q2 Q1 Q3 + """ + n1_bw_max =3D 10000 + n2_bw_max =3D 20000 + + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support node scope shapers with bw_max,= metric bps and nesting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + _require_queues(cfg, 4) + + # Create N1 with Q1, Q2 + n1_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}, + {'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': n1_bw_max}) + n1_id =3D n1_handle['handle']['id'] + for i in range(1, 3): + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': i}) + + # Create N2 with Q3 + n2_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': n2_bw_max}) + n2_id =3D n2_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 3}) + + # Move Q1 from N1 to N2 by re-grouping N2 with Q1, Q3 + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 2}, + {'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}], + 'handle': {'scope':'node', 'id': n2_id}, + 'metric': 'bps', + 'bw-max': n2_bw_max}) + + shaper_n1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n1_id}}) + ksft_eq(shaper_n1, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n1_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': n1_bw_max}) + shaper_n2 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n2_id}}) + ksft_eq(shaper_n2, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': n2_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': n2_bw_max}) + + # Verify Q1 moved to N2 + shaper_q1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 1}}) + ksft_eq(shaper_q1, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n2_id}, + 'handle': {'scope': 'queue', 'id': 1}, + 'weight': 2}) + + # Verify Q2 still under N1 + shaper_q2 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 2}}) + ksft_eq(shaper_q2, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n1_id}, + 'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}) + + # Verify Q3 remained under N2 + shaper_q3 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 3}}) + ksft_eq(shaper_q3, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n2_id}, + 'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}) + + # Cleanup + for i in range(1, 4): + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': i}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def queue_update(cfg, nl_shaper) -> None: nq =3D _require_queues(cfg, 4) if not cfg.queues: @@ -842,6 +943,7 @@ def main() -> None: delegation, nested_depth_limit, delete_child_reparent, + move_queue_between_nodes, dup_leaves, queue_update], args=3D(cfg, NetshaperFamily())) --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f175.google.com (mail-oi1-f175.google.com [209.85.167.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C08CF3CF209 for ; Wed, 5 Aug 2026 03:10:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899413; cv=none; b=XSXZ8CC2qdpxjfHSPmpv+XnUhvYbOm0CesIm9XSu3OvomunkZTGnthMelKDyIVTuEFNylokwlCdEEqUerKzN77qn4/O9GeviGZkpD1LATPW0y1r5aM0D+UfkXNqcPhdzyqIYNu90N8J5/8y3ntGAyss5KLJKp0ugL0fBmqGz3Wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899413; c=relaxed/simple; bh=1L2Nivd25hshl3NsGCDcCU3jpDluDLUxskmCeHoJaV8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b+Ko86nFWcWPwt2il+AVCBirDT2PALo12X8z35GodyMSQcpIIRpbfibF32VqMHHi3jtzt8B1vZmtkoBNi+I37uScJTntX4lZpNBGwDloUSyJK9ZZ8+aW+osu/r7MUv94Y8HkN6N9kvSmVL9csRzoUYbFAJUyNu2x5rzqPVzIu38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Xp8ckLya; arc=none smtp.client-ip=209.85.167.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xp8ckLya" Received: by mail-oi1-f175.google.com with SMTP id 5614622812f47-4a45b3f0becso342723b6e.1 for ; Tue, 04 Aug 2026 20:10:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899408; x=1786504208; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=PUH6SmhjRHh0unfECppocgsvf6286r8htqNG+/1YYkk=; b=Xp8ckLyaefWarBSci09jXWsg+4fTy8cEdd6+byndqDqa6J+8Z+3A/cJfnVSU5f/oeE S8c3KUf1QZPt+eWugbugEDeAyhbQcV3XvZ56bB/jR5MlD45xqByO/K2aOKqz3N6Pnlrf AUkmK/d7Akld4KAOkvzyhOaEcbXdNyfIkYDmG1njKPRZY7W0Bha56bLUeb0/S5ltn10n C8/sfgigwmQM/QOnW5yVp+MIuTA74hYO6JzEM4oTn0D8OgWjfpnijqlJozJQSKUqMcAa vULYdNlNPq5nYVCTzaDPINJHRZbXIWQJ55Ik6iUmKCFIq1bP/qzi4+7cV1GrmkG+WA0/ NQ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899408; x=1786504208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=PUH6SmhjRHh0unfECppocgsvf6286r8htqNG+/1YYkk=; b=rqK/MFDCeKX9TO9uqK4aYV4JMMTGIR7/D/c5ysePaL8JKz6zo8dXUDubDldHa+D1vT f3yG5BcuWwUNpX6wPAo9PIq4RHP669XPLGOH8uyZm2Agygo4nJ5Omc5PD8c7JRvDQNBR HxlxzpG0JBpZuqaPotkdWaXrQkwkBIfQCKVInM7z/B+KQtWer8koh4LvMfU3C3vyDfZE +jCyb6yXGPQVQRz3DJ3W5GCtJDNggX2MDQiIyn/RGSIDsN3eeMs5m3C1PaBMn8S9uX82 ZKDcwS/XCd9/USUDSYoRobdWyUPzzOaLrzvuufPmUd50zaxGpHBGBk+SlCo8Q28Xjshz 6+cA== X-Forwarded-Encrypted: i=1; AHgh+Rqg9nSSgBjOqyocdxNM/cHXsJ81rUlwUMh/ylJAK2Khvmv2JR3ivRdPe3EiQwgtJFNS2Pnh/SIcEDFLd4k=@vger.kernel.org X-Gm-Message-State: AOJu0YxaGYXDemMiKa124nEacuxxlmeOJgtMS2dCI8uetmnIXr78NerL mWmYQFw5hwDQ4N8x3g7fc0DoBW5VST3phc9NMXdDqu20kERLIjiXyhks X-Gm-Gg: AR+sD102kY5W00aoZbruceVYrurt9IWoOYUUi5UGzFjAwFDphURqOwECAzuGo26C8pr oBphZwse+iE9ZtNlGFNzz1dPGHYLpv2gXtVsLm2kq/THw4M7bDiIrIWMfBD+fkY6WJBc4d19dzO RmP4kGXs+xAxVLbxUTXDBiPT6SsoXdmoFGKF/HPAi5tGhVTCPpq0bKaPfw8U7qAE1DIb2LrVI77 K7BitBlypX6wtBPIopbz/NtX0l4q8bvuDnUu0qV4ma9cZ8sDyWI2NoE7texW3Sk7kJOn5LZ346I /guT4EOv/4nvnCQv9Et9q09DVOnCvKKxjv0EEdigsnY+mCj3FR4DE8oVVQG4BUPczJwoHY+iHXm WlR1RMfto1VfO4hTh5IkS0UkD6mKCQ7cEUTt5wjUuQ0Sl8yL93NGj2cusjgoIiBNE0SCs1ROpb1 39EsBJLD5HoRvycsyNFas82T0WGi855IvBi8Pp8JVHdBZEL7+GeFvCqSHcWoRqxcfRi8uX3Q== X-Received: by 2002:a05:6808:1797:b0:4a3:3108:866a with SMTP id 5614622812f47-4afae12fc4fmr2175455b6e.17.1785899408467; Tue, 04 Aug 2026 20:10:08 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:47::]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4afae1777d2sm1118570b6e.0.2026.08.04.20.10.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:07 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 10/14] selftests: net: shaper: Add reparenting rejection test Date: Tue, 4 Aug 2026 20:09:32 -0700 Message-ID: <20260805030936.1092907-11-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add reject_reparenting to verify that the group operation rejects attempts to change an existing node's parent. The test creates two node shapers under netdev and verifies that re-grouping the first node under the second fails with EOPNOTSUPP. It also verifies that updating the node with the same parent succeeds, and that updating the node without specifying a parent keeps the queue leaves under the original node while updating their weights. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 62c74a0c0563..e7af94264409 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 +# pylint: disable=3Dtoo-many-lines =20 import errno import glob @@ -825,6 +826,154 @@ def move_queue_between_nodes(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def reject_reparenting(cfg, nl_shaper) -> None: + r"""Reject reparenting an existing node; the hierarchy stays intact. + + netdev + / \ rejected: N3 -> netdev + N1 N2 rejected: N1 -> N2 + / \ | (both EOPNOTSUPP) + Q1 N3 Q2 + | + Q3 + """ + node1_bw_max =3D 10000 + node2_bw_max =3D 5000 + node3_bw_max =3D 20000 + + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support node scope shapers with bw_max,= metric bps and nesting") + _require_caps(cfg, nl_shaper, 'queue', ['support-nesting', 'support-we= ight'], + "device does not support nested queue scope shapers with= weight") + + _require_queues(cfg, 4) + + # Create Node1 under netdev with Q1. + node1_id =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': node1_bw_max})['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 1}) + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'node', 'id': node1_id= }) + + # Create Node2 under netdev with Q2. + node2_id =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 2}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': node2_bw_max})['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 2}) + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'node', 'id': node2_id= }) + + # Create Node3 nested under Node1 with Q3. + node3_id =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': node3_bw_max, + 'parent': {'scope': 'node', 'id': node1_id}})['handle']= ['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 3}) + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'node', 'id': node3_id= }) + + # Reparenting a nested node up to netdev must fail. + with ksft_raises(NlError) as cm: + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}], + 'handle': {'scope':'node', 'id': node3_id}, + 'parent': {'scope': 'netdev'}}) + if cm.exception: + ksft_eq(cm.exception.error, errno.EOPNOTSUPP) + + # Reparenting a node under another node must fail as well. + with ksft_raises(NlError) as cm: + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 1}], + 'handle': {'scope':'node', 'id': node1_id}, + 'parent': {'scope': 'node', 'id': node2_id}}) + if cm.exception: + ksft_eq(cm.exception.error, errno.EOPNOTSUPP) + + # Updating a node with the same parent must succeed. + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 5}], + 'handle': {'scope':'node', 'id': node1_id}, + 'parent': {'scope': 'netdev'}}) + + # Updating a node without specifying the parent must succeed. + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 2}, + 'weight': 7}], + 'handle': {'scope':'node', 'id': node2_id}}) + + # The rejected reparents must have left the hierarchy intact. + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node1_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node1_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': node1_bw_max}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node2_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node2_id}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': node2_bw_max}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node3_id}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': node3_id}, + 'parent': {'scope': 'node', 'id': node1_id}, + 'metric': 'bps', + 'bw-max': node3_bw_max}) + + # Verify the leaf weights were updated and parents unchanged. + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 1}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node1_id}, + 'handle': {'scope': 'queue', 'id': 1}, + 'weight': 5}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 2}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node2_id}, + 'handle': {'scope': 'queue', 'id': 2}, + 'weight': 7}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 3}}) + ksft_eq(shaper, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node3_id}, + 'handle': {'scope': 'queue', 'id': 3}, + 'weight': 1}) + + # Cleanup. Delete the nodes explicitly instead of relying on the + # empty-node auto-delete: a kernel that wrongly accepts a reparent may + # mishandle the leaf accounting and leave a node behind. Removing them + # by handle keeps a failing run from leaking state into later tests. + for i in range(1, 4): + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': i}) + for nid in (node1_id, node2_id, node3_id): + _delete_shaper(cfg, nl_shaper, {'scope': 'node', 'id': nid}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def queue_update(cfg, nl_shaper) -> None: nq =3D _require_queues(cfg, 4) if not cfg.queues: @@ -944,6 +1093,7 @@ def main() -> None: nested_depth_limit, delete_child_reparent, move_queue_between_nodes, + reject_reparenting, dup_leaves, queue_update], args=3D(cfg, NetshaperFamily())) --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oi1-f174.google.com (mail-oi1-f174.google.com [209.85.167.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA28B3CF020 for ; Wed, 5 Aug 2026 03:10:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899414; cv=none; b=CPT11ZIoKmUnRZOndSUOqY1Fg6c22xQusDm/zwuFzIiGrlinPR8E8jYtOSxNvohluiQZektjvFAuVtm6yUn8iWZiLoeCP1PPLCW64Uf3PvCnwZi3DX+u9ZlqC/vFRyo/WgQoqqU9jjkiGxYM2yvDeYkF92zE9E/XhdxXMYmcahc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899414; c=relaxed/simple; bh=oOK+6ucr5hFnvPa1Cyt6MMMW2Oz8T8PdrwBeO7VqXz0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oibDt3Xh9kVG4bknJZJ7PcdPdOqKmCaZsBVquecRfp7A3Z2EfJ3/hGcQ8XZur4daMIIDX8C1amtB0infrhngX7bug083ioFczTTp2bUnUorFNgjdjnuwmFTMMCIFttIaxmFHFLEsnY31i5vNnTlVMvDQhj3WmbM8u8M572LdcVw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ge5RN1e3; arc=none smtp.client-ip=209.85.167.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ge5RN1e3" Received: by mail-oi1-f174.google.com with SMTP id 5614622812f47-4955cd5da3dso236185b6e.2 for ; Tue, 04 Aug 2026 20:10:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899411; x=1786504211; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OyAL7vKiCo/6sYMJZ1fmy0xuR69l2pnMk9awj9AE7OI=; b=ge5RN1e3/0j9vNY5SSEMZE56WU74ok3jrFS9M6b1EqhnNt0UI8KdL0pK1j3wu6Wd7d wI+FjEJcnrIhfA+ytoVJv2YO9Fez0dM2OtVt9UBBv/1+5sPqds2CWkDSRKnP9QJ7sGL5 sFY+goJomrh+a2V1iGyTCu1F1BqeQuit0ViP/cyMV+WSj+/U/QTBoMCcptB/uXs9Pz5E c3m9MidPEKaYO4QzlU14BmxzF3KiNSWAyroTTxa+H9pwYWcVp2wWBDsgoa1PH+jB5wxI rBYzPN11A9UitunZhfklSYCxTnXNs/rrLNPIOdAKh19lADyqfP3Im+mIQb2Nr2/4R/dj d7jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899411; x=1786504211; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OyAL7vKiCo/6sYMJZ1fmy0xuR69l2pnMk9awj9AE7OI=; b=mZLS/R1ZN0NTpfSrovcuU7tWe0y6JW9VzUUMaxnwiLnqFe0e0Fb1JAnkI0XVUaM+Vm Rfh+rUoTDt97LifiYcw3YBdQ3XMQsCpS3N6ylKanJgN9b/wbvYhn1QPydEyY85/G1iuf KspvZ8tKgVHFtET6c1N+/vEJZtmda+KF9eFW8IM5OOgCZ9qmBO/g61KexhFtCAwLfgDb gDTktboPiABXPsGLcIEEG6O1na51yQF0DHU54hhuQhAK8o+VJOhm8myftuzzX1XY22TW TyPMhK7OPCP0fO/Km6vWYft09r2JAxWpJ7kDkJxX3yQ5k9xQAlF3YDTXIFgNGwfisBAe 3exw== X-Forwarded-Encrypted: i=1; AHgh+RoBiEfs+IaAv9Z48U38TssBdJbRmg1VRQ3oZ6RX/838S0Dxn3S0c+F3l7PZfMQZT5f1i50okaJTdiVhWzI=@vger.kernel.org X-Gm-Message-State: AOJu0YxTENBQdoJsJHQDUM0qzP0Tq6zfsPU+clGvo108l+HirBvk6Bta IpM0MJPQ1tWP2qta8rHySkXdZm/hHGzcTuY/SD8DzynU6htOhKVTcZHe X-Gm-Gg: AR+sD12cb796DabyHAjjyaZWnfagjV86OARoj9gESF2mGyfL4M241qllNMZK+kSmxgw w+bl65Gu11FMlb0NGgbmz2+r/Dsszi9UxGOfOp4u7H/l/1wBK2F5RoIvHsenTvCxx74yZe2xh97 F+OEikhOz3XJr/W3juiHkhBnxTonqwKKvnnU2w6PE/+7prOSpqse3Vs5zx+AfHcABW+PbLUnK+F +k9gMhWZhlTrifERYMktlMkjDcZal07VSt1MGiusFi3BbtYNTie4KVbmNlkO7+bdWK+bqNjwr40 ewv88ZItYCVesbesnEQ5U/oKjfSyjXRgFP4TkvFjm22XIuGGC8cUZB0FCDm1Nnb2PJEjlEoE2l+ PCE2JLEockx6TMqUIyMSlGnC6CrP8k8SLKQ2QxqVUAM7/Re1vwKQHREpOUvQ+eENBEQk9dMlA71 IEPT/7hVpD11SOeJliotKSv7BtrEZ9C8Sh2dRS7DZnzwKxucmNVuRog7Pgqw== X-Received: by 2002:a05:6871:df:b0:43c:44c9:b87e with SMTP id 586e51a60fabf-4599ebe0291mr1927971fac.3.1785899411436; Tue, 04 Aug 2026 20:10:11 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:34::]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4599e1bc01csm1331966fac.4.2026.08.04.20.10.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:10 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 11/14] selftests: net: shaper: Cover scalar attributes Date: Tue, 4 Aug 2026 20:09:33 -0700 Message-ID: <20260805030936.1092907-12-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Exercise queue-scope scalar shaper attributes reported by the device, including rate limits, burst, priority and weight. Build the set request from advertised capabilities so devices are tested for the attributes they claim rather than skipped for missing unrelated fields. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index e7af94264409..8dd4897e999e 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -168,6 +168,73 @@ def del_nshapers(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def set_all_supported_attrs(cfg, nl_shaper) -> None: + """ Set every queue-scope attribute the device advertises and verify t= he read-back. """ + _require_queues(cfg, 1) + + _require_caps(cfg, nl_shaper, 'queue', [], + "queue scope shapers not supported by the device") + caps =3D _cap_get(cfg, nl_shaper, 'queue') + + attrs =3D {'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}} + expected =3D {'ifindex': cfg.ifindex, + 'parent': {'scope': 'netdev'}, + 'handle': {'scope': 'queue', 'id': 0}} + + rate_attrs =3D {'support-bw-min': ('bw-min', 10000, 100), + 'support-bw-max': ('bw-max', 20000, 200), + 'support-burst': ('burst', 3000, 30)} + rate_attr_supported =3D any(cap in caps for cap in rate_attrs) + bps_supported =3D 'support-metric-bps' in caps + pps_supported =3D 'support-metric-pps' in caps + + def add_rate_attrs(metric, value_idx) -> None: + attrs['metric'] =3D metric + expected['metric'] =3D metric + for cap, (attr, bps_value, pps_value) in rate_attrs.items(): + if cap not in caps: + continue + + value =3D bps_value if value_idx =3D=3D 0 else pps_value + attrs[attr] =3D value + expected[attr] =3D value + + if rate_attr_supported: + if bps_supported: + add_rate_attrs('bps', 0) + elif pps_supported: + add_rate_attrs('pps', 1) + + if 'support-priority' in caps: + attrs['priority'] =3D 1 + expected['priority'] =3D 1 + if 'support-weight' in caps: + attrs['weight'] =3D 2 + expected['weight'] =3D 2 + + if len(attrs) =3D=3D 2: + raise KsftSkipEx("device does not advertise any supported queue sh= aper attributes") + + nl_shaper.set(attrs) + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper, expected) + + if rate_attr_supported and bps_supported and pps_supported: + add_rate_attrs('pps', 1) + nl_shaper.set(attrs) + + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper, expected) + + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def _group_under_netdev(cfg, nl_shaper, bw_max=3DNone): r"""Group queues under a netdev-scope node; caller owns node teardown. =20 @@ -1084,6 +1151,7 @@ def main() -> None: del_qshapers, set_nshapers, del_nshapers, + set_all_supported_attrs, basic_groups, basic_groups_with_rate, qgroups, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-ot1-f44.google.com (mail-ot1-f44.google.com [209.85.210.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7808B3CFF6B for ; Wed, 5 Aug 2026 03:10:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899417; cv=none; b=ExbilY3gi1VAW7jZFQLL+gr6QMsY3bMbXAWjQCkeEAUcLKmqVfZ6y0/mCFextBiWLcrCt7OTZkImKj7tb5cXTyPD8G18rquRgKC4AKN/wfUR0dECjwgaKI+ngaceg7atsuJFuIsBeDeRfuPTHn5b8LO8IkFXdvLHdM/eI/LaceM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899417; c=relaxed/simple; bh=BVyEg/yYgPSwLV5IwdhaQQaJYuhZyIaj0diGnbsjN/E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BXy7efxaIpYqBHZvASkjym2+0p2fMtCGYjHTN+av1A4joqNk+5ed1/A8u5ZOPFyY8mJbnrleDndzUeqqbEULTEu+hVHbbSqKX0cjICzaZ40UPR/b8yl63d8sZxBkSKSJiaEIsW2BvZ356xAtIRMPNJt2rmJQR6X+ZyZgcxeyrV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BG1uqBpM; arc=none smtp.client-ip=209.85.210.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BG1uqBpM" Received: by mail-ot1-f44.google.com with SMTP id 46e09a7af769-7ee37dc91f5so371846a34.3 for ; Tue, 04 Aug 2026 20:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899414; x=1786504214; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=wP2lXcYocA4uRBulyzxXopr9bWkNcIAmOaQO5fndKNg=; b=BG1uqBpMFB6GxFqavNvHDRjYkU3K3+ij/6BoE+9kjINbb50QG9WuV7g1aUNOHvaH0L y78xHcwW9d38lPATELKAYlua53nLENkdynGyGb+EG8siIYBLrpMEQ7ojXTuEC7tSXrb+ gKjlHsgQl5sBBSlT7a9AKSwItzzpqs0BaLxKoloYKT/LwmJfStyOSFh5UU5JY3HuaE3h 6JKiFHDEF/9Tfri0gytvZ5MM17FVcOevNcXyME0pG0UeHrvxeQLteNVAb5KAfN+bRuus FQPr7pl5fUZaouVIiEVqcohPWd3oQhH8zo43LB5GNJkAcuyGOc6BX0lQj9ozuDM2mUHD Rk4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899414; x=1786504214; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=wP2lXcYocA4uRBulyzxXopr9bWkNcIAmOaQO5fndKNg=; b=IgSAwnRyIRCc11C71ovUTJG5GSqCiCDHHEip/aNxc6hkmJZueAwzijm3uW0aHeUM2J qrwH0JE8MyyWjAIlFicKeRrOj6kyg5rJVyBuD3m6EKCRAJuJWtiyGgdtgEBoO+urHuxl oNJLOgzPjdmftVbMtpbpRkH+piUWs54D024fcHLXaJX5yy/xuW5qYrv5lPpCZKZoProi YHH7ZOpmLuOa4ljCEdL9U+LYEyTk6y4UQMsR3qLK3W6T7hgL4wW7406LE50oHGSZGWAP DCt0Ysw7Vam9GDO4hU9z48Dq1o8am27CeO+WgEXKOG7ZgEUl3OWFeCtYnIoS99hr8tHI WOOQ== X-Forwarded-Encrypted: i=1; AHgh+Rp0sQNzz3We1TZ0WDvmjo1881rgfshVQha/2qRTyGTYiOcSYa0RWocgfxiIketdeJBcqA442tnafkQuv+g=@vger.kernel.org X-Gm-Message-State: AOJu0YwtyoCPoUFyjyFLUkkhYp3lCSeq14dt/JQ2ZVzoig9bHs7eEjUX mcADh/MIJw8UmGrhRzplPnHu1ylf+pc/NVzFDY+NI+e4hX6M7IGLMl5p X-Gm-Gg: AR+sD10NwJnEBDmdf8tmQqj0BUwYLUd1swCr2s4BU16yhRAETCim/66Lwp0JF5KJ7Zz i+YGm9nJvrVT3WSc/MQ/F0dUS4tmCfva22j443qucmDwztYW81ztRamat6Vf+k2l6OxYOHJbm+G eSV1S3DdtN1cvjZcTqiA/4DrspjgBhX0NSd0IPO0RXXJ6IKDK0rFNg/0m8N32ZZPFsiHrEwOUip LqwGRQvlSTQYq9qV6Xu831j1lVImIDxrfL8RbZVHbInUyQqRb4NifRgLlOfKET/6wnzCkZ0Kald ZinVPqL+FbFPq5VXMxlHGcH4uHrzCnZbfEcGTXXBdx5NwiBuPF3VaM5CnxAlOUg2BVC00YaQ1Rb LqRGBPM3FQRDu4X3kAb/F0jkQ3FRKdbYMIazZB21FW6NL238vWmzOLrFB0sDe+daD5UdmmtXfQe Txqtz5NfzfrnRc9+6y9ARcj+2cuwdgtQzyVloTiiV56G2qcQMlQkvlZ7mxHol4WBl2+wE9 X-Received: by 2002:a05:6820:2083:b0:6aa:da04:b56f with SMTP id 006d021491bc7-6ae96c10163mr2164961eaf.3.1785899414376; Tue, 04 Aug 2026 20:10:14 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:44::]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-6ae94013615sm1584904eaf.10.2026.08.04.20.10.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:13 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 12/14] selftests: net: shaper: Reject invalid set requests Date: Tue, 4 Aug 2026 20:09:34 -0700 Message-ID: <20260805030936.1092907-13-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Verify that invalid set requests fail without corrupting existing queue shaper state. The test covers invalid node creation through set and invalid queue identifiers, then confirms the original queue configuration remains unchanged. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 8dd4897e999e..02a11e6b9a05 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -235,6 +235,46 @@ def set_all_supported_attrs(cfg, nl_shaper) -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def invalid_set_preserves_state(cfg, nl_shaper) -> None: + """ Verify a rejected .set leaves the existing shaper configuration un= changed. """ + nq =3D _require_queues(cfg, 1) + _require_caps(cfg, nl_shaper, 'queue', + ['support-bw-max', 'support-metric-bps'], + "device does not support queue scope bw_max with bps met= ric") + + initial =3D {'ifindex': cfg.ifindex, + 'parent': {'scope': 'netdev'}, + 'handle': {'scope': 'queue', 'id': 0}, + 'metric': 'bps', + 'bw-max': 10000} + nl_shaper.set({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}, + 'metric': 'bps', + 'bw-max': 10000}) + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + + with ksft_raises(NlError): + nl_shaper.set({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': 0}, + 'metric': 'bps', + 'bw-max': 20000}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper, initial) + + with ksft_raises(NlError): + nl_shaper.set({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': nq}, + 'metric': 'bps', + 'bw-max': 20000}) + shaper =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper, initial) + + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def _group_under_netdev(cfg, nl_shaper, bw_max=3DNone): r"""Group queues under a netdev-scope node; caller owns node teardown. =20 @@ -1152,6 +1192,7 @@ def main() -> None: set_nshapers, del_nshapers, set_all_supported_attrs, + invalid_set_preserves_state, basic_groups, basic_groups_with_rate, qgroups, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oa1-f54.google.com (mail-oa1-f54.google.com [209.85.160.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3CCF3D1709 for ; Wed, 5 Aug 2026 03:10:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899419; cv=none; b=ftDIw5eM7A4dR18NvGlLQ605VTlOfnemxwTard2zrZKfDFCyU0esdgK9WzV8m+cUer+r+uM7BI/22YKlwIyai6w1cKnZ5cqlKqKG79CUrHJpY7gLx3BTO3dhLiQJASzkcMpDL6Mn9RCNc7Jr+ES82IjKI7IjTFBwqhw8oGKe39Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899419; c=relaxed/simple; bh=J7+TAxwHTK1cC9KFhwWX1h7vQchRo36B00uXMT5HteU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j893/uO9UhphF6oWZoMSIG0KksboVRdaYVccXFhUzfA/XCVpWTR7hx+DJnpoVBriGnM1L+WFRmWl5dn3K+QH204GdqFWfd5XutEbPn0jU6mRP7tymhkAGLH+FX4/+Y0SJH5zO+D6tpMafomGU9HbrRFcCWZMaXIOX36dPUKwkCo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OTIvVOtN; arc=none smtp.client-ip=209.85.160.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OTIvVOtN" Received: by mail-oa1-f54.google.com with SMTP id 586e51a60fabf-448cf99c133so2046005fac.1 for ; Tue, 04 Aug 2026 20:10:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899417; x=1786504217; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=4+lZJMF1bstP0Y7Cx/H1yn52yK2NNJ1xKbJgdUuBFDc=; b=OTIvVOtNYFeD/AniBIi3c6qIrwkmzRbDIktZNCP+K5EeLbuSoy7Pg5XGE3k53nZg29 RRWSb+b4sBqNR/onPc6z90bDQdWA3Xn7OfPiduLavQ3Izm20B1vIBKwuOQ0V+Jley38y efFEn8QJpxCXMN+gnsDDRKE/vaRSciFfNc1dh9t/84BQCK68dMSA7DkYWMgmk1TsCbwx nbtZoFkTAO6PpKmWkwcimIg0eBcGpJ4r/8vEaQjIeKxCTVYCHdqvfqCOf0mqPXXdQtYF 4QYf33wIcpH+IJNfkAoHA3UDasGrth3R1rZYXROd5SJjUvH2719LKyx/WbBB72g5aS9r LQyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899417; x=1786504217; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=4+lZJMF1bstP0Y7Cx/H1yn52yK2NNJ1xKbJgdUuBFDc=; b=abQ4L0DXISzfvS47MHTbjvxYOL7tNYKjhsdOFb6hKbIsqW91LzsIDGPZ8N5WZc9SUp wlfpu0+M4WnX7or+8qXKDDz1CYpsl4t0kjO6cwUZwbtyb9A3tQjbLtRHHSHzctFj6w5n c5H7HM5z0kvJ24r1ookMw9LcI2p7YpA3ZUi/fefN9Z2g96IU7NuDYYmR4hByN5gbjqtf 3ZM/YRLE5YT5bb7XA9ShoVFHZfpNUB81jrawrgHoQrgdhEO93YW34gWJrTMdABzYTbz6 OQmGSWC/3tPj7k4a/L97R0//45UdKnnkGSIOx1rQTuZ452CWCCOb8YQASvI1NjZG0fCy Pk8A== X-Forwarded-Encrypted: i=1; AHgh+Rq39AFoeXYyM/JkDKTqXBfPN3S8JNETl6l6FguGBenjNQuy8i8OY3xYorUJzs1BTjooAgU/yFyMtPRt0rM=@vger.kernel.org X-Gm-Message-State: AOJu0YxdS3sZbD4YtDmhcjMHFy3WkIR/c8ghhqyYJYACiADha7evgb/x HdCze/lJ0Yw00Kj5FcospJQxT0sobq6GTL1Zqx3YOW4rFDEW27qrcCOb X-Gm-Gg: AR+sD11JMsbt+AySs8XXq+GI3+432WOObn1MlFE+zC/2zbJa5f2Y50j1xcK8xhn54xV +MfXamXxOMCEXzwxp++sfkcmq9aTdguetDLKw6KFps0alM2xDg0Vn2UK/UlGEkivMqzPWxIzzze 6EHJ/nLzfQpuHYoxx+qlb0ZA1kJ9hGud6gie3ZGNPI7CRILveGqsnCuJWwjqDwsWXs3QrdfygRM 53RyaCje6K6cdqm6HhB093kFFZzb5hRdcvAaeivikY7q5BhHS3/urIar1HXjXqp8Xl0ySuBKOnY YzBGxgAjlHRcZxazugpZixnygMQ24FMe69gX9fwAX9zAmVpAIbE/zH6KR7s3JarUphKvxDsBj0Z KHCmEP36MXtd/K0W8QTf0s5E62tZdVT5BnQxkixUh3WPWFW5rNSTI7wwNLaNiGQcVaKJqUVo++H V025h7F8YF1txskicMGOu+c879llr6XOpMR6Jpernc9LdArlUzJzTUvQ== X-Received: by 2002:a05:6871:3a0d:b0:456:7f6e:38b8 with SMTP id 586e51a60fabf-45978d97323mr7502837fac.12.1785899416669; Tue, 04 Aug 2026 20:10:16 -0700 (PDT) Received: from localhost ([2a03:2880:31ff::]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4599e24dfa6sm1354093fac.6.2026.08.04.20.10.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:16 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 13/14] selftests: net: shaper: Cover mixed-parent grouping Date: Tue, 4 Aug 2026 20:09:35 -0700 Message-ID: <20260805030936.1092907-14-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Add coverage for grouping leaves that currently belong to different parent nodes. The test verifies that an implicit parent is rejected, an explicit parent succeeds, and the old empty parent nodes are cleaned up. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 02a11e6b9a05..9264aeb74a7a 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -275,6 +275,105 @@ def invalid_set_preserves_state(cfg, nl_shaper) -> No= ne: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def mixed_parent_group_requires_parent(cfg, nl_shaper) -> None: + r"""Grouping leaves from different nodes requires an explicit parent. + + netdev netdev + / \ parent=3Dnetdev + N1 N2 group N + | | {Q0,Q1} / \ + Q0 Q1 -------> Q0 Q1 + + Without an explicit parent the group is rejected; parent=3Dnetdev + collapses the leaves into one new node. + """ + _require_queues(cfg, 2) + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps'], + "device does not support node scope shapers with bw_max = and metric bps") + _require_caps(cfg, nl_shaper, 'queue', + ['support-nesting', 'support-weight'], + "device does not support nested queue scope shapers with= weight") + + n1_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 10000}) + n1_id =3D n1_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + + n2_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 1}, + 'weight': 2}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 20000}) + n2_id =3D n2_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 1}) + + with ksft_raises(NlError): + nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 3}, + {'handle': {'scope': 'queue', 'id': 1}, + 'weight': 4}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 30000}) + + shaper_q0 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper_q0, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n1_id}, + 'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}) + shaper_q1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 1}}) + ksft_eq(shaper_q1, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n2_id}, + 'handle': {'scope': 'queue', 'id': 1}, + 'weight': 2}) + + node_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 3}, + {'handle': {'scope': 'queue', 'id': 1}, + 'weight': 4}], + 'handle': {'scope':'node'}, + 'parent': {'scope': 'netdev'}, + 'metric': 'bps', + 'bw-max': 30000}) + node_id =3D node_handle['handle']['id'] + + for old_id in (n1_id, n2_id): + with ksft_raises(NlError): + nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'node', 'id': old_id}}) + + shaper_q0 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper_q0, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': 0}, + 'weight': 3}) + shaper_q1 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 1}}) + ksft_eq(shaper_q1, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': node_id}, + 'handle': {'scope': 'queue', 'id': 1}, + 'weight': 4}) + + for i in range(2): + _delete_shaper(cfg, nl_shaper, {'scope': 'queue', 'id': i}) + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def _group_under_netdev(cfg, nl_shaper, bw_max=3DNone): r"""Group queues under a netdev-scope node; caller owns node teardown. =20 @@ -1193,6 +1292,7 @@ def main() -> None: del_nshapers, set_all_supported_attrs, invalid_set_preserves_state, + mixed_parent_group_requires_parent, basic_groups, basic_groups_with_rate, qgroups, --=20 2.53.0-Meta From nobody Fri Oct 2 05:28:19 2026 Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A69793C98A2 for ; Wed, 5 Aug 2026 03:10:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899422; cv=none; b=VR0EGwLR6xdU4xyMQTyKgTJXLShXi2HiMI2J37Zgps0ym0gWmb0aaxlX9krlHxI6dTIS+aLX8gvz1uxbr5wE6avuoNSvB0/qvj0MWa42QPjMU0uW8JzfSIhTRClY2Y7P2HruPQW2BM39wFpg9abVmWN3wFNb7RAgr8rUESdtJDA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785899422; c=relaxed/simple; bh=Ew9kqnx7gNLh63gLTyVSPNRcNPey74+hcBLknh/TAH0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VIAa0JsHyoyb0c4rd/xk9IFLdSfR7m62DTY9Xje2Lrtg77auBLKfoXNab8ZtjSDhXnakj2kDMV3CwXjEihn8N0w66uXoT58E7vVYKmbYGG+v86ju3hFBGn2164wLyq37fom6KbZqWKU0lxgmKqpeB3c0xRpGern/7/mD3hIAr04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fffVNSwF; arc=none smtp.client-ip=209.85.161.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fffVNSwF" Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-6acabd2c8bdso368497eaf.2 for ; Tue, 04 Aug 2026 20:10:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785899419; x=1786504219; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lcsQyfByd70EchMKWRKdanf3VR0eB6+yq95Jw1CGYPw=; b=fffVNSwF35pnScmiJy0Gp4fzCbMgu5G1uZpHPxqqfBMgi6BoUoCLdsXE6xAPkCf2XG EP/RIs1SOuKK/HoGfZkTK03EAtzHBcIncvj3uamJoLrAGOKJF9Sq2qrCJz98CpZw9uj2 0p5Xaw1yjrdKMG68bG7IYHKySFHtPIZlO5oNpsFT15xMXA6Ces2p1e90+Dx78CLjua9m KfiQijfAR+6jzxTbxYaZFBsM94xVyQs80yWStyg+32wpjzWYhN4tZEngokyoBFnTraRX x3mUQkIa20ex0jSqsrc8ZXZ4zgkBP16dAxqybfRjuRZVMIPynxxePap1O+Ze3vLg5nLw bCBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785899419; x=1786504219; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=lcsQyfByd70EchMKWRKdanf3VR0eB6+yq95Jw1CGYPw=; b=LBnBdrVxoQ0L78pw2L4sgu1U2jAQGWmXhxWA2IMolGZj8oqQ7+K0oxFTodQCBo0d96 U9MxqSYyX7fPq0sjVoehiR5IiW4j3slLcoWKKlFb6H58WfyQpxJ/JrjJyufyREnMl9cZ nWBZxHQm3RkH0HW1LXMhfOv8rHQHV/XUOoGZNxhmr1iGQk1pSdjPb4fR1bQh3TbOMejD hYOlSFBRRR/kDpA20A4I9bqnyaONc+WK2qNRAxqhMMQWMCLa7N2thA8ym0tJFxrRnbzu g0Ke+oSWK2/OavrCimWs5Y/vpK424nZHWCqRoeJPPgeAv/DfjA0w1r91e70IXEuD/CVl jnrg== X-Forwarded-Encrypted: i=1; AHgh+RpOUFtINzER8b/7uNRZBIb6wpei6alUctw/uYuUCtQksuDAC6q/jJUpxohj9xnWI95kSenezCdEzvHW/q4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/VopeHO7b0YjwegxdnIt3JYTyB1jehApZhKmFwH4DOv/5NomO 9C8VZLTCo33Cqd82Wp71IGHQoDFmMoeI7xnqbjE/y6mgRSxdH+ipZDAg X-Gm-Gg: AR+sD115cmQBS2sj2MR2qXE3HOQTkxWUNlxeE5FD6RyzEC0E7+oP6wcgTlsOQpSHkNT w0GvSi9kvAz/SIM40sguxZRXgRhJQSWui9mxmzj317QXDuRXXoD7b2Jd3OyfPUta9b1e/abVXF+ FCRTL1zYEfrn8bCK6OXUSKGGna75YE/8JEVqow+VRU5fqE7kIB0x4mwzuyjYk+P/c5+ZJwWSmri mG5x0hPSa4YDReFjPNMja3gRHzApoaP/oETU6qTT6Adxig/3wAsXpuIECZshCfuyb8Fl43NiZq9 WCnRq1+8f1xdjwu2o95dswE7v06g+rmFHVkbiO68bVlRQ4KGN7MWzmYbPq5kL1p2gScJG9xHMtV TRWZ1ova9VLLJPTCRhhd+Z47e2YtZCv/ul0QXK8HWdORsQfR/wPWSyqjRjfcOb08+sudZ640Fc5 +wl17b9KZO/Qh3CLRzJUOx+Nft3ub/0cWFNIGTFLZPNNojKtvm9RMJ8reNWkg= X-Received: by 2002:a05:6820:1990:b0:69d:e4c8:86f6 with SMTP id 006d021491bc7-6ae96e3b5afmr1985507eaf.15.1785899419557; Tue, 04 Aug 2026 20:10:19 -0700 (PDT) Received: from localhost ([2a03:2880:31ff:3a::]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-6ae93cbf7a9sm1632805eaf.2.2026.08.04.20.10.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 20:10:18 -0700 (PDT) From: Mohsin Bashir To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, pabeni@redhat.com, shuah@kernel.org, alexander.duyck@gmail.com Subject: [PATCH net-next 14/14] selftests: net: shaper: Cover recursive node cleanup Date: Tue, 4 Aug 2026 20:09:36 -0700 Message-ID: <20260805030936.1092907-15-mohsin.bashr@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260805030936.1092907-1-mohsin.bashr@gmail.com> References: <20260805030936.1092907-1-mohsin.bashr@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mohsin Bashir Exercise cleanup of nested nodes after deleting their last queue leaf. The test builds a two-level node hierarchy and checks that removing the queue also removes both now-empty node shapers. Signed-off-by: Jakub Kicinski Signed-off-by: Mohsin Bashir --- tools/testing/selftests/drivers/net/shaper.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tools/testing/selftests/drivers/net/shaper.py b/tools/testing/= selftests/drivers/net/shaper.py index 9264aeb74a7a..a53316726f69 100755 --- a/tools/testing/selftests/drivers/net/shaper.py +++ b/tools/testing/selftests/drivers/net/shaper.py @@ -374,6 +374,64 @@ def mixed_parent_group_requires_parent(cfg, nl_shaper)= -> None: shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) ksft_eq(len(shapers), 0) =20 +def recursive_empty_node_cleanup(cfg, nl_shaper) -> None: + r"""Deleting the last leaf recursively removes the emptied ancestors. + + netdev netdev + | del Q0 + N1 ------> (N1 and N2 removed too) + | + N2 + | + Q0 + """ + _require_queues(cfg, 1) + _require_caps(cfg, nl_shaper, 'node', + ['support-bw-max', 'support-metric-bps', 'support-nestin= g'], + "device does not support nested node scope shapers") + _require_caps(cfg, nl_shaper, 'queue', + ['support-nesting', 'support-weight'], + "device does not support nested queue scope shapers with= weight") + + n1_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'metric': 'bps', + 'bw-max': 10000}) + n1_id =3D n1_handle['handle']['id'] + defer(_delete_shaper, cfg, nl_shaper, {'scope': 'queue', 'id': 0}) + + n2_handle =3D nl_shaper.group({ + 'ifindex': cfg.ifindex, + 'leaves':[{'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}], + 'handle': {'scope':'node'}, + 'parent': {'scope': 'node', 'id': n1_id}, + 'metric': 'bps', + 'bw-max': 5000}) + n2_id =3D n2_handle['handle']['id'] + + shaper_q0 =3D nl_shaper.get({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + ksft_eq(shaper_q0, {'ifindex': cfg.ifindex, + 'parent': {'scope': 'node', 'id': n2_id}, + 'handle': {'scope': 'queue', 'id': 0}, + 'weight': 1}) + + nl_shaper.delete({'ifindex': cfg.ifindex, + 'handle': {'scope': 'queue', 'id': 0}}) + + for handle in ({'scope': 'queue', 'id': 0}, + {'scope': 'node', 'id': n2_id}, + {'scope': 'node', 'id': n1_id}): + with ksft_raises(NlError): + nl_shaper.get({'ifindex': cfg.ifindex, 'handle': handle}) + + shapers =3D nl_shaper.get({'ifindex': cfg.ifindex}, dump=3DTrue) + ksft_eq(len(shapers), 0) + def _group_under_netdev(cfg, nl_shaper, bw_max=3DNone): r"""Group queues under a netdev-scope node; caller owns node teardown. =20 @@ -1293,6 +1351,7 @@ def main() -> None: set_all_supported_attrs, invalid_set_preserves_state, mixed_parent_group_requires_parent, + recursive_empty_node_cleanup, basic_groups, basic_groups_with_rate, qgroups, --=20 2.53.0-Meta