Commit 7b0f62ee authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

mlxsw: spectrum_acl: Don't take rtnl lock during vregion_rehash_intrvl_set()

Relax dependency on rtnl mutex during vregion_rehash_intrvl_set(). The
vregion list is protected with newly introduced mutex.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ddaa2875
...@@ -38,6 +38,7 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, ...@@ -38,6 +38,7 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
size_t alloc_size; size_t alloc_size;
int err; int err;
mutex_init(&tcam->lock);
tcam->vregion_rehash_intrvl = tcam->vregion_rehash_intrvl =
MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT; MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT;
INIT_LIST_HEAD(&tcam->vregion_list); INIT_LIST_HEAD(&tcam->vregion_list);
...@@ -85,6 +86,7 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, ...@@ -85,6 +86,7 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
{ {
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops; const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
mutex_destroy(&tcam->lock);
ops->fini(mlxsw_sp, tcam->priv); ops->fini(mlxsw_sp, tcam->priv);
kfree(tcam->used_groups); kfree(tcam->used_groups);
kfree(tcam->used_regions); kfree(tcam->used_regions);
...@@ -784,7 +786,9 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp, ...@@ -784,7 +786,9 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
INIT_DELAYED_WORK(&vregion->rehash_dw, INIT_DELAYED_WORK(&vregion->rehash_dw,
mlxsw_sp_acl_tcam_vregion_rehash_work); mlxsw_sp_acl_tcam_vregion_rehash_work);
mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion); mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion);
mutex_lock(&tcam->lock);
list_add_tail(&vregion->tlist, &tcam->vregion_list); list_add_tail(&vregion->tlist, &tcam->vregion_list);
mutex_unlock(&tcam->lock);
} }
return vregion; return vregion;
...@@ -804,9 +808,12 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp, ...@@ -804,9 +808,12 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
{ {
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops; const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
struct mlxsw_sp_acl_tcam_vgroup *vgroup = vregion->vgroup; struct mlxsw_sp_acl_tcam_vgroup *vgroup = vregion->vgroup;
struct mlxsw_sp_acl_tcam *tcam = vregion->tcam;
if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) { if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) {
mutex_lock(&tcam->lock);
list_del(&vregion->tlist); list_del(&vregion->tlist);
mutex_unlock(&tcam->lock);
cancel_delayed_work_sync(&vregion->rehash_dw); cancel_delayed_work_sync(&vregion->rehash_dw);
} }
mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion); mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
...@@ -842,14 +849,14 @@ int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, ...@@ -842,14 +849,14 @@ int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
if (WARN_ON(!ops->region_rehash_hints_get)) if (WARN_ON(!ops->region_rehash_hints_get))
return -EOPNOTSUPP; return -EOPNOTSUPP;
tcam->vregion_rehash_intrvl = val; tcam->vregion_rehash_intrvl = val;
rtnl_lock(); mutex_lock(&tcam->lock);
list_for_each_entry(vregion, &tcam->vregion_list, tlist) { list_for_each_entry(vregion, &tcam->vregion_list, tlist) {
if (val) if (val)
mlxsw_core_schedule_dw(&vregion->rehash_dw, 0); mlxsw_core_schedule_dw(&vregion->rehash_dw, 0);
else else
cancel_delayed_work_sync(&vregion->rehash_dw); cancel_delayed_work_sync(&vregion->rehash_dw);
} }
rtnl_unlock(); mutex_unlock(&tcam->lock);
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ struct mlxsw_sp_acl_tcam { ...@@ -17,6 +17,7 @@ struct mlxsw_sp_acl_tcam {
unsigned long *used_groups; /* bit array */ unsigned long *used_groups; /* bit array */
unsigned int max_groups; unsigned int max_groups;
unsigned int max_group_size; unsigned int max_group_size;
struct mutex lock; /* guards vregion list */
struct list_head vregion_list; struct list_head vregion_list;
u32 vregion_rehash_intrvl; /* ms */ u32 vregion_rehash_intrvl; /* ms */
unsigned long priv[0]; unsigned long priv[0];
......
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