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

Configure Feed

Select the types of activity you want to include in your feed.

vxlan: drop sock_lock

We won't be able to sleep soon in vxlan_offload_rx_ports and won't be
able to grab sock_lock. Instead of having separate spinlock to
manage sockets, rely on rtnl lock. This is similar to how geneve
manages its sockets.

Signed-off-by: Stanislav Fomichev <stfomichev@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20250616162117.287806-3-stfomichev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Stanislav Fomichev and committed by
Jakub Kicinski
df5425b3 3e14960f

+22 -33
+14 -21
drivers/net/vxlan/vxlan_core.c
··· 1485 1485 1486 1486 static bool __vxlan_sock_release_prep(struct vxlan_sock *vs) 1487 1487 { 1488 - struct vxlan_net *vn; 1488 + ASSERT_RTNL(); 1489 1489 1490 1490 if (!vs) 1491 1491 return false; 1492 1492 if (!refcount_dec_and_test(&vs->refcnt)) 1493 1493 return false; 1494 1494 1495 - vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id); 1496 - spin_lock(&vn->sock_lock); 1497 1495 hlist_del_rcu(&vs->hlist); 1498 1496 udp_tunnel_notify_del_rx_port(vs->sock, 1499 1497 (vs->flags & VXLAN_F_GPE) ? 1500 1498 UDP_TUNNEL_TYPE_VXLAN_GPE : 1501 1499 UDP_TUNNEL_TYPE_VXLAN); 1502 - spin_unlock(&vn->sock_lock); 1503 1500 1504 1501 return true; 1505 1502 } ··· 2854 2857 2855 2858 static void vxlan_vs_del_dev(struct vxlan_dev *vxlan) 2856 2859 { 2857 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 2860 + ASSERT_RTNL(); 2858 2861 2859 - spin_lock(&vn->sock_lock); 2860 2862 hlist_del_init_rcu(&vxlan->hlist4.hlist); 2861 2863 #if IS_ENABLED(CONFIG_IPV6) 2862 2864 hlist_del_init_rcu(&vxlan->hlist6.hlist); 2863 2865 #endif 2864 - spin_unlock(&vn->sock_lock); 2865 2866 } 2866 2867 2867 2868 static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan, 2868 2869 struct vxlan_dev_node *node) 2869 2870 { 2870 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 2871 2871 __be32 vni = vxlan->default_dst.remote_vni; 2872 2872 2873 + ASSERT_RTNL(); 2874 + 2873 2875 node->vxlan = vxlan; 2874 - spin_lock(&vn->sock_lock); 2875 2876 hlist_add_head_rcu(&node->hlist, vni_head(vs, vni)); 2876 - spin_unlock(&vn->sock_lock); 2877 2877 } 2878 2878 2879 2879 /* Setup stats when device is created */ ··· 3295 3301 struct vxlan_net *vn = net_generic(net, vxlan_net_id); 3296 3302 unsigned int i; 3297 3303 3298 - spin_lock(&vn->sock_lock); 3304 + ASSERT_RTNL(); 3305 + 3299 3306 for (i = 0; i < PORT_HASH_SIZE; ++i) { 3300 - hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist) { 3307 + hlist_for_each_entry(vs, &vn->sock_list[i], hlist) { 3301 3308 unsigned short type; 3302 3309 3303 3310 if (vs->flags & VXLAN_F_GPE) ··· 3312 3317 udp_tunnel_drop_rx_port(dev, vs->sock, type); 3313 3318 } 3314 3319 } 3315 - spin_unlock(&vn->sock_lock); 3316 3320 } 3317 3321 3318 3322 /* Initialize the device structure. */ ··· 3542 3548 __be16 port, u32 flags, 3543 3549 int ifindex) 3544 3550 { 3545 - struct vxlan_net *vn = net_generic(net, vxlan_net_id); 3546 3551 struct vxlan_sock *vs; 3547 3552 struct socket *sock; 3548 3553 unsigned int h; 3549 3554 struct udp_tunnel_sock_cfg tunnel_cfg; 3555 + 3556 + ASSERT_RTNL(); 3550 3557 3551 3558 vs = kzalloc(sizeof(*vs), GFP_KERNEL); 3552 3559 if (!vs) ··· 3566 3571 refcount_set(&vs->refcnt, 1); 3567 3572 vs->flags = (flags & VXLAN_F_RCV_FLAGS); 3568 3573 3569 - spin_lock(&vn->sock_lock); 3570 3574 hlist_add_head_rcu(&vs->hlist, vs_head(net, port)); 3571 3575 udp_tunnel_notify_add_rx_port(sock, 3572 3576 (vs->flags & VXLAN_F_GPE) ? 3573 3577 UDP_TUNNEL_TYPE_VXLAN_GPE : 3574 3578 UDP_TUNNEL_TYPE_VXLAN); 3575 - spin_unlock(&vn->sock_lock); 3576 3579 3577 3580 /* Mark socket as an encapsulation socket. */ 3578 3581 memset(&tunnel_cfg, 0, sizeof(tunnel_cfg)); ··· 3594 3601 3595 3602 static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6) 3596 3603 { 3597 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 3598 3604 bool metadata = vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA; 3599 3605 struct vxlan_sock *vs = NULL; 3600 3606 struct vxlan_dev_node *node; 3601 3607 int l3mdev_index = 0; 3608 + 3609 + ASSERT_RTNL(); 3602 3610 3603 3611 if (vxlan->cfg.remote_ifindex) 3604 3612 l3mdev_index = l3mdev_master_upper_ifindex_by_index( 3605 3613 vxlan->net, vxlan->cfg.remote_ifindex); 3606 3614 3607 3615 if (!vxlan->cfg.no_share) { 3608 - spin_lock(&vn->sock_lock); 3616 + rcu_read_lock(); 3609 3617 vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET, 3610 3618 vxlan->cfg.dst_port, vxlan->cfg.flags, 3611 3619 l3mdev_index); 3612 3620 if (vs && !refcount_inc_not_zero(&vs->refcnt)) { 3613 - spin_unlock(&vn->sock_lock); 3621 + rcu_read_unlock(); 3614 3622 return -EBUSY; 3615 3623 } 3616 - spin_unlock(&vn->sock_lock); 3624 + rcu_read_unlock(); 3617 3625 } 3618 3626 if (!vs) 3619 3627 vs = vxlan_socket_create(vxlan->net, ipv6, ··· 4888 4894 unsigned int h; 4889 4895 4890 4896 INIT_LIST_HEAD(&vn->vxlan_list); 4891 - spin_lock_init(&vn->sock_lock); 4892 4897 vn->nexthop_notifier_block.notifier_call = vxlan_nexthop_event; 4893 4898 4894 4899 for (h = 0; h < PORT_HASH_SIZE; ++h)
+1 -1
drivers/net/vxlan/vxlan_private.h
··· 19 19 /* per-network namespace private data for this module */ 20 20 struct vxlan_net { 21 21 struct list_head vxlan_list; 22 + /* sock_list is protected by rtnl lock */ 22 23 struct hlist_head sock_list[PORT_HASH_SIZE]; 23 - spinlock_t sock_lock; 24 24 struct notifier_block nexthop_notifier_block; 25 25 }; 26 26
+7 -11
drivers/net/vxlan/vxlan_vnifilter.c
··· 40 40 struct vxlan_vni_node *v, 41 41 bool del) 42 42 { 43 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 44 43 struct vxlan_dev_node *node; 45 44 struct vxlan_sock *vs; 46 45 47 - spin_lock(&vn->sock_lock); 46 + ASSERT_RTNL(); 47 + 48 48 if (del) { 49 49 if (!hlist_unhashed(&v->hlist4.hlist)) 50 50 hlist_del_init_rcu(&v->hlist4.hlist); ··· 52 52 if (!hlist_unhashed(&v->hlist6.hlist)) 53 53 hlist_del_init_rcu(&v->hlist6.hlist); 54 54 #endif 55 - goto out; 55 + return; 56 56 } 57 57 58 58 #if IS_ENABLED(CONFIG_IPV6) ··· 67 67 node = &v->hlist4; 68 68 hlist_add_head_rcu(&node->hlist, vni_head(vs, v->vni)); 69 69 } 70 - out: 71 - spin_unlock(&vn->sock_lock); 72 70 } 73 71 74 72 void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan, 75 73 struct vxlan_sock *vs, 76 74 bool ipv6) 77 75 { 78 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 79 76 struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp); 80 77 struct vxlan_vni_node *v, *tmp; 81 78 struct vxlan_dev_node *node; 82 79 80 + ASSERT_RTNL(); 81 + 83 82 if (!vg) 84 83 return; 85 84 86 - spin_lock(&vn->sock_lock); 87 85 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 88 86 #if IS_ENABLED(CONFIG_IPV6) 89 87 if (ipv6) ··· 92 94 node->vxlan = vxlan; 93 95 hlist_add_head_rcu(&node->hlist, vni_head(vs, v->vni)); 94 96 } 95 - spin_unlock(&vn->sock_lock); 96 97 } 97 98 98 99 void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan) 99 100 { 100 101 struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp); 101 - struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 102 102 struct vxlan_vni_node *v, *tmp; 103 + 104 + ASSERT_RTNL(); 103 105 104 106 if (!vg) 105 107 return; 106 108 107 - spin_lock(&vn->sock_lock); 108 109 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 109 110 hlist_del_init_rcu(&v->hlist4.hlist); 110 111 #if IS_ENABLED(CONFIG_IPV6) 111 112 hlist_del_init_rcu(&v->hlist6.hlist); 112 113 #endif 113 114 } 114 - spin_unlock(&vn->sock_lock); 115 115 } 116 116 117 117 static void vxlan_vnifilter_stats_get(const struct vxlan_vni_node *vninode,