After a mask is assigned to a flow, it will not change for the life of the flow. Since flow access is protected by RCU lock, access to flow->mask after getting a flow is always safe.
Suggested-by: Jesse Gross <je...@nicira.com> Reported-by: Ben Pfaff <b...@nicira.com> Signed-off-by: Andy Zhou <az...@nicira.com> ---- V1 - V2: remove cast from ovs_flow_free() --- datapath/datapath.c | 6 ++---- datapath/flow.c | 8 +++----- datapath/flow.h | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 9a3a07b..4330ce3 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1127,7 +1127,6 @@ 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; - struct sw_flow_mask *mask; struct nlattr *start; struct ovs_flow_stats stats; struct ovs_header *ovs_header; @@ -1157,8 +1156,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, if (!nla) goto nla_put_failure; - mask = rcu_dereference_check(flow->mask, lockdep_ovsl_is_held()); - err = ovs_flow_to_nlattrs(&flow->key, &mask->key, skb); + err = ovs_flow_to_nlattrs(&flow->key, &flow->mask->key, skb); if (err) goto error; @@ -1344,7 +1342,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) } ovs_sw_flow_mask_add_ref(mask_p); - rcu_assign_pointer(flow->mask, mask_p); + flow->mask = mask_p; rcu_assign_pointer(flow->sf_acts, acts); /* Put flow in bucket. */ diff --git a/datapath/flow.c b/datapath/flow.c index 95fea7f..c6a90b9 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -638,8 +638,7 @@ void ovs_flow_free(struct sw_flow *flow, bool deferred) if (!flow) return; - ovs_sw_flow_mask_del_ref((struct sw_flow_mask __force *)flow->mask, - deferred); + ovs_sw_flow_mask_del_ref(flow->mask, deferred); if (deferred) call_rcu(&flow->rcu, rcu_free_flow_callback); @@ -1073,9 +1072,8 @@ struct sw_flow *ovs_flow_lookup(struct flow_table *tbl, void ovs_flow_insert(struct flow_table *table, struct sw_flow *flow) { - flow->hash = ovs_flow_hash(&flow->key, - ovsl_dereference(flow->mask)->range.start, - ovsl_dereference(flow->mask)->range.end); + flow->hash = ovs_flow_hash(&flow->key, flow->mask->range.start, + flow->mask->range.end); __tbl_insert(table, flow); } diff --git a/datapath/flow.h b/datapath/flow.h index 1a3764e..59c7f6e 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -120,7 +120,7 @@ struct sw_flow { struct sw_flow_key key; struct sw_flow_key unmasked_key; - struct sw_flow_mask __rcu *mask; + struct sw_flow_mask *mask; struct sw_flow_actions __rcu *sf_acts; spinlock_t lock; /* Lock for values below. */ -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev