public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] netdevsim: support ETS offload
@ 2026-03-10 18:06 Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 1/4] netdevsim: move TC offload code to a dedicated file Davide Caratti
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Davide Caratti @ 2026-03-10 18:06 UTC (permalink / raw)
  To: Jakub Kicinski, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jamal Hadi Salim, Jiri Pirko
  Cc: netdev

 - patch 1 and 2 generalize taprio offload code so that we can re-use it
   to offload most of the existing qdiscs on netdevsim
 - patch 3 enables ETS offload on netdevsim
 - patch 4 is a tdc test for ets offload on netdevsim

Davide Caratti (4):
  netdevsim: move TC offload code to a dedicated file
  netdevsim: generalize taprio offload
  netdevsim: support ETS qdisc offload
  tc-testing: add a test case for ETS offload

 drivers/net/netdevsim/Makefile                |  2 +-
 drivers/net/netdevsim/netdev.c                | 51 --------------
 drivers/net/netdevsim/netdevsim.h             |  3 +
 drivers/net/netdevsim/tc.c                    | 70 +++++++++++++++++++
 .../tc-testing/tc-tests/qdiscs/ets.json       | 23 ++++++
 5 files changed, 97 insertions(+), 52 deletions(-)
 create mode 100644 drivers/net/netdevsim/tc.c

-- 
2.52.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net-next 1/4] netdevsim: move TC offload code to a dedicated file
  2026-03-10 18:06 [PATCH net-next 0/4] netdevsim: support ETS offload Davide Caratti
@ 2026-03-10 18:06 ` Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 2/4] netdevsim: generalize taprio offload Davide Caratti
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Davide Caratti @ 2026-03-10 18:06 UTC (permalink / raw)
  To: Jakub Kicinski, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jamal Hadi Salim, Jiri Pirko
  Cc: netdev

This commit has no functional change.

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
---
 drivers/net/netdevsim/Makefile    |  2 +-
 drivers/net/netdevsim/netdev.c    | 51 ---------------------------
 drivers/net/netdevsim/netdevsim.h |  3 ++
 drivers/net/netdevsim/tc.c        | 57 +++++++++++++++++++++++++++++++
 4 files changed, 61 insertions(+), 52 deletions(-)
 create mode 100644 drivers/net/netdevsim/tc.c

diff --git a/drivers/net/netdevsim/Makefile b/drivers/net/netdevsim/Makefile
index 14a553e000ec..87718204fb4d 100644
--- a/drivers/net/netdevsim/Makefile
+++ b/drivers/net/netdevsim/Makefile
@@ -3,7 +3,7 @@
 obj-$(CONFIG_NETDEVSIM) += netdevsim.o
 
 netdevsim-objs := \
-	netdev.o dev.o ethtool.o fib.o bus.o health.o hwstats.o udp_tunnels.o
+	netdev.o dev.o ethtool.o fib.o bus.o health.o hwstats.o udp_tunnels.o tc.o
 
 ifeq ($(CONFIG_BPF_SYSCALL),y)
 netdevsim-objs += \
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 5ec028a00c62..1dc2f8c0695d 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -199,12 +199,6 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu)
 	return 0;
 }
 
-static int
-nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
-{
-	return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
-}
-
 static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
 {
 	struct netdevsim *ns = netdev_priv(dev);
@@ -335,51 +329,6 @@ static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
 	return 0;
 }
 
-static void nsim_taprio_stats(struct tc_taprio_qopt_stats *stats)
-{
-	stats->window_drops = 0;
-	stats->tx_overruns = 0;
-}
-
-static int nsim_setup_tc_taprio(struct net_device *dev,
-				struct tc_taprio_qopt_offload *offload)
-{
-	int err = 0;
-
-	switch (offload->cmd) {
-	case TAPRIO_CMD_REPLACE:
-	case TAPRIO_CMD_DESTROY:
-		break;
-	case TAPRIO_CMD_STATS:
-		nsim_taprio_stats(&offload->stats);
-		break;
-	default:
-		err = -EOPNOTSUPP;
-	}
-
-	return err;
-}
-
-static LIST_HEAD(nsim_block_cb_list);
-
-static int
-nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
-{
-	struct netdevsim *ns = netdev_priv(dev);
-
-	switch (type) {
-	case TC_SETUP_QDISC_TAPRIO:
-		return nsim_setup_tc_taprio(dev, type_data);
-	case TC_SETUP_BLOCK:
-		return flow_block_cb_setup_simple(type_data,
-						  &nsim_block_cb_list,
-						  nsim_setup_tc_block_cb,
-						  ns, ns, true);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
 static int
 nsim_set_features(struct net_device *dev, netdev_features_t features)
 {
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index f767fc8a7505..fdd35ab29d98 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -470,3 +470,6 @@ struct nsim_bus_dev {
 
 int nsim_bus_init(void);
 void nsim_bus_exit(void);
+
+int nsim_setup_tc(struct net_device *dev, enum tc_setup_type type,
+		  void *type_data);
diff --git a/drivers/net/netdevsim/tc.c b/drivers/net/netdevsim/tc.c
new file mode 100644
index 000000000000..8a1960f5f99e
--- /dev/null
+++ b/drivers/net/netdevsim/tc.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/netdevice.h>
+#include <net/pkt_sched.h>
+
+#include "netdevsim.h"
+
+static int
+nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+{
+	return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
+}
+
+static void nsim_taprio_stats(struct tc_taprio_qopt_stats *stats)
+{
+	stats->window_drops = 0;
+	stats->tx_overruns = 0;
+}
+
+static int nsim_setup_tc_taprio(struct net_device *dev,
+				struct tc_taprio_qopt_offload *offload)
+{
+	int err = 0;
+
+	switch (offload->cmd) {
+	case TAPRIO_CMD_REPLACE:
+	case TAPRIO_CMD_DESTROY:
+		break;
+	case TAPRIO_CMD_STATS:
+		nsim_taprio_stats(&offload->stats);
+		break;
+	default:
+		err = -EOPNOTSUPP;
+	}
+
+	return err;
+}
+
+static LIST_HEAD(nsim_block_cb_list);
+
+int
+nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
+{
+	struct netdevsim *ns = netdev_priv(dev);
+
+	switch (type) {
+	case TC_SETUP_QDISC_TAPRIO:
+		return nsim_setup_tc_taprio(dev, type_data);
+	case TC_SETUP_BLOCK:
+		return flow_block_cb_setup_simple(type_data,
+						  &nsim_block_cb_list,
+						  nsim_setup_tc_block_cb,
+						  ns, ns, true);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next 2/4] netdevsim: generalize taprio offload
  2026-03-10 18:06 [PATCH net-next 0/4] netdevsim: support ETS offload Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 1/4] netdevsim: move TC offload code to a dedicated file Davide Caratti
@ 2026-03-10 18:06 ` Davide Caratti
  2026-03-10 23:38   ` Jakub Kicinski
  2026-03-10 18:06 ` [PATCH net-next 3/4] netdevsim: support ETS qdisc offload Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 4/4] tc-testing: add a test case for ETS offload Davide Caratti
  3 siblings, 1 reply; 6+ messages in thread
From: Davide Caratti @ 2026-03-10 18:06 UTC (permalink / raw)
  To: Jakub Kicinski, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jamal Hadi Salim, Jiri Pirko
  Cc: netdev

Currently, netdevsim supports TC offloads only for filter blocks and the
'taprio' qdisc. This improves coverage for situations where

  .ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, ...)

returns 0, but the code can be generalized for offloading most of the
Linux qdiscs we have at the moment. Generalize netdevsim qdisc offload,
by providing:
 - a function that returns 0 on 'setup'/'destroy'/'get_stats' commands
   read from qdisc-specific offload parameters, and returns -EOPNOTSUPP
   otherwise, namely "handle_<qdisc_name>()"
 - a case label handling TC_SETUP_QDISC_<qdisc_name> in nsim_setup_tc().

This commit has no functional change.

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
---
 drivers/net/netdevsim/tc.c | 57 ++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/drivers/net/netdevsim/tc.c b/drivers/net/netdevsim/tc.c
index 8a1960f5f99e..358fa5bb835f 100644
--- a/drivers/net/netdevsim/tc.c
+++ b/drivers/net/netdevsim/tc.c
@@ -11,32 +11,31 @@ nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
 	return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
 }
 
-static void nsim_taprio_stats(struct tc_taprio_qopt_stats *stats)
-{
-	stats->window_drops = 0;
-	stats->tx_overruns = 0;
-}
+static LIST_HEAD(nsim_block_cb_list);
 
-static int nsim_setup_tc_taprio(struct net_device *dev,
-				struct tc_taprio_qopt_offload *offload)
-{
-	int err = 0;
-
-	switch (offload->cmd) {
-	case TAPRIO_CMD_REPLACE:
-	case TAPRIO_CMD_DESTROY:
-		break;
-	case TAPRIO_CMD_STATS:
-		nsim_taprio_stats(&offload->stats);
-		break;
-	default:
-		err = -EOPNOTSUPP;
-	}
+#define QDISC_OFFLOAD_HANDLERS(X)					\
+	X(taprio, tc_taprio_qopt_offload, cmd, TAPRIO_CMD_REPLACE,	\
+	  TAPRIO_CMD_DESTROY, TAPRIO_CMD_STATS, stats)			\
 
-	return err;
+#define QH(NAME, OL_TYPE, CMD_FLD, O_REPLACE, O_DESTROY, O_STATS, STATS_FLD) \
+static int handle_##NAME(struct net_device *dev, struct OL_TYPE *offload) \
+{									\
+	switch (offload->CMD_FLD) {					\
+	case O_REPLACE:							\
+	case O_DESTROY:							\
+		/* Do nothing, accept offload */			\
+		return 0;						\
+	case O_STATS:							\
+		/* Zero out the requested stats block */		\
+		memset(&offload->STATS_FLD, 0, sizeof(offload->STATS_FLD)); \
+		return 0;						\
+	default:							\
+		return -EOPNOTSUPP;					\
+	}								\
 }
 
-static LIST_HEAD(nsim_block_cb_list);
+QDISC_OFFLOAD_HANDLERS(QH)
+#undef QH
 
 int
 nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
@@ -44,8 +43,18 @@ nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
 	struct netdevsim *ns = netdev_priv(dev);
 
 	switch (type) {
-	case TC_SETUP_QDISC_TAPRIO:
-		return nsim_setup_tc_taprio(dev, type_data);
+#define TC_QDISC_SETUP_CASES(X)						\
+	X(TC_SETUP_QDISC_TAPRIO, tc_taprio_qopt_offload, taprio)	\
+
+#define SC(SETUP_LABEL, OL_TYPE, NAME)					\
+	case SETUP_LABEL:						\
+	{								\
+		return handle_##NAME(dev, (struct OL_TYPE *)type_data); \
+	}
+
+	TC_QDISC_SETUP_CASES(SC)
+#undef SC
+
 	case TC_SETUP_BLOCK:
 		return flow_block_cb_setup_simple(type_data,
 						  &nsim_block_cb_list,
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next 3/4] netdevsim: support ETS qdisc offload
  2026-03-10 18:06 [PATCH net-next 0/4] netdevsim: support ETS offload Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 1/4] netdevsim: move TC offload code to a dedicated file Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 2/4] netdevsim: generalize taprio offload Davide Caratti
@ 2026-03-10 18:06 ` Davide Caratti
  2026-03-10 18:06 ` [PATCH net-next 4/4] tc-testing: add a test case for ETS offload Davide Caratti
  3 siblings, 0 replies; 6+ messages in thread
From: Davide Caratti @ 2026-03-10 18:06 UTC (permalink / raw)
  To: Jakub Kicinski, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jamal Hadi Salim, Jiri Pirko
  Cc: netdev

Extend QDISC_OFFLOAD_HANDLERS() and TC_QDISC_SETUP_CASES() to add "fake"
offload for the 'ets' qdisc.

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
---
 drivers/net/netdevsim/tc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/netdevsim/tc.c b/drivers/net/netdevsim/tc.c
index 358fa5bb835f..ce0a8e6a611a 100644
--- a/drivers/net/netdevsim/tc.c
+++ b/drivers/net/netdevsim/tc.c
@@ -2,6 +2,7 @@
 
 #include <linux/netdevice.h>
 #include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
 
 #include "netdevsim.h"
 
@@ -16,6 +17,8 @@ static LIST_HEAD(nsim_block_cb_list);
 #define QDISC_OFFLOAD_HANDLERS(X)					\
 	X(taprio, tc_taprio_qopt_offload, cmd, TAPRIO_CMD_REPLACE,	\
 	  TAPRIO_CMD_DESTROY, TAPRIO_CMD_STATS, stats)			\
+	X(ets, tc_ets_qopt_offload, command, TC_ETS_REPLACE, TC_ETS_DESTROY, \
+	  TC_ETS_STATS, stats)						\
 
 #define QH(NAME, OL_TYPE, CMD_FLD, O_REPLACE, O_DESTROY, O_STATS, STATS_FLD) \
 static int handle_##NAME(struct net_device *dev, struct OL_TYPE *offload) \
@@ -45,6 +48,7 @@ nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
 	switch (type) {
 #define TC_QDISC_SETUP_CASES(X)						\
 	X(TC_SETUP_QDISC_TAPRIO, tc_taprio_qopt_offload, taprio)	\
+	X(TC_SETUP_QDISC_ETS, tc_ets_qopt_offload, ets)			\
 
 #define SC(SETUP_LABEL, OL_TYPE, NAME)					\
 	case SETUP_LABEL:						\
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next 4/4] tc-testing: add a test case for ETS offload
  2026-03-10 18:06 [PATCH net-next 0/4] netdevsim: support ETS offload Davide Caratti
                   ` (2 preceding siblings ...)
  2026-03-10 18:06 ` [PATCH net-next 3/4] netdevsim: support ETS qdisc offload Davide Caratti
@ 2026-03-10 18:06 ` Davide Caratti
  3 siblings, 0 replies; 6+ messages in thread
From: Davide Caratti @ 2026-03-10 18:06 UTC (permalink / raw)
  To: Jakub Kicinski, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jamal Hadi Salim, Jiri Pirko
  Cc: netdev

While reviewing the fix for unintentional u32 overflows in ets offload
code, Jamal said:

 [...]

 > otherwise a tdc test should cover it fine (when you get to the
 > netdevsim change perhaps)

Add a test case to reproduce the division by zero fixed in [1].

[1] https://lore.kernel.org/all/CAM0EoMm17wsYZmdFLshH3_-GrZtzd=i0xnoO2yiVB=-N4761mw@mail.gmail.com/

Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
---
 .../tc-testing/tc-tests/qdiscs/ets.json       | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
index a5d94cdec605..479b866031bb 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
@@ -984,5 +984,28 @@
         "matchCount": "1",
         "teardown": [
         ]
+    },
+    {
+        "id": "41f5",
+        "name": "ETS offload where the sum of quanta wraps u32",
+        "category": [
+            "qdisc",
+            "ets"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
+            "ethtool -K $ETH hw-tc-offload on"
+        ],
+        "cmdUnderTest": "$TC qdisc add dev $ETH root ets quanta 4294967294 1 1",
+        "expExitCode": "0",
+        "verifyCmd": "$TC qdisc show dev $ETH",
+        "matchPattern": "qdisc ets .*bands 3 quanta 4294967294 1 1",
+        "matchCount": "1",
+        "teardown": [
+            "echo \"1\" > /sys/bus/netdevsim/del_device"
+        ]
     }
 ]
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next 2/4] netdevsim: generalize taprio offload
  2026-03-10 18:06 ` [PATCH net-next 2/4] netdevsim: generalize taprio offload Davide Caratti
@ 2026-03-10 23:38   ` Jakub Kicinski
  0 siblings, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2026-03-10 23:38 UTC (permalink / raw)
  To: Davide Caratti
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
	Jamal Hadi Salim, Jiri Pirko, netdev

On Tue, 10 Mar 2026 19:06:29 +0100 Davide Caratti wrote:
> -static void nsim_taprio_stats(struct tc_taprio_qopt_stats *stats)
> -{
> -	stats->window_drops = 0;
> -	stats->tx_overruns = 0;
> -}
> +static LIST_HEAD(nsim_block_cb_list);
>  
> -static int nsim_setup_tc_taprio(struct net_device *dev,
> -				struct tc_taprio_qopt_offload *offload)
> -{
> -	int err = 0;
> -
> -	switch (offload->cmd) {
> -	case TAPRIO_CMD_REPLACE:
> -	case TAPRIO_CMD_DESTROY:
> -		break;
> -	case TAPRIO_CMD_STATS:
> -		nsim_taprio_stats(&offload->stats);
> -		break;
> -	default:
> -		err = -EOPNOTSUPP;
> -	}
> +#define QDISC_OFFLOAD_HANDLERS(X)					\
> +	X(taprio, tc_taprio_qopt_offload, cmd, TAPRIO_CMD_REPLACE,	\
> +	  TAPRIO_CMD_DESTROY, TAPRIO_CMD_STATS, stats)			\
>  
> -	return err;
> +#define QH(NAME, OL_TYPE, CMD_FLD, O_REPLACE, O_DESTROY, O_STATS, STATS_FLD) \
> +static int handle_##NAME(struct net_device *dev, struct OL_TYPE *offload) \
> +{									\
> +	switch (offload->CMD_FLD) {					\
> +	case O_REPLACE:							\
> +	case O_DESTROY:							\
> +		/* Do nothing, accept offload */			\
> +		return 0;						\
> +	case O_STATS:							\
> +		/* Zero out the requested stats block */		\
> +		memset(&offload->STATS_FLD, 0, sizeof(offload->STATS_FLD)); \
> +		return 0;						\
> +	default:							\
> +		return -EOPNOTSUPP;					\
> +	}								\
>  }
>  
> -static LIST_HEAD(nsim_block_cb_list);
> +QDISC_OFFLOAD_HANDLERS(QH)
> +#undef QH

Please just type the code in. These sort of macros are too ugly to live
in code I directly maintain, sorry.
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-10 23:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-10 18:06 [PATCH net-next 0/4] netdevsim: support ETS offload Davide Caratti
2026-03-10 18:06 ` [PATCH net-next 1/4] netdevsim: move TC offload code to a dedicated file Davide Caratti
2026-03-10 18:06 ` [PATCH net-next 2/4] netdevsim: generalize taprio offload Davide Caratti
2026-03-10 23:38   ` Jakub Kicinski
2026-03-10 18:06 ` [PATCH net-next 3/4] netdevsim: support ETS qdisc offload Davide Caratti
2026-03-10 18:06 ` [PATCH net-next 4/4] tc-testing: add a test case for ETS offload Davide Caratti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox