Skip to content

Commit

Permalink
vxlan: reduce usage of synchronize_net in ndo_stop
Browse files Browse the repository at this point in the history
We only need to do the synchronize_net dance once for both, ipv4 and
ipv6 sockets, thus removing one synchronize_net in case both sockets get
dismantled.

Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hannes Frederic Sowa authored and David S. Miller committed Apr 16, 2016
1 parent 0412bd9 commit 544a773
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions drivers/net/vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,31 +1037,43 @@ static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev)
return false;
}

static void __vxlan_sock_release(struct vxlan_sock *vs)
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
{
struct vxlan_net *vn;

if (!vs)
return;
return false;
if (!atomic_dec_and_test(&vs->refcnt))
return;
return false;

vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
spin_lock(&vn->sock_lock);
hlist_del_rcu(&vs->hlist);
vxlan_notify_del_rx_port(vs);
spin_unlock(&vn->sock_lock);

synchronize_net();
udp_tunnel_sock_release(vs->sock);
kfree(vs);
return true;
}

static void vxlan_sock_release(struct vxlan_dev *vxlan)
{
__vxlan_sock_release(vxlan->vn4_sock);
bool ipv4 = __vxlan_sock_release_prep(vxlan->vn4_sock);
#if IS_ENABLED(CONFIG_IPV6)
__vxlan_sock_release(vxlan->vn6_sock);
bool ipv6 = __vxlan_sock_release_prep(vxlan->vn6_sock);
#endif

synchronize_net();

if (ipv4) {
udp_tunnel_sock_release(vxlan->vn4_sock->sock);
kfree(vxlan->vn4_sock);
}

#if IS_ENABLED(CONFIG_IPV6)
if (ipv6) {
udp_tunnel_sock_release(vxlan->vn6_sock->sock);
kfree(vxlan->vn6_sock);
}
#endif
}

Expand Down

0 comments on commit 544a773

Please sign in to comment.