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 <jrajaha...@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

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to