[ovs-dev] [PATCH v2 10/13] datapath: Store alloced size with sw_flow_acts.

Jarno Rajahalme jrajahalme at nicira.com
Wed Feb 12 00:07:21 UTC 2014


This helps reduce calls to ksize().

Also add support for statically alloced actions, which will be used by
a subsequent patch.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 datapath/datapath.c     |    2 +-
 datapath/flow.h         |    2 ++
 datapath/flow_netlink.c |   20 +++++++++++++++-----
 datapath/flow_netlink.h |    2 +-
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 1599d70..a46ceb0 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -882,7 +882,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 		/* Update actions. */
 		old_acts = ovsl_dereference(flow->sf_acts);
 		rcu_assign_pointer(flow->sf_acts, acts);
-		ovs_nla_free_flow_actions(old_acts);
+		ovs_nla_free_flow_actions(old_acts, true);
 
 		/* Clear stats. */
 		if (a[OVS_FLOW_ATTR_CLEAR])
diff --git a/datapath/flow.h b/datapath/flow.h
index f6cce35..441fdee 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -146,6 +146,8 @@ struct sw_flow_match {
 struct sw_flow_actions {
 	struct rcu_head rcu;
 	u32 actions_len;
+	u32 alloc_size;
+	bool alloced;
 	struct nlattr actions[];
 };
 
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 3024a61..5bcf258 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1127,6 +1127,9 @@ struct sw_flow_actions *ovs_nla_alloc_flow_actions(int size)
 		return ERR_PTR(-ENOMEM);
 
 	sfa->actions_len = 0;
+	sfa->alloc_size = ksize(sfa);
+	sfa->alloced = true;
+
 	return sfa;
 }
 
@@ -1140,11 +1143,17 @@ static void rcu_free_acts_callback(struct rcu_head *rcu)
 
 /* Schedules 'sf_acts' to be freed after the next RCU grace period.
  * The caller must hold rcu_read_lock for this to be sensible. */
-void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
+void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts, bool deferred)
 {
-	call_rcu(&sf_acts->rcu, rcu_free_acts_callback);
+	if (sf_acts->alloced) {
+		if (deferred)
+			call_rcu(&sf_acts->rcu, rcu_free_acts_callback);
+		else
+			kfree(sf_acts);
+	}
 }
 
+/* May only be called before actions are placed in to the flow table. */
 static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
 				       int attr_len)
 {
@@ -1155,10 +1164,10 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
 	int next_offset = offsetof(struct sw_flow_actions, actions) +
 					(*sfa)->actions_len;
 
-	if (req_size <= (ksize(*sfa) - next_offset))
+	if (req_size <= ((*sfa)->alloc_size - next_offset))
 		goto out;
 
-	new_acts_size = ksize(*sfa) * 2;
+	new_acts_size = (*sfa)->alloc_size * 2;
 
 	if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
 		if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size)
@@ -1172,7 +1181,8 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
 
 	memcpy(acts->actions, (*sfa)->actions, (*sfa)->actions_len);
 	acts->actions_len = (*sfa)->actions_len;
-	kfree(*sfa);
+
+	ovs_nla_free_flow_actions(*sfa, false);
 	*sfa = acts;
 
 out:
diff --git a/datapath/flow_netlink.h b/datapath/flow_netlink.h
index 4401510..786f93f 100644
--- a/datapath/flow_netlink.h
+++ b/datapath/flow_netlink.h
@@ -55,6 +55,6 @@ int ovs_nla_put_actions(const struct nlattr *attr,
 			int len, struct sk_buff *skb);
 
 struct sw_flow_actions *ovs_nla_alloc_flow_actions(int actions_len);
-void ovs_nla_free_flow_actions(struct sw_flow_actions *);
+void ovs_nla_free_flow_actions(struct sw_flow_actions *, bool deferred);
 
 #endif /* flow_netlink.h */
-- 
1.7.10.4




More information about the dev mailing list