Skip to content

Commit df5425b

Browse files
Stanislav Fomichevkuba-moo
authored andcommitted
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 <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3e14960 commit df5425b

File tree

3 files changed

+22
-33
lines changed

3 files changed

+22
-33
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,21 +1485,18 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
14851485

14861486
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
14871487
{
1488-
struct vxlan_net *vn;
1488+
ASSERT_RTNL();
14891489

14901490
if (!vs)
14911491
return false;
14921492
if (!refcount_dec_and_test(&vs->refcnt))
14931493
return false;
14941494

1495-
vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
1496-
spin_lock(&vn->sock_lock);
14971495
hlist_del_rcu(&vs->hlist);
14981496
udp_tunnel_notify_del_rx_port(vs->sock,
14991497
(vs->flags & VXLAN_F_GPE) ?
15001498
UDP_TUNNEL_TYPE_VXLAN_GPE :
15011499
UDP_TUNNEL_TYPE_VXLAN);
1502-
spin_unlock(&vn->sock_lock);
15031500

15041501
return true;
15051502
}
@@ -2857,26 +2854,23 @@ static void vxlan_cleanup(struct timer_list *t)
28572854

28582855
static void vxlan_vs_del_dev(struct vxlan_dev *vxlan)
28592856
{
2860-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
2857+
ASSERT_RTNL();
28612858

2862-
spin_lock(&vn->sock_lock);
28632859
hlist_del_init_rcu(&vxlan->hlist4.hlist);
28642860
#if IS_ENABLED(CONFIG_IPV6)
28652861
hlist_del_init_rcu(&vxlan->hlist6.hlist);
28662862
#endif
2867-
spin_unlock(&vn->sock_lock);
28682863
}
28692864

28702865
static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan,
28712866
struct vxlan_dev_node *node)
28722867
{
2873-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
28742868
__be32 vni = vxlan->default_dst.remote_vni;
28752869

2870+
ASSERT_RTNL();
2871+
28762872
node->vxlan = vxlan;
2877-
spin_lock(&vn->sock_lock);
28782873
hlist_add_head_rcu(&node->hlist, vni_head(vs, vni));
2879-
spin_unlock(&vn->sock_lock);
28802874
}
28812875

28822876
/* Setup stats when device is created */
@@ -3301,9 +3295,10 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push)
33013295
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
33023296
unsigned int i;
33033297

3304-
spin_lock(&vn->sock_lock);
3298+
ASSERT_RTNL();
3299+
33053300
for (i = 0; i < PORT_HASH_SIZE; ++i) {
3306-
hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist) {
3301+
hlist_for_each_entry(vs, &vn->sock_list[i], hlist) {
33073302
unsigned short type;
33083303

33093304
if (vs->flags & VXLAN_F_GPE)
@@ -3317,7 +3312,6 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push)
33173312
udp_tunnel_drop_rx_port(dev, vs->sock, type);
33183313
}
33193314
}
3320-
spin_unlock(&vn->sock_lock);
33213315
}
33223316

33233317
/* Initialize the device structure. */
@@ -3548,12 +3542,13 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
35483542
__be16 port, u32 flags,
35493543
int ifindex)
35503544
{
3551-
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
35523545
struct vxlan_sock *vs;
35533546
struct socket *sock;
35543547
unsigned int h;
35553548
struct udp_tunnel_sock_cfg tunnel_cfg;
35563549

3550+
ASSERT_RTNL();
3551+
35573552
vs = kzalloc(sizeof(*vs), GFP_KERNEL);
35583553
if (!vs)
35593554
return ERR_PTR(-ENOMEM);
@@ -3571,13 +3566,11 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
35713566
refcount_set(&vs->refcnt, 1);
35723567
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
35733568

3574-
spin_lock(&vn->sock_lock);
35753569
hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
35763570
udp_tunnel_notify_add_rx_port(sock,
35773571
(vs->flags & VXLAN_F_GPE) ?
35783572
UDP_TUNNEL_TYPE_VXLAN_GPE :
35793573
UDP_TUNNEL_TYPE_VXLAN);
3580-
spin_unlock(&vn->sock_lock);
35813574

35823575
/* Mark socket as an encapsulation socket. */
35833576
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
@@ -3601,26 +3594,27 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
36013594

36023595
static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
36033596
{
3604-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
36053597
bool metadata = vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA;
36063598
struct vxlan_sock *vs = NULL;
36073599
struct vxlan_dev_node *node;
36083600
int l3mdev_index = 0;
36093601

3602+
ASSERT_RTNL();
3603+
36103604
if (vxlan->cfg.remote_ifindex)
36113605
l3mdev_index = l3mdev_master_upper_ifindex_by_index(
36123606
vxlan->net, vxlan->cfg.remote_ifindex);
36133607

36143608
if (!vxlan->cfg.no_share) {
3615-
spin_lock(&vn->sock_lock);
3609+
rcu_read_lock();
36163610
vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
36173611
vxlan->cfg.dst_port, vxlan->cfg.flags,
36183612
l3mdev_index);
36193613
if (vs && !refcount_inc_not_zero(&vs->refcnt)) {
3620-
spin_unlock(&vn->sock_lock);
3614+
rcu_read_unlock();
36213615
return -EBUSY;
36223616
}
3623-
spin_unlock(&vn->sock_lock);
3617+
rcu_read_unlock();
36243618
}
36253619
if (!vs)
36263620
vs = vxlan_socket_create(vxlan->net, ipv6,
@@ -4894,7 +4888,6 @@ static __net_init int vxlan_init_net(struct net *net)
48944888
unsigned int h;
48954889

48964890
INIT_LIST_HEAD(&vn->vxlan_list);
4897-
spin_lock_init(&vn->sock_lock);
48984891
vn->nexthop_notifier_block.notifier_call = vxlan_nexthop_event;
48994892

49004893
for (h = 0; h < PORT_HASH_SIZE; ++h)

drivers/net/vxlan/vxlan_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ extern const struct rhashtable_params vxlan_vni_rht_params;
1919
/* per-network namespace private data for this module */
2020
struct vxlan_net {
2121
struct list_head vxlan_list;
22+
/* sock_list is protected by rtnl lock */
2223
struct hlist_head sock_list[PORT_HASH_SIZE];
23-
spinlock_t sock_lock;
2424
struct notifier_block nexthop_notifier_block;
2525
};
2626

drivers/net/vxlan/vxlan_vnifilter.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ static void vxlan_vs_add_del_vninode(struct vxlan_dev *vxlan,
4040
struct vxlan_vni_node *v,
4141
bool del)
4242
{
43-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
4443
struct vxlan_dev_node *node;
4544
struct vxlan_sock *vs;
4645

47-
spin_lock(&vn->sock_lock);
46+
ASSERT_RTNL();
47+
4848
if (del) {
4949
if (!hlist_unhashed(&v->hlist4.hlist))
5050
hlist_del_init_rcu(&v->hlist4.hlist);
5151
#if IS_ENABLED(CONFIG_IPV6)
5252
if (!hlist_unhashed(&v->hlist6.hlist))
5353
hlist_del_init_rcu(&v->hlist6.hlist);
5454
#endif
55-
goto out;
55+
return;
5656
}
5757

5858
#if IS_ENABLED(CONFIG_IPV6)
@@ -67,23 +67,21 @@ static void vxlan_vs_add_del_vninode(struct vxlan_dev *vxlan,
6767
node = &v->hlist4;
6868
hlist_add_head_rcu(&node->hlist, vni_head(vs, v->vni));
6969
}
70-
out:
71-
spin_unlock(&vn->sock_lock);
7270
}
7371

7472
void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,
7573
struct vxlan_sock *vs,
7674
bool ipv6)
7775
{
78-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
7976
struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp);
8077
struct vxlan_vni_node *v, *tmp;
8178
struct vxlan_dev_node *node;
8279

80+
ASSERT_RTNL();
81+
8382
if (!vg)
8483
return;
8584

86-
spin_lock(&vn->sock_lock);
8785
list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
8886
#if IS_ENABLED(CONFIG_IPV6)
8987
if (ipv6)
@@ -94,26 +92,24 @@ void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,
9492
node->vxlan = vxlan;
9593
hlist_add_head_rcu(&node->hlist, vni_head(vs, v->vni));
9694
}
97-
spin_unlock(&vn->sock_lock);
9895
}
9996

10097
void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan)
10198
{
10299
struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp);
103-
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
104100
struct vxlan_vni_node *v, *tmp;
105101

102+
ASSERT_RTNL();
103+
106104
if (!vg)
107105
return;
108106

109-
spin_lock(&vn->sock_lock);
110107
list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
111108
hlist_del_init_rcu(&v->hlist4.hlist);
112109
#if IS_ENABLED(CONFIG_IPV6)
113110
hlist_del_init_rcu(&v->hlist6.hlist);
114111
#endif
115112
}
116-
spin_unlock(&vn->sock_lock);
117113
}
118114

119115
static void vxlan_vnifilter_stats_get(const struct vxlan_vni_node *vninode,

0 commit comments

Comments
 (0)