[ovs-dev] [PATCH 07/10] datapath: Add casts for direct freeing of RCU data.

Jesse Gross jesse at nicira.com
Wed Dec 29 04:50:45 UTC 2010


There are a few places where we have two levels of RCU protected
data to allow the second level to change independently of the
first.  Although the two pieces are independent, they have the
same users and the same lifetime.  This means that we directly
free the second level when it is safe to free the first.  This
implies that we directly access RCU-protected data, which is
generally not allowed.  There are locks to check, so none of the
normal RCU functions apply.  Instead, this adds an explicit cast.

Found with sparse.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/flow.c        |    2 +-
 datapath/tunnel.c      |    7 ++++---
 datapath/vport-patch.c |    4 ++--
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/datapath/flow.c b/datapath/flow.c
index 5cf0d54..b33b315 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -175,7 +175,7 @@ void flow_put(struct sw_flow *flow)
 		return;
 
 	if (atomic_dec_and_test(&flow->refcnt)) {
-		kfree(flow->sf_acts);
+		kfree((struct sf_flow_acts __force *)flow->sf_acts);
 		kmem_cache_free(flow_cache, flow);
 	}
 }
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index ee9e45d..d49d928 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -1456,10 +1456,11 @@ error:
 
 static void free_port_rcu(struct rcu_head *rcu)
 {
-	struct tnl_vport *tnl_vport = container_of(rcu, struct tnl_vport, rcu);
+	struct tnl_vport *tnl_vport = container_of(rcu,
+						   struct tnl_vport, rcu);
 
-	free_cache(tnl_vport->cache);
-	kfree(tnl_vport->mutable);
+	free_cache((struct tnl_cache __force *)tnl_vport->cache);
+	kfree((struct tnl_mutable __force *)tnl_vport->mutable);
 	vport_free(tnl_vport_to_vport(tnl_vport));
 }
 
diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c
index ef9778f..67b68a3 100644
--- a/datapath/vport-patch.c
+++ b/datapath/vport-patch.c
@@ -185,9 +185,9 @@ error:
 static void free_port_rcu(struct rcu_head *rcu)
 {
 	struct patch_vport *patch_vport = container_of(rcu,
-						      struct patch_vport, rcu);
+					  struct patch_vport, rcu);
 
-	kfree(patch_vport->devconf);
+	kfree((struct device_config __force *)patch_vport->devconf);
 	vport_free(vport_from_priv(patch_vport));
 }
 
-- 
1.7.1





More information about the dev mailing list