From: Jesse Gross Date: Sat, 4 Dec 2010 17:43:35 +0000 (-0800) Subject: datapath: Convert patch vport to use call_rcu() on destruction. X-Git-Tag: v1.1.0~687 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=5b68fb428764e66dc73b2674ceb3f3e3555b59f2;p=sliver-openvswitch.git datapath: Convert patch vport to use call_rcu() on destruction. Since patch ports are virtual devices, we can potentially have many of them in a datapath. Currently we have a call to synchronize_rcu() each time we destroy one, which can be expensive if we are deleting a datapath with many ports. This converts it to use call_rcu() instead, which allows us to wait for only a single RCU grace period independent of the number of ports. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c index b0ae3a070..d49f83d36 100644 --- a/datapath/vport-patch.c +++ b/datapath/vport-patch.c @@ -22,6 +22,8 @@ struct device_config { }; struct patch_vport { + struct rcu_head rcu; + char name[IFNAMSIZ]; /* Protected by RTNL lock. */ @@ -158,19 +160,22 @@ static int patch_modify(struct vport *vport, struct odp_port *port) return err; } +static void free_port_rcu(struct rcu_head *rcu) +{ + struct patch_vport *patch_vport = container_of(rcu, + struct patch_vport, rcu); + + kfree(patch_vport->devconf); + vport_free(vport_from_priv(patch_vport)); +} + static int patch_destroy(struct vport *vport) { struct patch_vport *patch_vport = patch_vport_priv(vport); update_peers(patch_vport->name, NULL); - rcu_assign_pointer(patch_vport->peer, NULL); - hlist_del(&patch_vport->hash_node); - - synchronize_rcu(); - - kfree(patch_vport->devconf); - vport_free(vport); + call_rcu(&patch_vport->rcu, free_port_rcu); return 0; }