From 39872c70e2feefb85e3d7aa577d281d20c8decf6 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 23 Dec 2010 16:44:22 -0800 Subject: [PATCH] datapath: Add casts for direct freeing of RCU data. 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 Acked-by: Ben Pfaff --- 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 5cf0d54a..b33b3155 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 ee9e45d3..d49d928c 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 ef9778f3..67b68a36 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)); } -- 2.30.2