From: Jesse Gross Date: Wed, 28 Nov 2012 20:15:49 +0000 (-0800) Subject: datapath: Use RCU callback when detaching netdevices. X-Git-Tag: sliver-openvswitch-1.9.90-3~10^2~146 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=e65361d6b6fa0c3fb383b37cd259a24846ded7d5;p=sliver-openvswitch.git datapath: Use RCU callback when detaching netdevices. Currently, each time a device is detached from an OVS datapath we call synchronize RCU before freeing associated data structures. However, if a bridge is deleted (which detaches all ports) when many devices are connected then there can be a long delay. This switches to use call_rcu() to group the cost together. Reported-by: Justin Pettit Signed-off-by: Jesse Gross --- diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index f1ecfdbfe..5f437d343 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -173,6 +173,15 @@ error: return ERR_PTR(err); } +static void free_port_rcu(struct rcu_head *rcu) +{ + struct netdev_vport *netdev_vport = container_of(rcu, + struct netdev_vport, rcu); + + dev_put(netdev_vport->dev); + ovs_vport_free(vport_from_priv(netdev_vport)); +} + static void netdev_destroy(struct vport *vport) { struct netdev_vport *netdev_vport = netdev_vport_priv(vport); @@ -181,10 +190,7 @@ static void netdev_destroy(struct vport *vport) netdev_rx_handler_unregister(netdev_vport->dev); dev_set_promiscuity(netdev_vport->dev, -1); - synchronize_rcu(); - - dev_put(netdev_vport->dev); - ovs_vport_free(vport); + call_rcu(&netdev_vport->rcu, free_port_rcu); } int ovs_netdev_set_addr(struct vport *vport, const unsigned char *addr) diff --git a/datapath/vport-netdev.h b/datapath/vport-netdev.h index c9cf5e509..b4f455dd3 100644 --- a/datapath/vport-netdev.h +++ b/datapath/vport-netdev.h @@ -20,12 +20,15 @@ #define VPORT_NETDEV_H 1 #include +#include #include "vport.h" struct vport *ovs_netdev_get_vport(struct net_device *dev); struct netdev_vport { + struct rcu_head rcu; + struct net_device *dev; };