Commit ad86755b authored by Vlad Buslov's avatar Vlad Buslov Committed by Saeed Mahameed

net/mlx5e: Protect unready flows with dedicated lock

In order to remove dependency on rtnl lock for protecting unready_flows
list when reoffloading unready flows on workqueue, extend representor
uplink private structure with dedicated 'unready_flows_lock' mutex. Take
the lock in all users of unready_flows list before accessing it. Implement
helper functions to add and delete unready flow.
Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Reviewed-by: default avatarJianbo Liu <jianbol@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent c5d326b2
...@@ -1560,6 +1560,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) ...@@ -1560,6 +1560,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
if (rpriv->rep->vport == MLX5_VPORT_UPLINK) { if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
uplink_priv = &rpriv->uplink_priv; uplink_priv = &rpriv->uplink_priv;
mutex_init(&uplink_priv->unready_flows_lock);
INIT_LIST_HEAD(&uplink_priv->unready_flows); INIT_LIST_HEAD(&uplink_priv->unready_flows);
/* init shared tc flow table */ /* init shared tc flow table */
...@@ -1604,6 +1605,7 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv) ...@@ -1604,6 +1605,7 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
/* delete shared tc flow table */ /* delete shared tc flow table */
mlx5e_tc_esw_cleanup(&rpriv->uplink_priv.tc_ht); mlx5e_tc_esw_cleanup(&rpriv->uplink_priv.tc_ht);
mutex_destroy(&rpriv->uplink_priv.unready_flows_lock);
} }
} }
......
...@@ -75,6 +75,8 @@ struct mlx5_rep_uplink_priv { ...@@ -75,6 +75,8 @@ struct mlx5_rep_uplink_priv {
struct mlx5_tun_entropy tun_entropy; struct mlx5_tun_entropy tun_entropy;
/* protects unready_flows */
struct mutex unready_flows_lock;
struct list_head unready_flows; struct list_head unready_flows;
struct work_struct reoffload_flows_work; struct work_struct reoffload_flows_work;
}; };
......
...@@ -996,6 +996,25 @@ mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw, ...@@ -996,6 +996,25 @@ mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
flow_flag_clear(flow, SLOW); flow_flag_clear(flow, SLOW);
} }
/* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this
* function.
*/
static void unready_flow_add(struct mlx5e_tc_flow *flow,
struct list_head *unready_flows)
{
flow_flag_set(flow, NOT_READY);
list_add_tail(&flow->unready, unready_flows);
}
/* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this
* function.
*/
static void unready_flow_del(struct mlx5e_tc_flow *flow)
{
list_del(&flow->unready);
flow_flag_clear(flow, NOT_READY);
}
static void add_unready_flow(struct mlx5e_tc_flow *flow) static void add_unready_flow(struct mlx5e_tc_flow *flow)
{ {
struct mlx5_rep_uplink_priv *uplink_priv; struct mlx5_rep_uplink_priv *uplink_priv;
...@@ -1006,14 +1025,24 @@ static void add_unready_flow(struct mlx5e_tc_flow *flow) ...@@ -1006,14 +1025,24 @@ static void add_unready_flow(struct mlx5e_tc_flow *flow)
rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
uplink_priv = &rpriv->uplink_priv; uplink_priv = &rpriv->uplink_priv;
flow_flag_set(flow, NOT_READY); mutex_lock(&uplink_priv->unready_flows_lock);
list_add_tail(&flow->unready, &uplink_priv->unready_flows); unready_flow_add(flow, &uplink_priv->unready_flows);
mutex_unlock(&uplink_priv->unready_flows_lock);
} }
static void remove_unready_flow(struct mlx5e_tc_flow *flow) static void remove_unready_flow(struct mlx5e_tc_flow *flow)
{ {
list_del(&flow->unready); struct mlx5_rep_uplink_priv *uplink_priv;
flow_flag_clear(flow, NOT_READY); struct mlx5e_rep_priv *rpriv;
struct mlx5_eswitch *esw;
esw = flow->priv->mdev->priv.eswitch;
rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
uplink_priv = &rpriv->uplink_priv;
mutex_lock(&uplink_priv->unready_flows_lock);
unready_flow_del(flow);
mutex_unlock(&uplink_priv->unready_flows_lock);
} }
static int static int
...@@ -3723,10 +3752,10 @@ void mlx5e_tc_reoffload_flows_work(struct work_struct *work) ...@@ -3723,10 +3752,10 @@ void mlx5e_tc_reoffload_flows_work(struct work_struct *work)
reoffload_flows_work); reoffload_flows_work);
struct mlx5e_tc_flow *flow, *tmp; struct mlx5e_tc_flow *flow, *tmp;
rtnl_lock(); mutex_lock(&rpriv->unready_flows_lock);
list_for_each_entry_safe(flow, tmp, &rpriv->unready_flows, unready) { list_for_each_entry_safe(flow, tmp, &rpriv->unready_flows, unready) {
if (!mlx5e_tc_add_fdb_flow(flow->priv, flow, NULL)) if (!mlx5e_tc_add_fdb_flow(flow->priv, flow, NULL))
remove_unready_flow(flow); unready_flow_del(flow);
} }
rtnl_unlock(); mutex_unlock(&rpriv->unready_flows_lock);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment