[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