datapath: Add casts for direct freeing of RCU data.
authorJesse Gross <jesse@nicira.com>
Fri, 24 Dec 2010 00:44:22 +0000 (16:44 -0800)
committerJesse Gross <jesse@nicira.com>
Wed, 29 Dec 2010 18:31:11 +0000 (10:31 -0800)
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 lifetime of the first level always exceeds that
of the second level.  This means that we can 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 no 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@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
datapath/flow.c
datapath/tunnel.c
datapath/vport-patch.c

index 5cf0d54a7839860519c9f7337e1890f220c8db95..b33b31559f77995a738e821bfb4b447a7b009c48 100644 (file)
@@ -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);
        }
 }
index ee9e45d31a750586cb9ea2621c8529a6a1cbe271..d49d928cc42db5318622a6a361836cfafd00cc41 100644 (file)
@@ -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));
 }
 
index ef9778f3c5e1aede4aff6a93f1b9ea01495cfb5f..67b68a367757ed8758b21ffb24c25d3acf7503a7 100644 (file)
@@ -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));
 }