git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
datapath: Use RCU lock for flow dump operation.
[sliver-openvswitch.git]
/
datapath
/
datapath.c
diff --git
a/datapath/datapath.c
b/datapath/datapath.c
index
3680391
..
744a9a4
100644
(file)
--- 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;
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;
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;
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;
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;
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;
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) {
*/
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);
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;
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) {
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
if (!dp) {
-
ovs
_unlock();
+
rcu_read
_unlock();
return -ENODEV;
}
return -ENODEV;
}
- table = ovsl_dereference(dp->table);
-
+ table = rcu_dereference(dp->table);
for (;;) {
struct sw_flow *flow;
u32 bucket, obj;
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;
}
cb->args[0] = bucket;
cb->args[1] = obj;
}
-
ovs
_unlock();
+
rcu_read
_unlock();
return skb->len;
}
return skb->len;
}