Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: designate XSK pool pointers in queues as "ops protected"

Read accesses go via xsk_get_pool_from_qid(), the call coming
from the core and gve look safe (other "ops locked" drivers
don't support XSK).

Write accesses go via xsk_reg_pool_at_qid() and xsk_clear_pool_at_qid().
Former is already under the ops lock, latter is not (both coming from
the workqueue via xp_clear_dev() and NETDEV_UNREGISTER via xsk_notifier()).

Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250408195956.412733-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+9 -4
+1
include/linux/netdevice.h
··· 688 688 /* Subordinate device that the queue has been assigned to */ 689 689 struct net_device *sb_dev; 690 690 #ifdef CONFIG_XDP_SOCKETS 691 + /* "ops protected", see comment about net_device::lock */ 691 692 struct xsk_buff_pool *pool; 692 693 #endif 693 694
+3 -3
include/net/netdev_rx_queue.h
··· 20 20 struct net_device *dev; 21 21 netdevice_tracker dev_tracker; 22 22 23 + /* All fields below are "ops protected", 24 + * see comment about net_device::lock 25 + */ 23 26 #ifdef CONFIG_XDP_SOCKETS 24 27 struct xsk_buff_pool *pool; 25 28 #endif 26 - /* NAPI instance for the queue 27 - * "ops protected", see comment about net_device::lock 28 - */ 29 29 struct napi_struct *napi; 30 30 struct pp_memory_provider_params mp_params; 31 31 } ____cacheline_aligned_in_smp;
+5 -1
net/xdp/xsk_buff_pool.c
··· 266 266 267 267 void xp_clear_dev(struct xsk_buff_pool *pool) 268 268 { 269 + struct net_device *netdev = pool->netdev; 270 + 269 271 if (!pool->netdev) 270 272 return; 271 273 274 + netdev_lock_ops(netdev); 272 275 xp_disable_drv_zc(pool); 273 276 xsk_clear_pool_at_qid(pool->netdev, pool->queue_id); 274 - dev_put(pool->netdev); 275 277 pool->netdev = NULL; 278 + netdev_unlock_ops(netdev); 279 + dev_put(netdev); 276 280 } 277 281 278 282 static void xp_release_deferred(struct work_struct *work)