From 129cdce9da9e44c52d38889e0411be9817bca114 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 24 Jun 2026 11:20:16 -0700 Subject: net: add the driver-facing netdev_work scheduling API With an extra event mask we can easily extend the netdev work to also service driver-defined events. For advanced drivers this is probably not a perfect match, but it makes running deferred work easier in simple cases. Expose the netdev_work facility to drivers. Add helpers to schedule work and a dedicated ndo to perform the driver- -scheduled actions. Reviewed-by: Kuniyuki Iwashima Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20260624182018.2445732-3-kuba@kernel.org Signed-off-by: Jakub Kicinski --- include/linux/netdevice.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 732506787db3..9981d637f8b5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1131,6 +1131,9 @@ struct netdev_net_notifier { * netdev_hw_addr_list_for_each(ha, uc). Return 0 on success or a * negative errno to request a retry via the core backoff. * + * void (*ndo_work)(struct net_device *dev, unsigned long events); + * Run deferred work scheduled with netdev_work_sched(@events). + * * int (*ndo_set_mac_address)(struct net_device *dev, void *addr); * This function is called when the Media Access Control address * needs to be changed. If this interface is not defined, the @@ -1460,6 +1463,8 @@ struct net_device_ops { struct net_device *dev, struct netdev_hw_addr_list *uc, struct netdev_hw_addr_list *mc); + void (*ndo_work)(struct net_device *dev, + unsigned long events); int (*ndo_set_mac_address)(struct net_device *dev, void *addr); int (*ndo_validate_addr)(struct net_device *dev); @@ -1932,6 +1937,8 @@ enum netdev_reg_state { * does not implement ndo_set_rx_mode() * @work_node: List entry for async netdev_work processing * @work_tracker: Refcount tracker for async netdev_work + * @work_pending: Driver-defined pending netdev_work, passed to + * ndo_work() (see netdev_work_sched()) * @work_core_pending: Core-defined pending netdev_work (NETDEV_WORK_*) * @rx_mode_addr_cache: Recycled snapshot entries for rx_mode work * @rx_mode_retry_timer: Timer that re-queues rx_mode work after failure @@ -2329,6 +2336,7 @@ struct net_device { bool uc_promisc; struct list_head work_node; netdevice_tracker work_tracker; + unsigned long work_pending; unsigned long work_core_pending; struct netdev_hw_addr_list rx_mode_addr_cache; struct timer_list rx_mode_retry_timer; @@ -5178,6 +5186,9 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, const struct pcpu_sw_netstats __percpu *netstats); void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s); +void netdev_work_sched(struct net_device *dev, unsigned long events); +unsigned long netdev_work_cancel(struct net_device *dev, unsigned long mask); + enum { NESTED_SYNC_IMM_BIT, NESTED_SYNC_TODO_BIT, -- cgit v1.2.3