Flow dump operation is read-only operation.  There is no need to
take ovs-lock.  Following patch use rcu-lock for dumping flows.

Signed-off-by: Pravin B Shelar <[email protected]>
---
v1-v2:
 - Fix rcu annotations.
---
 datapath/datapath.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 3680391..744a9a4 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -1126,7 +1126,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, 
struct datapath *dp,
                                  u32 seq, u32 flags, u8 cmd)
 {
        const int skb_orig_len = skb->len;
-       const struct sw_flow_actions *sf_acts;
+       struct sw_flow_mask *mask;
        struct nlattr *start;
        struct ovs_flow_stats stats;
        struct ovs_header *ovs_header;
@@ -1135,8 +1135,6 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, 
struct datapath *dp,
        u8 tcp_flags;
        int err;
 
-       sf_acts = ovsl_dereference(flow->sf_acts);
-
        ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, 
cmd);
        if (!ovs_header)
                return -EMSGSIZE;
@@ -1158,8 +1156,8 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, 
struct datapath *dp,
        if (!nla)
                goto nla_put_failure;
 
-       err = ovs_flow_to_nlattrs(&flow->key,
-                       &ovsl_dereference(flow->mask)->key, skb);
+       mask = rcu_dereference_check(flow->mask, lockdep_ovsl_is_held());
+       err = ovs_flow_to_nlattrs(&flow->key, &mask->key, skb);
        if (err)
                goto error;
 
@@ -1197,6 +1195,11 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, 
struct datapath *dp,
         */
        start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
        if (start) {
+               const struct sw_flow_actions *sf_acts;
+
+               sf_acts = rcu_dereference_check(flow->sf_acts,
+                                               lockdep_ovsl_is_held());
+
                err = actions_to_attr(sf_acts->actions, sf_acts->actions_len, 
skb);
                if (!err)
                        nla_nest_end(skb, start);
@@ -1507,15 +1510,14 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, 
struct netlink_callback *cb)
        struct datapath *dp;
        struct flow_table *table;
 
-       ovs_lock();
+       rcu_read_lock();
        dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        if (!dp) {
-               ovs_unlock();
+               rcu_read_unlock();
                return -ENODEV;
        }
 
-       table = ovsl_dereference(dp->table);
-
+       table = rcu_dereference(dp->table);
        for (;;) {
                struct sw_flow *flow;
                u32 bucket, obj;
@@ -1535,7 +1537,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct 
netlink_callback *cb)
                cb->args[0] = bucket;
                cb->args[1] = obj;
        }
-       ovs_unlock();
+       rcu_read_unlock();
        return skb->len;
 }
 
-- 
1.7.1

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to