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>
This commit is contained in:
Jakub Kicinski 2025-04-08 12:59:49 -07:00
parent a82dc19db1
commit 606048cbd8
3 changed files with 9 additions and 4 deletions

View File

@ -688,6 +688,7 @@ struct netdev_queue {
/* Subordinate device that the queue has been assigned to */ /* Subordinate device that the queue has been assigned to */
struct net_device *sb_dev; struct net_device *sb_dev;
#ifdef CONFIG_XDP_SOCKETS #ifdef CONFIG_XDP_SOCKETS
/* "ops protected", see comment about net_device::lock */
struct xsk_buff_pool *pool; struct xsk_buff_pool *pool;
#endif #endif

View File

@ -20,12 +20,12 @@ struct netdev_rx_queue {
struct net_device *dev; struct net_device *dev;
netdevice_tracker dev_tracker; netdevice_tracker dev_tracker;
/* All fields below are "ops protected",
* see comment about net_device::lock
*/
#ifdef CONFIG_XDP_SOCKETS #ifdef CONFIG_XDP_SOCKETS
struct xsk_buff_pool *pool; struct xsk_buff_pool *pool;
#endif #endif
/* NAPI instance for the queue
* "ops protected", see comment about net_device::lock
*/
struct napi_struct *napi; struct napi_struct *napi;
struct pp_memory_provider_params mp_params; struct pp_memory_provider_params mp_params;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;

View File

@ -266,13 +266,17 @@ int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
void xp_clear_dev(struct xsk_buff_pool *pool) void xp_clear_dev(struct xsk_buff_pool *pool)
{ {
struct net_device *netdev = pool->netdev;
if (!pool->netdev) if (!pool->netdev)
return; return;
netdev_lock_ops(netdev);
xp_disable_drv_zc(pool); xp_disable_drv_zc(pool);
xsk_clear_pool_at_qid(pool->netdev, pool->queue_id); xsk_clear_pool_at_qid(pool->netdev, pool->queue_id);
dev_put(pool->netdev);
pool->netdev = NULL; pool->netdev = NULL;
netdev_unlock_ops(netdev);
dev_put(netdev);
} }
static void xp_release_deferred(struct work_struct *work) static void xp_release_deferred(struct work_struct *work)