netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function
@ 2025-07-22  3:07 Samiullah Khawaja
  2025-07-22  3:07 ` [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers Samiullah Khawaja
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Samiullah Khawaja @ 2025-07-22  3:07 UTC (permalink / raw)
  To: Jakub Kicinski, David S . Miller , Eric Dumazet, Paolo Abeni,
	almasrymina, willemb
  Cc: netdev, skhawaja

Move multiple copies of same code snippet doing `gro_flush` and
`gro_normal_list` into separate helper function.

Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
---

v6:
 - gro_flush_helper renamed to gro_flush_normal and moved to gro.h. Also
   used it in kernel/bpf/cpumap.c
---
 include/net/gro.h   | 6 ++++++
 kernel/bpf/cpumap.c | 3 +--
 net/core/dev.c      | 9 +++------
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/net/gro.h b/include/net/gro.h
index 22d3a69e4404..a0fca7ac6e7e 100644
--- a/include/net/gro.h
+++ b/include/net/gro.h
@@ -534,6 +534,12 @@ static inline void gro_normal_list(struct gro_node *gro)
 	gro->rx_count = 0;
 }
 
+static inline void gro_flush_normal(struct gro_node *gro, bool flush_old)
+{
+	gro_flush(gro, flush_old);
+	gro_normal_list(gro);
+}
+
 /* Queue one GRO_NORMAL SKB up for list processing. If batch size exceeded,
  * pass the whole batch up to the stack.
  */
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index 67e8a2fc1a99..b2b7b8ec2c2a 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -282,8 +282,7 @@ static void cpu_map_gro_flush(struct bpf_cpu_map_entry *rcpu, bool empty)
 	 * This is equivalent to how NAPI decides whether to perform a full
 	 * flush.
 	 */
-	gro_flush(&rcpu->gro, !empty && HZ >= 1000);
-	gro_normal_list(&rcpu->gro);
+	gro_flush_normal(&rcpu->gro, !empty && HZ >= 1000);
 }
 
 static int cpu_map_kthread_run(void *data)
diff --git a/net/core/dev.c b/net/core/dev.c
index 354d3453b407..76384b8a7871 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6578,8 +6578,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
 	 * it, we need to bound somehow the time packets are kept in
 	 * the GRO layer.
 	 */
-	gro_flush(&n->gro, !!timeout);
-	gro_normal_list(&n->gro);
+	gro_flush_normal(&n->gro, !!timeout);
 
 	if (unlikely(!list_empty(&n->poll_list))) {
 		/* If n->poll_list is not empty, we need to mask irqs */
@@ -6649,8 +6648,7 @@ static void __busy_poll_stop(struct napi_struct *napi, bool skip_schedule)
 	}
 
 	/* Flush too old packets. If HZ < 1000, flush all packets */
-	gro_flush(&napi->gro, HZ >= 1000);
-	gro_normal_list(&napi->gro);
+	gro_flush_normal(&napi->gro, HZ >= 1000);
 
 	clear_bit(NAPI_STATE_SCHED, &napi->state);
 }
@@ -7515,8 +7513,7 @@ static int __napi_poll(struct napi_struct *n, bool *repoll)
 	}
 
 	/* Flush too old packets. If HZ < 1000, flush all packets */
-	gro_flush(&n->gro, HZ >= 1000);
-	gro_normal_list(&n->gro);
+	gro_flush_normal(&n->gro, HZ >= 1000);
 
 	/* Some drivers may have called napi_schedule
 	 * prior to exhausting their budget.

base-commit: fbd47be098b542dd8ad7beb42c88e7726d14cfb6
-- 
2.50.0.727.gbf7dc18ff4-goog


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

* [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers
  2025-07-22  3:07 [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Samiullah Khawaja
@ 2025-07-22  3:07 ` Samiullah Khawaja
  2025-07-22  8:21   ` Eric Dumazet
  2025-07-22  3:07 ` [PATCH net-next v7 3/3] net: define an enum for the napi threaded state Samiullah Khawaja
  2025-07-22  7:57 ` [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Eric Dumazet
  2 siblings, 1 reply; 8+ messages in thread
From: Samiullah Khawaja @ 2025-07-22  3:07 UTC (permalink / raw)
  To: Jakub Kicinski, David S . Miller , Eric Dumazet, Paolo Abeni,
	almasrymina, willemb
  Cc: netdev, skhawaja

Prepare for adding an enum type for NAPI threaded states by adding
netif_set_threaded_hint API. De-export the existing netif_set_threaded API
and only use it internally. Update existing drivers to use
netif_set_threaded_hint instead of the de-exported netif_set_threaded.

Note that dev_set_threaded used by mt76 debugfs file is unchanged.

Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
---
v7:
 - Rebased and resolved conflicts.

---
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/pci.c       | 2 +-
 drivers/net/ethernet/renesas/ravb_main.c        | 2 +-
 drivers/net/wireguard/device.c                  | 2 +-
 drivers/net/wireless/ath/ath10k/snoc.c          | 2 +-
 include/linux/netdevice.h                       | 2 +-
 net/core/dev.c                                  | 7 ++++++-
 net/core/dev.h                                  | 2 ++
 8 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 3a9ad4a9c1cb..ee7d07c86dcf 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2688,7 +2688,7 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	adapter->mii.mdio_write = atl1c_mdio_write;
 	adapter->mii.phy_id_mask = 0x1f;
 	adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
-	netif_set_threaded(netdev, true);
+	netif_set_threaded_hint(netdev);
 	for (i = 0; i < adapter->rx_queue_count; ++i)
 		netif_napi_add(netdev, &adapter->rrd_ring[i].napi,
 			       atl1c_clean_rx);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index a2e97b712a3d..e5af8ffd771c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -156,7 +156,7 @@ static int mlxsw_pci_napi_devs_init(struct mlxsw_pci *mlxsw_pci)
 	}
 	strscpy(mlxsw_pci->napi_dev_rx->name, "mlxsw_rx",
 		sizeof(mlxsw_pci->napi_dev_rx->name));
-	netif_set_threaded(mlxsw_pci->napi_dev_rx, true);
+	netif_set_threaded_hint(mlxsw_pci->napi_dev_rx);
 
 	return 0;
 
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 4e79bf88688a..068fff76d883 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -3075,7 +3075,7 @@ static int ravb_probe(struct platform_device *pdev)
 	if (info->coalesce_irqs) {
 		netdev_sw_irq_coalesce_default_on(ndev);
 		if (num_present_cpus() == 1)
-			netif_set_threaded(ndev, true);
+			netif_set_threaded_hint(ndev);
 	}
 
 	/* Network device register */
diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index 5afec5a865f4..b36c585d520a 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -366,7 +366,7 @@ static int wg_newlink(struct net_device *dev,
 	if (ret < 0)
 		goto err_free_handshake_queue;
 
-	netif_set_threaded(dev, true);
+	netif_set_threaded_hint(dev);
 	ret = register_netdevice(dev);
 	if (ret < 0)
 		goto err_uninit_ratelimiter;
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
index 0ee68d3dad12..3a84780529e2 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -936,7 +936,7 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
 
 	bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX);
 
-	netif_set_threaded(ar->napi_dev, true);
+	netif_set_threaded_hint(ar->napi_dev);
 	ath10k_core_napi_enable(ar);
 	/* IRQs are left enabled when we restart due to a firmware crash */
 	if (!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5aee8d3895f4..32ea881d79fe 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -589,7 +589,7 @@ static inline bool napi_complete(struct napi_struct *n)
 	return napi_complete_done(n, 0);
 }
 
-int netif_set_threaded(struct net_device *dev, bool threaded);
+int netif_set_threaded_hint(struct net_device *dev);
 int dev_set_threaded(struct net_device *dev, bool threaded);
 
 void napi_disable(struct napi_struct *n);
diff --git a/net/core/dev.c b/net/core/dev.c
index 76384b8a7871..4eeae65fda09 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7029,7 +7029,12 @@ int netif_set_threaded(struct net_device *dev, bool threaded)
 
 	return err;
 }
-EXPORT_SYMBOL(netif_set_threaded);
+
+int netif_set_threaded_hint(struct net_device *dev)
+{
+	return netif_set_threaded(dev, true);
+}
+EXPORT_SYMBOL(netif_set_threaded_hint);
 
 /**
  * netif_queue_set_napi - Associate queue with the napi
diff --git a/net/core/dev.h b/net/core/dev.h
index a603387fb566..f5b567310908 100644
--- a/net/core/dev.h
+++ b/net/core/dev.h
@@ -322,6 +322,8 @@ static inline bool napi_get_threaded(struct napi_struct *n)
 
 int napi_set_threaded(struct napi_struct *n, bool threaded);
 
+int netif_set_threaded(struct net_device *dev, bool threaded);
+
 int rps_cpumask_housekeeping(struct cpumask *mask);
 
 #if defined(CONFIG_DEBUG_NET) && defined(CONFIG_BPF_SYSCALL)
-- 
2.50.0.727.gbf7dc18ff4-goog


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

* [PATCH net-next v7 3/3] net: define an enum for the napi threaded state
  2025-07-22  3:07 [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Samiullah Khawaja
  2025-07-22  3:07 ` [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers Samiullah Khawaja
@ 2025-07-22  3:07 ` Samiullah Khawaja
  2025-07-22  7:57 ` [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Eric Dumazet
  2 siblings, 0 replies; 8+ messages in thread
From: Samiullah Khawaja @ 2025-07-22  3:07 UTC (permalink / raw)
  To: Jakub Kicinski, David S . Miller , Eric Dumazet, Paolo Abeni,
	almasrymina, willemb
  Cc: netdev, skhawaja

Instead of using '0' and '1' for napi threaded state use an enum with
'disabled' and 'enabled' states.

Tested:
 ./tools/testing/selftests/net/nl_netdev.py
 TAP version 13
 1..7
 ok 1 nl_netdev.empty_check
 ok 2 nl_netdev.lo_check
 ok 3 nl_netdev.page_pool_check
 ok 4 nl_netdev.napi_list_check
 ok 5 nl_netdev.dev_set_threaded
 ok 6 nl_netdev.napi_set_threaded
 ok 7 nl_netdev.nsim_rxq_reset_down
 # Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0

Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
---

v7:
 - Fixed yamllint issue.

v6:
 - Moved threaded in struct netdevice up to fill the cacheline hole.
 - Changed dev_set_threaded to dev_set_threaded_hint and removed the
   second argument that was always set to true by all the drivers.
   Exported only dev_set_threaded_hint and made dev_set_threaded core
   only function. This change is done in a separate commit.
 - Updated documentation comment for threaded in struct netdevice.

---
 Documentation/netlink/specs/netdev.yaml       | 13 ++++---
 .../networking/net_cachelines/net_device.rst  |  2 +-
 include/linux/netdevice.h                     | 10 +++---
 include/uapi/linux/netdev.h                   |  5 +++
 net/core/dev.c                                | 12 ++++---
 net/core/dev.h                                | 13 ++++---
 net/core/dev_api.c                            |  3 +-
 net/core/netdev-genl-gen.c                    |  2 +-
 net/core/netdev-genl.c                        |  2 +-
 tools/include/uapi/linux/netdev.h             |  5 +++
 tools/testing/selftests/net/nl_netdev.py      | 36 +++++++++----------
 11 files changed, 62 insertions(+), 41 deletions(-)

diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
index 85d0ea6ac426..c035dc0f64fd 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -85,6 +85,10 @@ definitions:
     name: qstats-scope
     type: flags
     entries: [queue]
+  -
+    name: napi-threaded
+    type: enum
+    entries: [disabled, enabled]
 
 attribute-sets:
   -
@@ -286,11 +290,10 @@ attribute-sets:
       -
         name: threaded
         doc: Whether the NAPI is configured to operate in threaded polling
-             mode. If this is set to 1 then the NAPI context operates in
-             threaded polling mode.
-        type: uint
-        checks:
-          max: 1
+             mode. If this is set to enabled then the NAPI context operates
+             in threaded polling mode.
+        type: u32
+        enum: napi-threaded
   -
     name: xsk-info
     attributes: []
diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index 2d3dc4692d20..1c19bb7705df 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -68,6 +68,7 @@ unsigned_char                       addr_assign_type
 unsigned_char                       addr_len
 unsigned_char                       upper_level
 unsigned_char                       lower_level
+u8                                  threaded                                                            napi_poll(napi_enable,netif_set_threaded)
 unsigned_short                      neigh_priv_len
 unsigned_short                      padded
 unsigned_short                      dev_id
@@ -165,7 +166,6 @@ struct sfp_bus*                     sfp_bus
 struct lock_class_key*              qdisc_tx_busylock
 bool                                proto_down
 unsigned:1                          wol_enabled
-unsigned:1                          threaded                                                            napi_poll(napi_enable,netif_set_threaded)
 unsigned_long:1                     see_all_hwtstamp_requests
 unsigned_long:1                     change_proto_down
 unsigned_long:1                     netns_immutable
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 32ea881d79fe..ee1bedb4ee06 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -369,7 +369,7 @@ struct napi_config {
 	u64 irq_suspend_timeout;
 	u32 defer_hard_irqs;
 	cpumask_t affinity_mask;
-	bool threaded;
+	u8 threaded;
 	unsigned int napi_id;
 };
 
@@ -590,7 +590,8 @@ static inline bool napi_complete(struct napi_struct *n)
 }
 
 int netif_set_threaded_hint(struct net_device *dev);
-int dev_set_threaded(struct net_device *dev, bool threaded);
+int dev_set_threaded(struct net_device *dev,
+		     enum netdev_napi_threaded threaded);
 
 void napi_disable(struct napi_struct *n);
 void napi_disable_locked(struct napi_struct *n);
@@ -1872,6 +1873,7 @@ enum netdev_reg_state {
  * 	@addr_len:		Hardware address length
  *	@upper_level:		Maximum depth level of upper devices.
  *	@lower_level:		Maximum depth level of lower devices.
+ *	@threaded:		napi threaded state.
  *	@neigh_priv_len:	Used in neigh_alloc()
  * 	@dev_id:		Used to differentiate devices that share
  * 				the same link layer address
@@ -2011,8 +2013,6 @@ enum netdev_reg_state {
  *			switch driver and used to set the phys state of the
  *			switch port.
  *
- *	@threaded:	napi threaded mode is enabled
- *
  *	@irq_affinity_auto: driver wants the core to store and re-assign the IRQ
  *			    affinity. Set by netif_enable_irq_affinity(), then
  *			    the driver must create a persistent napi by
@@ -2248,6 +2248,7 @@ struct net_device {
 	unsigned char		addr_len;
 	unsigned char		upper_level;
 	unsigned char		lower_level;
+	u8			threaded;
 
 	unsigned short		neigh_priv_len;
 	unsigned short          dev_id;
@@ -2429,7 +2430,6 @@ struct net_device {
 	struct sfp_bus		*sfp_bus;
 	struct lock_class_key	*qdisc_tx_busylock;
 	bool			proto_down;
-	bool			threaded;
 	bool			irq_affinity_auto;
 	bool			rx_cpu_rmap_auto;
 
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 1f3719a9a0eb..48eb49aa03d4 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -77,6 +77,11 @@ enum netdev_qstats_scope {
 	NETDEV_QSTATS_SCOPE_QUEUE = 1,
 };
 
+enum netdev_napi_threaded {
+	NETDEV_NAPI_THREADED_DISABLED,
+	NETDEV_NAPI_THREADED_ENABLED,
+};
+
 enum {
 	NETDEV_A_DEV_IFINDEX = 1,
 	NETDEV_A_DEV_PAD,
diff --git a/net/core/dev.c b/net/core/dev.c
index 4eeae65fda09..c236c7570693 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6963,7 +6963,8 @@ static void napi_stop_kthread(struct napi_struct *napi)
 	napi->thread = NULL;
 }
 
-int napi_set_threaded(struct napi_struct *napi, bool threaded)
+int napi_set_threaded(struct napi_struct *napi,
+		      enum netdev_napi_threaded threaded)
 {
 	if (threaded) {
 		if (!napi->thread) {
@@ -6988,7 +6989,8 @@ int napi_set_threaded(struct napi_struct *napi, bool threaded)
 	return 0;
 }
 
-int netif_set_threaded(struct net_device *dev, bool threaded)
+int netif_set_threaded(struct net_device *dev,
+		       enum netdev_napi_threaded threaded)
 {
 	struct napi_struct *napi;
 	int err = 0;
@@ -7000,7 +7002,7 @@ int netif_set_threaded(struct net_device *dev, bool threaded)
 			if (!napi->thread) {
 				err = napi_kthread_create(napi);
 				if (err) {
-					threaded = false;
+					threaded = NETDEV_NAPI_THREADED_DISABLED;
 					break;
 				}
 			}
@@ -7032,7 +7034,7 @@ int netif_set_threaded(struct net_device *dev, bool threaded)
 
 int netif_set_threaded_hint(struct net_device *dev)
 {
-	return netif_set_threaded(dev, true);
+	return netif_set_threaded(dev, NETDEV_NAPI_THREADED_ENABLED);
 }
 EXPORT_SYMBOL(netif_set_threaded_hint);
 
@@ -7349,7 +7351,7 @@ void netif_napi_add_weight_locked(struct net_device *dev,
 	 * threaded mode will not be enabled in napi_enable().
 	 */
 	if (dev->threaded && napi_kthread_create(napi))
-		dev->threaded = false;
+		dev->threaded = NETDEV_NAPI_THREADED_DISABLED;
 	netif_napi_set_irq_locked(napi, -1);
 }
 EXPORT_SYMBOL(netif_napi_add_weight_locked);
diff --git a/net/core/dev.h b/net/core/dev.h
index f5b567310908..ab69edc0c3e3 100644
--- a/net/core/dev.h
+++ b/net/core/dev.h
@@ -315,14 +315,19 @@ static inline void napi_set_irq_suspend_timeout(struct napi_struct *n,
 	WRITE_ONCE(n->irq_suspend_timeout, timeout);
 }
 
-static inline bool napi_get_threaded(struct napi_struct *n)
+static inline enum netdev_napi_threaded napi_get_threaded(struct napi_struct *n)
 {
-	return test_bit(NAPI_STATE_THREADED, &n->state);
+	if (test_bit(NAPI_STATE_THREADED, &n->state))
+		return NETDEV_NAPI_THREADED_ENABLED;
+
+	return NETDEV_NAPI_THREADED_DISABLED;
 }
 
-int napi_set_threaded(struct napi_struct *n, bool threaded);
+int napi_set_threaded(struct napi_struct *n,
+		      enum netdev_napi_threaded threaded);
 
-int netif_set_threaded(struct net_device *dev, bool threaded);
+int netif_set_threaded(struct net_device *dev,
+		       enum netdev_napi_threaded threaded);
 
 int rps_cpumask_housekeeping(struct cpumask *mask);
 
diff --git a/net/core/dev_api.c b/net/core/dev_api.c
index dd7f57013ce5..f28852078aa6 100644
--- a/net/core/dev_api.c
+++ b/net/core/dev_api.c
@@ -368,7 +368,8 @@ void netdev_state_change(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_state_change);
 
-int dev_set_threaded(struct net_device *dev, bool threaded)
+int dev_set_threaded(struct net_device *dev,
+		     enum netdev_napi_threaded threaded)
 {
 	int ret;
 
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
index 0994bd68a7e6..e9a2a6f26cb7 100644
--- a/net/core/netdev-genl-gen.c
+++ b/net/core/netdev-genl-gen.c
@@ -97,7 +97,7 @@ static const struct nla_policy netdev_napi_set_nl_policy[NETDEV_A_NAPI_THREADED
 	[NETDEV_A_NAPI_DEFER_HARD_IRQS] = NLA_POLICY_FULL_RANGE(NLA_U32, &netdev_a_napi_defer_hard_irqs_range),
 	[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT] = { .type = NLA_UINT, },
 	[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT] = { .type = NLA_UINT, },
-	[NETDEV_A_NAPI_THREADED] = NLA_POLICY_MAX(NLA_UINT, 1),
+	[NETDEV_A_NAPI_THREADED] = NLA_POLICY_MAX(NLA_U32, 1),
 };
 
 /* NETDEV_CMD_BIND_TX - do */
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 5875df372415..6314eb7bdf69 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -333,7 +333,7 @@ netdev_nl_napi_set_config(struct napi_struct *napi, struct genl_info *info)
 		int ret;
 
 		threaded = nla_get_uint(info->attrs[NETDEV_A_NAPI_THREADED]);
-		ret = napi_set_threaded(napi, !!threaded);
+		ret = napi_set_threaded(napi, threaded);
 		if (ret)
 			return ret;
 	}
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index 1f3719a9a0eb..48eb49aa03d4 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -77,6 +77,11 @@ enum netdev_qstats_scope {
 	NETDEV_QSTATS_SCOPE_QUEUE = 1,
 };
 
+enum netdev_napi_threaded {
+	NETDEV_NAPI_THREADED_DISABLED,
+	NETDEV_NAPI_THREADED_ENABLED,
+};
+
 enum {
 	NETDEV_A_DEV_IFINDEX = 1,
 	NETDEV_A_DEV_PAD,
diff --git a/tools/testing/selftests/net/nl_netdev.py b/tools/testing/selftests/net/nl_netdev.py
index c8ffade79a52..5c66421ab8aa 100755
--- a/tools/testing/selftests/net/nl_netdev.py
+++ b/tools/testing/selftests/net/nl_netdev.py
@@ -52,14 +52,14 @@ def napi_set_threaded(nf) -> None:
         napi1_id = napis[1]['id']
 
         # set napi threaded and verify
-        nf.napi_set({'id': napi0_id, 'threaded': 1})
+        nf.napi_set({'id': napi0_id, 'threaded': "enabled"})
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 1)
+        ksft_eq(napi0['threaded'], "enabled")
         ksft_ne(napi0.get('pid'), None)
 
         # check it is not set for napi1
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 0)
+        ksft_eq(napi1['threaded'], "disabled")
         ksft_eq(napi1.get('pid'), None)
 
         ip(f"link set dev {nsim.ifname} down")
@@ -67,18 +67,18 @@ def napi_set_threaded(nf) -> None:
 
         # verify if napi threaded is still set
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 1)
+        ksft_eq(napi0['threaded'], "enabled")
         ksft_ne(napi0.get('pid'), None)
 
         # check it is still not set for napi1
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 0)
+        ksft_eq(napi1['threaded'], "disabled")
         ksft_eq(napi1.get('pid'), None)
 
         # unset napi threaded and verify
-        nf.napi_set({'id': napi0_id, 'threaded': 0})
+        nf.napi_set({'id': napi0_id, 'threaded': "disabled"})
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 0)
+        ksft_eq(napi0['threaded'], "disabled")
         ksft_eq(napi0.get('pid'), None)
 
         # set threaded at device level
@@ -86,10 +86,10 @@ def napi_set_threaded(nf) -> None:
 
         # check napi threaded is set for both napis
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 1)
+        ksft_eq(napi0['threaded'], "enabled")
         ksft_ne(napi0.get('pid'), None)
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 1)
+        ksft_eq(napi1['threaded'], "enabled")
         ksft_ne(napi1.get('pid'), None)
 
         # unset threaded at device level
@@ -97,16 +97,16 @@ def napi_set_threaded(nf) -> None:
 
         # check napi threaded is unset for both napis
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 0)
+        ksft_eq(napi0['threaded'], "disabled")
         ksft_eq(napi0.get('pid'), None)
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 0)
+        ksft_eq(napi1['threaded'], "disabled")
         ksft_eq(napi1.get('pid'), None)
 
         # set napi threaded for napi0
         nf.napi_set({'id': napi0_id, 'threaded': 1})
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 1)
+        ksft_eq(napi0['threaded'], "enabled")
         ksft_ne(napi0.get('pid'), None)
 
         # unset threaded at device level
@@ -114,10 +114,10 @@ def napi_set_threaded(nf) -> None:
 
         # check napi threaded is unset for both napis
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 0)
+        ksft_eq(napi0['threaded'], "disabled")
         ksft_eq(napi0.get('pid'), None)
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 0)
+        ksft_eq(napi1['threaded'], "disabled")
         ksft_eq(napi1.get('pid'), None)
 
 def dev_set_threaded(nf) -> None:
@@ -141,10 +141,10 @@ def dev_set_threaded(nf) -> None:
 
         # check napi threaded is set for both napis
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 1)
+        ksft_eq(napi0['threaded'], "enabled")
         ksft_ne(napi0.get('pid'), None)
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 1)
+        ksft_eq(napi1['threaded'], "enabled")
         ksft_ne(napi1.get('pid'), None)
 
         # unset threaded
@@ -152,10 +152,10 @@ def dev_set_threaded(nf) -> None:
 
         # check napi threaded is unset for both napis
         napi0 = nf.napi_get({'id': napi0_id})
-        ksft_eq(napi0['threaded'], 0)
+        ksft_eq(napi0['threaded'], "disabled")
         ksft_eq(napi0.get('pid'), None)
         napi1 = nf.napi_get({'id': napi1_id})
-        ksft_eq(napi1['threaded'], 0)
+        ksft_eq(napi1['threaded'], "disabled")
         ksft_eq(napi1.get('pid'), None)
 
 def nsim_rxq_reset_down(nf) -> None:
-- 
2.50.0.727.gbf7dc18ff4-goog


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

* Re: [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function
  2025-07-22  3:07 [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Samiullah Khawaja
  2025-07-22  3:07 ` [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers Samiullah Khawaja
  2025-07-22  3:07 ` [PATCH net-next v7 3/3] net: define an enum for the napi threaded state Samiullah Khawaja
@ 2025-07-22  7:57 ` Eric Dumazet
  2 siblings, 0 replies; 8+ messages in thread
From: Eric Dumazet @ 2025-07-22  7:57 UTC (permalink / raw)
  To: Samiullah Khawaja
  Cc: Jakub Kicinski, David S . Miller, Paolo Abeni, almasrymina,
	willemb, netdev

On Mon, Jul 21, 2025 at 8:07 PM Samiullah Khawaja <skhawaja@google.com> wrote:
>
> Move multiple copies of same code snippet doing `gro_flush` and
> `gro_normal_list` into separate helper function.
>
> Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
> Reviewed-by: Willem de Bruijn <willemb@google.com>
> ---
>
> v6:
>  - gro_flush_helper renamed to gro_flush_normal and moved to gro.h. Also
>    used it in kernel/bpf/cpumap.c
>

Reviewed-by: Eric Dumazet <edumazet@google.com>

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

* Re: [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers
  2025-07-22  3:07 ` [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers Samiullah Khawaja
@ 2025-07-22  8:21   ` Eric Dumazet
  2025-07-22 22:41     ` Jakub Kicinski
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2025-07-22  8:21 UTC (permalink / raw)
  To: Samiullah Khawaja
  Cc: Jakub Kicinski, David S . Miller, Paolo Abeni, almasrymina,
	willemb, netdev

On Mon, Jul 21, 2025 at 8:07 PM Samiullah Khawaja <skhawaja@google.com> wrote:
>
> Prepare for adding an enum type for NAPI threaded states by adding
> netif_set_threaded_hint API. De-export the existing netif_set_threaded API
> and only use it internally. Update existing drivers to use
> netif_set_threaded_hint instead of the de-exported netif_set_threaded.
>
> Note that dev_set_threaded used by mt76 debugfs file is unchanged.
>
> Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
> ---
> v7:
>  - Rebased and resolved conflicts.
>
> ---
>  drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +-
>  drivers/net/ethernet/mellanox/mlxsw/pci.c       | 2 +-
>  drivers/net/ethernet/renesas/ravb_main.c        | 2 +-
>  drivers/net/wireguard/device.c                  | 2 +-
>  drivers/net/wireless/ath/ath10k/snoc.c          | 2 +-
>  include/linux/netdevice.h                       | 2 +-
>  net/core/dev.c                                  | 7 ++++++-
>  net/core/dev.h                                  | 2 ++
>  8 files changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> index 3a9ad4a9c1cb..ee7d07c86dcf 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> @@ -2688,7 +2688,7 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         adapter->mii.mdio_write = atl1c_mdio_write;
>         adapter->mii.phy_id_mask = 0x1f;
>         adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
> -       netif_set_threaded(netdev, true);
> +       netif_set_threaded_hint(netdev);

I have not seen a cover letter for this series ?

netif_set_threaded_hint() name seems a bit strange, it seems drivers
intent is to enable threaded mode ?

netif_threaded_enable() might be a better name.

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

* Re: [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers
  2025-07-22  8:21   ` Eric Dumazet
@ 2025-07-22 22:41     ` Jakub Kicinski
  2025-07-23  0:21       ` Samiullah Khawaja
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2025-07-22 22:41 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Samiullah Khawaja, David S . Miller, Paolo Abeni, almasrymina,
	willemb, netdev

On Tue, 22 Jul 2025 01:21:58 -0700 Eric Dumazet wrote:
> > diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > index 3a9ad4a9c1cb..ee7d07c86dcf 100644
> > --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > @@ -2688,7 +2688,7 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> >         adapter->mii.mdio_write = atl1c_mdio_write;
> >         adapter->mii.phy_id_mask = 0x1f;
> >         adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
> > -       netif_set_threaded(netdev, true);
> > +       netif_set_threaded_hint(netdev);  
> 
> I have not seen a cover letter for this series ?
> 
> netif_set_threaded_hint() name seems a bit strange, it seems drivers
> intent is to enable threaded mode ?
> 
> netif_threaded_enable() might be a better name.

Cover letter or at least a link to where this was suggested would indeed
be useful. I may have suggested the name, and if so the thinking was
that the API is for the driver to "recommend" that we default to
threaded NAPI, likely because the device is IRQ-challenged.
But no strong feelings if you prefer netif_set_threaded_enabled().

Since this is a driver-facing API a kdoc may be useful:

/**
 * netif_set_threaded_hint() - default to using threaded NAPIs
 * @dev: net_device instance
 *
 * Default NAPI instances of the device to run in threaded mode.
 * This may be useful for devices where multiple NAPI instances
 * get scheduled by a single interrupt. Threaded NAPI allows moving
 * the NAPI processing to cores other than the core where IRQ is mapped.
 *
 * This function should be called before @dev is registered.
 */

Since this is just a hint the function should be void. No caller cares
about the return value anyway.

BTW I think we should delete the debugfs file for threaded config
from mt76. debugfs is not uAPI, presumably.

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

* Re: [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers
  2025-07-22 22:41     ` Jakub Kicinski
@ 2025-07-23  0:21       ` Samiullah Khawaja
  2025-07-23  0:57         ` Jakub Kicinski
  0 siblings, 1 reply; 8+ messages in thread
From: Samiullah Khawaja @ 2025-07-23  0:21 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Eric Dumazet, David S . Miller, Paolo Abeni, almasrymina, willemb,
	netdev

On Tue, Jul 22, 2025 at 3:41 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Tue, 22 Jul 2025 01:21:58 -0700 Eric Dumazet wrote:
> > > diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > index 3a9ad4a9c1cb..ee7d07c86dcf 100644
> > > --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > @@ -2688,7 +2688,7 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> > >         adapter->mii.mdio_write = atl1c_mdio_write;
> > >         adapter->mii.phy_id_mask = 0x1f;
> > >         adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
> > > -       netif_set_threaded(netdev, true);
> > > +       netif_set_threaded_hint(netdev);
> >
> > I have not seen a cover letter for this series ?
> >
> > netif_set_threaded_hint() name seems a bit strange, it seems drivers
> > intent is to enable threaded mode ?
> >
> > netif_threaded_enable() might be a better name.
+1
>
> Cover letter or at least a link to where this was suggested would indeed
> be useful. I may have suggested the name, and if so the thinking was
> that the API is for the driver to "recommend" that we default to
> threaded NAPI, likely because the device is IRQ-challenged.
> But no strong feelings if you prefer netif_set_threaded_enabled().
Yes. You suggested it, but I am changing it to netif_threaded_enable
as it maybe is more clear.
>
> Since this is a driver-facing API a kdoc may be useful:
>
> /**
>  * netif_set_threaded_hint() - default to using threaded NAPIs
>  * @dev: net_device instance
>  *
>  * Default NAPI instances of the device to run in threaded mode.
>  * This may be useful for devices where multiple NAPI instances
>  * get scheduled by a single interrupt. Threaded NAPI allows moving
>  * the NAPI processing to cores other than the core where IRQ is mapped.
>  *
>  * This function should be called before @dev is registered.
>  */
+1
>
> Since this is just a hint the function should be void. No caller cares
> about the return value anyway.
+1
>
> BTW I think we should delete the debugfs file for threaded config
> from mt76. debugfs is not uAPI, presumably.
+1

Do you think I should send a patch for that with this series? I was
planning to remove that separately.

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

* Re: [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers
  2025-07-23  0:21       ` Samiullah Khawaja
@ 2025-07-23  0:57         ` Jakub Kicinski
  0 siblings, 0 replies; 8+ messages in thread
From: Jakub Kicinski @ 2025-07-23  0:57 UTC (permalink / raw)
  To: Samiullah Khawaja
  Cc: Eric Dumazet, David S . Miller, Paolo Abeni, almasrymina, willemb,
	netdev

On Tue, 22 Jul 2025 17:21:30 -0700 Samiullah Khawaja wrote:
> > BTW I think we should delete the debugfs file for threaded config
> > from mt76. debugfs is not uAPI, presumably.  
> +1
> 
> Do you think I should send a patch for that with this series? I was
> planning to remove that separately.

We can attach it to the next series. As I mentioned I don't want to
delay the last patch of this series, so fewer controversies for this
series the better.

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

end of thread, other threads:[~2025-07-23  0:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-22  3:07 [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Samiullah Khawaja
2025-07-22  3:07 ` [PATCH net-next v7 2/3] net: Use netif_set_threaded_hint instead of netif_set_threaded in drivers Samiullah Khawaja
2025-07-22  8:21   ` Eric Dumazet
2025-07-22 22:41     ` Jakub Kicinski
2025-07-23  0:21       ` Samiullah Khawaja
2025-07-23  0:57         ` Jakub Kicinski
2025-07-22  3:07 ` [PATCH net-next v7 3/3] net: define an enum for the napi threaded state Samiullah Khawaja
2025-07-22  7:57 ` [PATCH net-next v7 1/3] net: Create separate gro_flush_normal function Eric Dumazet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).