All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.