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 <jesse@nicira.com>
Reported-by: Ben Pfaff <blp@nicira.com>
Signed-off-by: Andy Zhou <azhou@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
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;
- 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;
if (!nla)
goto nla_put_failure;
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);
}
ovs_sw_flow_mask_add_ref(mask_p);
}
ovs_sw_flow_mask_add_ref(mask_p);
- rcu_assign_pointer(flow->mask, mask_p);
rcu_assign_pointer(flow->sf_acts, acts);
/* Put flow in bucket. */
rcu_assign_pointer(flow->sf_acts, acts);
/* Put flow in bucket. */
- 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);
if (deferred)
call_rcu(&flow->rcu, rcu_free_flow_callback);
void ovs_flow_insert(struct flow_table *table, struct sw_flow *flow)
{
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);
}
__tbl_insert(table, flow);
}
struct sw_flow_key key;
struct sw_flow_key unmasked_key;
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. */
struct sw_flow_actions __rcu *sf_acts;
spinlock_t lock; /* Lock for values below. */