[ovs-dev] [PATCH 03/19] datapath: Convert patch vport to use call_rcu() on destruction.

Jesse Gross jesse at nicira.com
Thu Dec 9 06:14:01 UTC 2010


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 <jesse at nicira.com>
---
 datapath/vport-patch.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c
index b0ae3a0..d49f83d 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;
 }
-- 
1.7.1





More information about the dev mailing list