From: Shivaji Kant <shivajikant@google.com>
To: netdev@vger.kernel.org
Cc: praan@google.com, Shivaji Kant <shivajikant@google.com>,
Mina Almasry <almasrymina@google.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Bobby Eshleman <bobbyeshleman@meta.com>,
Stanislav Fomichev <sdf@fomichev.me>,
Dragos Tatulea <dtatulea@nvidia.com>, Kees Cook <kees@kernel.org>,
David Carlier <devnexen@gmail.com>,
Yue Haibing <yuehaibing@huawei.com>,
Daniel Borkmann <daniel@iogearbox.net>,
Nikolay Aleksandrov <razor@blackwall.org>,
David Wei <dw@davidwei.uk>, Maoyi Xie <maoyixie.tju@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next v2] net: convert netdev_nl_sock bindings list to xarray
Date: Tue, 11 Aug 2026 14:29:39 +0000 [thread overview]
Message-ID: <20260811142958.160088-1-shivajikant@google.com> (raw)
netdev_nl_sock previously used a struct list_head bindings to keep
track of active netdev netlink bindings, protected by a per-socket
struct mutex lock (priv->lock).
Since list modifications and iterations are not concurrency-safe,
priv->lock was introduced to serialize operations on priv->bindings.
However, xarray manages its own internal locking (xa_lock) for store,
erase, and iteration operations.
Convert bindings in struct netdev_nl_sock from struct list_head to
struct xarray and remove priv->lock. This simplifies the code by
removing explicit mutex locking in netdev_nl_bind_rx_doit(),
netdev_nl_bind_tx_doit(), and socket initialization/teardown functions.
Reviewed-by: Mina Almasry <almasrymina@google.com>
Signed-off-by: Shivaji Kant <shivajikant@google.com>
---
v1 -> v2:
- Add explicit err_erase_dmabuf_bindings err label in net_devmem_bind_dmabuf()
to align cleanup paths with the rest of the function (feedback from reviewer).
v1: https://lore.kernel.org/all/20260810065759.3735934-1-shivajikant@google.com/
include/net/netdev_netlink.h | 5 ++---
net/core/devmem.c | 14 +++++++++++---
net/core/devmem.h | 4 ++--
net/core/netdev-genl.c | 25 ++++++-------------------
4 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/include/net/netdev_netlink.h b/include/net/netdev_netlink.h
index 075962dbe743..45a4a482d42e 100644
--- a/include/net/netdev_netlink.h
+++ b/include/net/netdev_netlink.h
@@ -2,11 +2,10 @@
#ifndef __NET_NETDEV_NETLINK_H
#define __NET_NETDEV_NETLINK_H
-#include <linux/list.h>
+#include <linux/xarray.h>
struct netdev_nl_sock {
- struct mutex lock;
- struct list_head bindings;
+ struct xarray bindings;
};
#endif /* __NET_NETDEV_NETLINK_H */
diff --git a/net/core/devmem.c b/net/core/devmem.c
index 957d6b96216b..bdf8a0799a42 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -134,8 +134,8 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
*/
synchronize_net();
- if (binding->list.next)
- list_del(&binding->list);
+ if (binding->sock_priv)
+ xa_erase(&binding->sock_priv->bindings, binding->id);
xa_for_each(&binding->bound_rxqs, xa_idx, rxq) {
const struct pp_memory_provider_params mp_params = {
@@ -193,6 +193,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
struct dma_buf *dmabuf;
unsigned int sg_idx, i;
unsigned long virtual;
+ void *res;
int err;
if (!dma_dev) {
@@ -325,10 +326,17 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
if (err < 0)
goto err_free_chunks;
- list_add(&binding->list, &priv->bindings);
+ binding->sock_priv = priv;
+ res = xa_store(&priv->bindings, binding->id, binding, GFP_KERNEL);
+ if (xa_is_err(res)) {
+ err = xa_err(res);
+ goto err_erase_dmabuf_bindings;
+ }
return binding;
+err_erase_dmabuf_bindings:
+ xa_erase(&net_devmem_dmabuf_bindings, binding->id);
err_free_chunks:
gen_pool_for_each_chunk(binding->chunk_pool,
net_devmem_dmabuf_free_chunk_owner, NULL);
diff --git a/net/core/devmem.h b/net/core/devmem.h
index 3852a56036cb..bf77e5a9a8fe 100644
--- a/net/core/devmem.h
+++ b/net/core/devmem.h
@@ -49,10 +49,10 @@ struct net_devmem_dmabuf_binding {
*/
struct percpu_ref ref;
- /* The list of bindings currently active. Used for netlink to notify us
+ /* The socket priv this binding belongs to. Used for netlink to notify us
* of the user dropping the bind.
*/
- struct list_head list;
+ struct netdev_nl_sock *sock_priv;
/* rxq's this binding is active on. */
struct xarray bound_rxqs;
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index c15d8d4ca1f8..d3f3a91a6d93 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -1044,13 +1044,11 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
goto err_genlmsg_free;
}
- mutex_lock(&priv->lock);
-
err = 0;
netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
if (!netdev) {
err = -ENODEV;
- goto err_unlock_sock;
+ goto err_genlmsg_free;
}
if (!netif_device_present(netdev))
err = -ENODEV;
@@ -1102,8 +1100,6 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
netdev_unlock(netdev);
- mutex_unlock(&priv->lock);
-
return err < 0 ? err : 0;
err_unbind:
@@ -1112,8 +1108,6 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
bitmap_free(rxq_bitmap);
err_unlock:
netdev_unlock(netdev);
-err_unlock_sock:
- mutex_unlock(&priv->lock);
err_genlmsg_free:
nlmsg_free(rsp);
return err;
@@ -1185,12 +1179,10 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
goto err_genlmsg_free;
}
- mutex_lock(&priv->lock);
-
netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
if (!netdev) {
err = -ENODEV;
- goto err_unlock_sock;
+ goto err_genlmsg_free;
}
if (!netif_device_present(netdev)) {
@@ -1233,7 +1225,6 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
if (bind_dev != netdev)
netdev_unlock(bind_dev);
netdev_unlock(netdev);
- mutex_unlock(&priv->lock);
return genlmsg_reply(rsp, info);
@@ -1242,8 +1233,6 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
netdev_unlock(bind_dev);
err_unlock_netdev:
netdev_unlock(netdev);
-err_unlock_sock:
- mutex_unlock(&priv->lock);
err_genlmsg_free:
nlmsg_free(rsp);
return err;
@@ -1418,19 +1407,17 @@ int netdev_nl_queue_create_doit(struct sk_buff *skb, struct genl_info *info)
void netdev_nl_sock_priv_init(struct netdev_nl_sock *priv)
{
- INIT_LIST_HEAD(&priv->bindings);
- mutex_init(&priv->lock);
+ xa_init(&priv->bindings);
}
void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
{
struct net_devmem_dmabuf_binding *binding;
- struct net_devmem_dmabuf_binding *temp;
netdevice_tracker dev_tracker;
struct net_device *dev;
+ unsigned long xa_idx;
- mutex_lock(&priv->lock);
- list_for_each_entry_safe(binding, temp, &priv->bindings, list) {
+ xa_for_each(&priv->bindings, xa_idx, binding) {
mutex_lock(&binding->lock);
dev = binding->dev;
if (!dev) {
@@ -1446,7 +1433,7 @@ void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
netdev_unlock(dev);
netdev_put(dev, &dev_tracker);
}
- mutex_unlock(&priv->lock);
+ xa_destroy(&priv->bindings);
}
static int netdev_genl_netdevice_event(struct notifier_block *nb,
--
2.55.0.654.g21b8a5bc05-goog
next reply other threads:[~2026-08-11 14:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 14:29 Shivaji Kant [this message]
2026-08-12 14:30 ` [PATCH net-next v2] net: convert netdev_nl_sock bindings list to xarray Nikolay Aleksandrov
2026-08-13 0:28 ` Jakub Kicinski
2026-08-13 0:28 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260811142958.160088-1-shivajikant@google.com \
--to=shivajikant@google.com \
--cc=almasrymina@google.com \
--cc=bobbyeshleman@meta.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=devnexen@gmail.com \
--cc=dtatulea@nvidia.com \
--cc=dw@davidwei.uk \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maoyixie.tju@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=praan@google.com \
--cc=razor@blackwall.org \
--cc=sdf@fomichev.me \
--cc=yuehaibing@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.