Commit 0e18134f authored by Vlad Buslov's avatar Vlad Buslov Committed by Saeed Mahameed

net/mlx5e: Eswitch, use state_lock to synchronize vlan change

esw->state_lock is already used to protect vlan vport configuration change.
However, all preparation and correctness checks, and code that sets vport
data are not protected by this lock and assume external synchronization by
rtnl lock. In order to remove dependency on rtnl lock, extend
esw->state_lock protection to whole eswitch vlan add/del functions.
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 525e84be
...@@ -2086,23 +2086,19 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, ...@@ -2086,23 +2086,19 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
if (vlan > 4095 || qos > 7) if (vlan > 4095 || qos > 7)
return -EINVAL; return -EINVAL;
mutex_lock(&esw->state_lock);
err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags); err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
if (err) if (err)
goto unlock; return err;
evport->info.vlan = vlan; evport->info.vlan = vlan;
evport->info.qos = qos; evport->info.qos = qos;
if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY) { if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY) {
err = esw_vport_ingress_config(esw, evport); err = esw_vport_ingress_config(esw, evport);
if (err) if (err)
goto unlock; return err;
err = esw_vport_egress_config(esw, evport); err = esw_vport_egress_config(esw, evport);
} }
unlock:
mutex_unlock(&esw->state_lock);
return err; return err;
} }
...@@ -2110,11 +2106,16 @@ int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, ...@@ -2110,11 +2106,16 @@ int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
u16 vport, u16 vlan, u8 qos) u16 vport, u16 vlan, u8 qos)
{ {
u8 set_flags = 0; u8 set_flags = 0;
int err;
if (vlan || qos) if (vlan || qos)
set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT; set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT;
return __mlx5_eswitch_set_vport_vlan(esw, vport, vlan, qos, set_flags); mutex_lock(&esw->state_lock);
err = __mlx5_eswitch_set_vport_vlan(esw, vport, vlan, qos, set_flags);
mutex_unlock(&esw->state_lock);
return err;
} }
int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw,
......
...@@ -442,9 +442,11 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, ...@@ -442,9 +442,11 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
fwd = !!((attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && fwd = !!((attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) &&
!attr->dest_chain); !attr->dest_chain);
mutex_lock(&esw->state_lock);
err = esw_add_vlan_action_check(attr, push, pop, fwd); err = esw_add_vlan_action_check(attr, push, pop, fwd);
if (err) if (err)
return err; goto unlock;
attr->vlan_handled = false; attr->vlan_handled = false;
...@@ -457,11 +459,11 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, ...@@ -457,11 +459,11 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
attr->vlan_handled = true; attr->vlan_handled = true;
} }
return 0; goto unlock;
} }
if (!push && !pop) if (!push && !pop)
return 0; goto unlock;
if (!(offloads->vlan_push_pop_refcount)) { if (!(offloads->vlan_push_pop_refcount)) {
/* it's the 1st vlan rule, apply global vlan pop policy */ /* it's the 1st vlan rule, apply global vlan pop policy */
...@@ -486,6 +488,8 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, ...@@ -486,6 +488,8 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
out: out:
if (!err) if (!err)
attr->vlan_handled = true; attr->vlan_handled = true;
unlock:
mutex_unlock(&esw->state_lock);
return err; return err;
} }
...@@ -508,6 +512,8 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, ...@@ -508,6 +512,8 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
pop = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_POP); pop = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
fwd = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST); fwd = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST);
mutex_lock(&esw->state_lock);
vport = esw_vlan_action_get_vport(attr, push, pop); vport = esw_vlan_action_get_vport(attr, push, pop);
if (!push && !pop && fwd) { if (!push && !pop && fwd) {
...@@ -515,7 +521,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, ...@@ -515,7 +521,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
if (attr->dests[0].rep->vport == MLX5_VPORT_UPLINK) if (attr->dests[0].rep->vport == MLX5_VPORT_UPLINK)
vport->vlan_refcount--; vport->vlan_refcount--;
return 0; goto out;
} }
if (push) { if (push) {
...@@ -533,12 +539,13 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, ...@@ -533,12 +539,13 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
skip_unset_push: skip_unset_push:
offloads->vlan_push_pop_refcount--; offloads->vlan_push_pop_refcount--;
if (offloads->vlan_push_pop_refcount) if (offloads->vlan_push_pop_refcount)
return 0; goto out;
/* no more vlan rules, stop global vlan pop policy */ /* no more vlan rules, stop global vlan pop policy */
err = esw_set_global_vlan_pop(esw, 0); err = esw_set_global_vlan_pop(esw, 0);
out: out:
mutex_unlock(&esw->state_lock);
return err; return err;
} }
......
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