net: add granular lock for the netdev netlink socket
authorStanislav Fomichev <sdf@fomichev.me>
Tue, 11 Mar 2025 14:40:25 +0000 (07:40 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 12 Mar 2025 20:32:35 +0000 (13:32 -0700)
As we move away from rtnl_lock for queue ops, introduce
per-netdev_nl_sock lock.

Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250311144026.4154277-3-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/netdev_netlink.h
net/core/netdev-genl.c

index 1599573..075962d 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/list.h>
 
 struct netdev_nl_sock {
+       struct mutex lock;
        struct list_head bindings;
 };
 
index a219be9..63e1071 100644 (file)
@@ -859,6 +859,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
                goto err_genlmsg_free;
        }
 
+       mutex_lock(&priv->lock);
        rtnl_lock();
 
        netdev = __dev_get_by_index(genl_info_net(info), ifindex);
@@ -918,6 +919,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
                goto err_unbind;
 
        rtnl_unlock();
+       mutex_unlock(&priv->lock);
 
        return 0;
 
@@ -925,6 +927,7 @@ err_unbind:
        net_devmem_unbind_dmabuf(binding);
 err_unlock:
        rtnl_unlock();
+       mutex_unlock(&priv->lock);
 err_genlmsg_free:
        nlmsg_free(rsp);
        return err;
@@ -933,6 +936,7 @@ err_genlmsg_free:
 void netdev_nl_sock_priv_init(struct netdev_nl_sock *priv)
 {
        INIT_LIST_HEAD(&priv->bindings);
+       mutex_init(&priv->lock);
 }
 
 void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
@@ -940,11 +944,13 @@ void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
        struct net_devmem_dmabuf_binding *binding;
        struct net_devmem_dmabuf_binding *temp;
 
+       mutex_lock(&priv->lock);
        list_for_each_entry_safe(binding, temp, &priv->bindings, list) {
                rtnl_lock();
                net_devmem_unbind_dmabuf(binding);
                rtnl_unlock();
        }
+       mutex_unlock(&priv->lock);
 }
 
 static int netdev_genl_netdevice_event(struct notifier_block *nb,