On Tue, 2019-07-30 at 12:37 -0400, Willem de Bruijn wrote: > On Tue, Jul 30, 2019 at 12:16 PM Willem de Bruijn > <willemdebruijn.ker...@gmail.com> wrote: > > On Mon, Jul 29, 2019 at 7:50 PM Saeed Mahameed <sae...@mellanox.com > > > wrote: > > > From: Vlad Buslov <vla...@mellanox.com> > > > > > > In order to remove dependency on rtnl lock, access to tc flows > > > hashtable > > > must be explicitly protected from concurrent flows removal. > > > > > > Extend tc flow structure with rcu to allow concurrent parallel > > > access. Use > > > rcu read lock to safely lookup flow in tc flows hash table, and > > > take > > > reference to it. Use rcu free for flow deletion to accommodate > > > concurrent > > > stats requests. > > > > > > Add new DELETED flow flag. Imlement new flow_flag_test_and_set() > > > helper > > > that is used to set a flag and return its previous value. Use it > > > to > > > atomically set the flag in mlx5e_delete_flower() to guarantee > > > that flow can > > > only be deleted once, even when same flow is deleted concurrently > > > by > > > multiple tasks. > > > > > > Signed-off-by: Vlad Buslov <vla...@mellanox.com> > > > Reviewed-by: Jianbo Liu <jian...@mellanox.com> > > > Reviewed-by: Roi Dayan <r...@mellanox.com> > > > Signed-off-by: Saeed Mahameed <sae...@mellanox.com> > > > --- > > > @@ -3492,16 +3507,32 @@ int mlx5e_delete_flower(struct net_device > > > *dev, struct mlx5e_priv *priv, > > > { > > > struct rhashtable *tc_ht = get_tc_ht(priv, flags); > > > struct mlx5e_tc_flow *flow; > > > + int err; > > > > > > + rcu_read_lock(); > > > flow = rhashtable_lookup_fast(tc_ht, &f->cookie, > > > tc_ht_params); > > > - if (!flow || !same_flow_direction(flow, flags)) > > > - return -EINVAL; > > > + if (!flow || !same_flow_direction(flow, flags)) { > > > + err = -EINVAL; > > > + goto errout; > > > + } > > > > > > + /* Only delete the flow if it doesn't have > > > MLX5E_TC_FLOW_DELETED flag > > > + * set. > > > + */ > > > + if (flow_flag_test_and_set(flow, DELETED)) { > > > + err = -EINVAL; > > > + goto errout; > > > + } > > > rhashtable_remove_fast(tc_ht, &flow->node, tc_ht_params); > > > + rcu_read_unlock(); > > > > > > mlx5e_flow_put(priv, flow); > > > > Dereferencing flow outside rcu readside critical section? Does a > > build > > with lockdep not complain? > > Eh no, it won't. The surprising part to me was to use a readside > critical section when performing a write action on an RCU ptr. The > DELETED flag ensures that multiple writers will not compete to call > rhashtable_remove_fast. rcu_read_lock is a common pattern to do > rhashtable lookup + delete. >
correct.