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

net: add granular lock for the netdev netlink socket

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>

authored by

Stanislav Fomichev and committed by
Jakub Kicinski
10eef096 b6b67141

+7
+1
include/net/netdev_netlink.h
··· 5 5 #include <linux/list.h> 6 6 7 7 struct netdev_nl_sock { 8 + struct mutex lock; 8 9 struct list_head bindings; 9 10 }; 10 11
+6
net/core/netdev-genl.c
··· 859 859 goto err_genlmsg_free; 860 860 } 861 861 862 + mutex_lock(&priv->lock); 862 863 rtnl_lock(); 863 864 864 865 netdev = __dev_get_by_index(genl_info_net(info), ifindex); ··· 919 918 goto err_unbind; 920 919 921 920 rtnl_unlock(); 921 + mutex_unlock(&priv->lock); 922 922 923 923 return 0; 924 924 ··· 927 925 net_devmem_unbind_dmabuf(binding); 928 926 err_unlock: 929 927 rtnl_unlock(); 928 + mutex_unlock(&priv->lock); 930 929 err_genlmsg_free: 931 930 nlmsg_free(rsp); 932 931 return err; ··· 936 933 void netdev_nl_sock_priv_init(struct netdev_nl_sock *priv) 937 934 { 938 935 INIT_LIST_HEAD(&priv->bindings); 936 + mutex_init(&priv->lock); 939 937 } 940 938 941 939 void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv) ··· 944 940 struct net_devmem_dmabuf_binding *binding; 945 941 struct net_devmem_dmabuf_binding *temp; 946 942 943 + mutex_lock(&priv->lock); 947 944 list_for_each_entry_safe(binding, temp, &priv->bindings, list) { 948 945 rtnl_lock(); 949 946 net_devmem_unbind_dmabuf(binding); 950 947 rtnl_unlock(); 951 948 } 949 + mutex_unlock(&priv->lock); 952 950 } 953 951 954 952 static int netdev_genl_netdevice_event(struct notifier_block *nb,