1
0

net/mlx5: FS, Convert vport acls root namespaces to xarray

Before this patch it was a linear array and could only support a certain
number of vports, in the next patches, vport numbers are not bound to a
well known limit, thus convert acl root name space storage to xarray.

In addition create fs_core public API to add/remove vport acl namespaces
as it is the eswitch responsibility to create the vports and their
root name spaces for acls, in the next patch we will move
mlx5_fs_ingress_acls_{init,cleanup} to eswitch and will use
the individual mlx5_fs_vport_{egress,ingresS}_acl_ns_{add,remove}
APIs for dynamically create vports.

Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250829223722.900629-2-saeed@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Saeed Mahameed
2025-08-29 15:37:16 -07:00
committed by Paolo Abeni
parent 48195dd18f
commit 2e894b99c0
2 changed files with 124 additions and 60 deletions

View File

@@ -2793,30 +2793,32 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
}
EXPORT_SYMBOL(mlx5_get_flow_namespace);
struct mlx5_vport_acl_root_ns {
u16 vport_idx;
struct mlx5_flow_root_namespace *root_ns;
};
struct mlx5_flow_namespace *
mlx5_get_flow_vport_namespace(struct mlx5_core_dev *dev,
enum mlx5_flow_namespace_type type, int vport_idx)
{
struct mlx5_flow_steering *steering = dev->priv.steering;
struct mlx5_vport_acl_root_ns *vport_ns;
if (!steering)
return NULL;
switch (type) {
case MLX5_FLOW_NAMESPACE_ESW_EGRESS:
if (vport_idx >= steering->esw_egress_acl_vports)
return NULL;
if (steering->esw_egress_root_ns &&
steering->esw_egress_root_ns[vport_idx])
return &steering->esw_egress_root_ns[vport_idx]->ns;
vport_ns = xa_load(&steering->esw_egress_root_ns, vport_idx);
if (vport_ns)
return &vport_ns->root_ns->ns;
else
return NULL;
case MLX5_FLOW_NAMESPACE_ESW_INGRESS:
if (vport_idx >= steering->esw_ingress_acl_vports)
return NULL;
if (steering->esw_ingress_root_ns &&
steering->esw_ingress_root_ns[vport_idx])
return &steering->esw_ingress_root_ns[vport_idx]->ns;
vport_ns = xa_load(&steering->esw_ingress_root_ns, vport_idx);
if (vport_ns)
return &vport_ns->root_ns->ns;
else
return NULL;
case MLX5_FLOW_NAMESPACE_RDMA_TRANSPORT_RX:
@@ -3575,30 +3577,102 @@ out_err:
return err;
}
static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering, int vport)
static void
mlx5_fs_remove_vport_acl_root_ns(struct xarray *esw_acl_root_ns, u16 vport_idx)
{
struct fs_prio *prio;
struct mlx5_vport_acl_root_ns *vport_ns;
steering->esw_egress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL);
if (!steering->esw_egress_root_ns[vport])
return -ENOMEM;
/* create 1 prio*/
prio = fs_create_prio(&steering->esw_egress_root_ns[vport]->ns, 0, 1);
return PTR_ERR_OR_ZERO(prio);
vport_ns = xa_erase(esw_acl_root_ns, vport_idx);
if (vport_ns) {
cleanup_root_ns(vport_ns->root_ns);
kfree(vport_ns);
}
}
static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering, int vport)
static int
mlx5_fs_add_vport_acl_root_ns(struct mlx5_flow_steering *steering,
struct xarray *esw_acl_root_ns,
enum fs_flow_table_type table_type,
u16 vport_idx)
{
struct mlx5_vport_acl_root_ns *vport_ns;
struct fs_prio *prio;
int err;
steering->esw_ingress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL);
if (!steering->esw_ingress_root_ns[vport])
/* sanity check, intended xarrays are used */
if (WARN_ON(esw_acl_root_ns != &steering->esw_egress_root_ns &&
esw_acl_root_ns != &steering->esw_ingress_root_ns))
return -EINVAL;
if (table_type != FS_FT_ESW_EGRESS_ACL &&
table_type != FS_FT_ESW_INGRESS_ACL) {
mlx5_core_err(steering->dev,
"Invalid table type %d for egress/ingress ACLs\n",
table_type);
return -EINVAL;
}
if (xa_load(esw_acl_root_ns, vport_idx))
return -EEXIST;
vport_ns = kzalloc(sizeof(*vport_ns), GFP_KERNEL);
if (!vport_ns)
return -ENOMEM;
vport_ns->root_ns = create_root_ns(steering, table_type);
if (!vport_ns->root_ns) {
err = -ENOMEM;
goto kfree_vport_ns;
}
/* create 1 prio*/
prio = fs_create_prio(&steering->esw_ingress_root_ns[vport]->ns, 0, 1);
return PTR_ERR_OR_ZERO(prio);
prio = fs_create_prio(&vport_ns->root_ns->ns, 0, 1);
if (IS_ERR(prio)) {
err = PTR_ERR(prio);
goto cleanup_root_ns;
}
vport_ns->vport_idx = vport_idx;
err = xa_insert(esw_acl_root_ns, vport_idx, vport_ns, GFP_KERNEL);
if (err)
goto cleanup_root_ns;
return 0;
cleanup_root_ns:
cleanup_root_ns(vport_ns->root_ns);
kfree_vport_ns:
kfree(vport_ns);
return err;
}
int mlx5_fs_vport_egress_acl_ns_add(struct mlx5_flow_steering *steering,
u16 vport_idx)
{
return mlx5_fs_add_vport_acl_root_ns(steering,
&steering->esw_egress_root_ns,
FS_FT_ESW_EGRESS_ACL, vport_idx);
}
int mlx5_fs_vport_ingress_acl_ns_add(struct mlx5_flow_steering *steering,
u16 vport_idx)
{
return mlx5_fs_add_vport_acl_root_ns(steering,
&steering->esw_ingress_root_ns,
FS_FT_ESW_INGRESS_ACL, vport_idx);
}
void mlx5_fs_vport_egress_acl_ns_remove(struct mlx5_flow_steering *steering,
int vport_idx)
{
mlx5_fs_remove_vport_acl_root_ns(&steering->esw_egress_root_ns,
vport_idx);
}
void mlx5_fs_vport_ingress_acl_ns_remove(struct mlx5_flow_steering *steering,
int vport_idx)
{
mlx5_fs_remove_vport_acl_root_ns(&steering->esw_ingress_root_ns,
vport_idx);
}
int mlx5_fs_egress_acls_init(struct mlx5_core_dev *dev, int total_vports)
@@ -3607,15 +3681,10 @@ int mlx5_fs_egress_acls_init(struct mlx5_core_dev *dev, int total_vports)
int err;
int i;
steering->esw_egress_root_ns =
kcalloc(total_vports,
sizeof(*steering->esw_egress_root_ns),
GFP_KERNEL);
if (!steering->esw_egress_root_ns)
return -ENOMEM;
xa_init(&steering->esw_egress_root_ns);
for (i = 0; i < total_vports; i++) {
err = init_egress_acl_root_ns(steering, i);
err = mlx5_fs_vport_egress_acl_ns_add(steering, i);
if (err)
goto cleanup_root_ns;
}
@@ -3623,10 +3692,9 @@ int mlx5_fs_egress_acls_init(struct mlx5_core_dev *dev, int total_vports)
return 0;
cleanup_root_ns:
for (i--; i >= 0; i--)
cleanup_root_ns(steering->esw_egress_root_ns[i]);
kfree(steering->esw_egress_root_ns);
steering->esw_egress_root_ns = NULL;
while (i--)
mlx5_fs_vport_egress_acl_ns_remove(steering, i);
xa_destroy(&steering->esw_egress_root_ns);
return err;
}
@@ -3635,14 +3703,10 @@ void mlx5_fs_egress_acls_cleanup(struct mlx5_core_dev *dev)
struct mlx5_flow_steering *steering = dev->priv.steering;
int i;
if (!steering->esw_egress_root_ns)
return;
for (i = 0; i < steering->esw_egress_acl_vports; i++)
cleanup_root_ns(steering->esw_egress_root_ns[i]);
mlx5_fs_vport_egress_acl_ns_remove(steering, i);
kfree(steering->esw_egress_root_ns);
steering->esw_egress_root_ns = NULL;
xa_destroy(&steering->esw_egress_root_ns);
}
int mlx5_fs_ingress_acls_init(struct mlx5_core_dev *dev, int total_vports)
@@ -3651,15 +3715,10 @@ int mlx5_fs_ingress_acls_init(struct mlx5_core_dev *dev, int total_vports)
int err;
int i;
steering->esw_ingress_root_ns =
kcalloc(total_vports,
sizeof(*steering->esw_ingress_root_ns),
GFP_KERNEL);
if (!steering->esw_ingress_root_ns)
return -ENOMEM;
xa_init(&steering->esw_ingress_root_ns);
for (i = 0; i < total_vports; i++) {
err = init_ingress_acl_root_ns(steering, i);
err = mlx5_fs_vport_ingress_acl_ns_add(steering, i);
if (err)
goto cleanup_root_ns;
}
@@ -3667,10 +3726,10 @@ int mlx5_fs_ingress_acls_init(struct mlx5_core_dev *dev, int total_vports)
return 0;
cleanup_root_ns:
for (i--; i >= 0; i--)
cleanup_root_ns(steering->esw_ingress_root_ns[i]);
kfree(steering->esw_ingress_root_ns);
steering->esw_ingress_root_ns = NULL;
while (i--)
mlx5_fs_vport_ingress_acl_ns_remove(steering, i);
xa_destroy(&steering->esw_ingress_root_ns);
return err;
}
@@ -3679,14 +3738,10 @@ void mlx5_fs_ingress_acls_cleanup(struct mlx5_core_dev *dev)
struct mlx5_flow_steering *steering = dev->priv.steering;
int i;
if (!steering->esw_ingress_root_ns)
return;
for (i = 0; i < steering->esw_ingress_acl_vports; i++)
cleanup_root_ns(steering->esw_ingress_root_ns[i]);
mlx5_fs_vport_ingress_acl_ns_remove(steering, i);
kfree(steering->esw_ingress_root_ns);
steering->esw_ingress_root_ns = NULL;
xa_destroy(&steering->esw_ingress_root_ns);
}
u32 mlx5_fs_get_capabilities(struct mlx5_core_dev *dev, enum mlx5_flow_namespace_type type)

View File

@@ -151,8 +151,8 @@ struct mlx5_flow_steering {
struct mlx5_flow_root_namespace *root_ns;
struct mlx5_flow_root_namespace *fdb_root_ns;
struct mlx5_flow_namespace **fdb_sub_ns;
struct mlx5_flow_root_namespace **esw_egress_root_ns;
struct mlx5_flow_root_namespace **esw_ingress_root_ns;
struct xarray esw_egress_root_ns;
struct xarray esw_ingress_root_ns;
struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
struct mlx5_flow_root_namespace *sniffer_rx_root_ns;
struct mlx5_flow_root_namespace *rdma_rx_root_ns;
@@ -383,6 +383,15 @@ void mlx5_fs_egress_acls_cleanup(struct mlx5_core_dev *dev);
int mlx5_fs_ingress_acls_init(struct mlx5_core_dev *dev, int total_vports);
void mlx5_fs_ingress_acls_cleanup(struct mlx5_core_dev *dev);
int mlx5_fs_vport_egress_acl_ns_add(struct mlx5_flow_steering *steering,
u16 vport_idx);
int mlx5_fs_vport_ingress_acl_ns_add(struct mlx5_flow_steering *steering,
u16 vport_idx);
void mlx5_fs_vport_egress_acl_ns_remove(struct mlx5_flow_steering *steering,
int vport_idx);
void mlx5_fs_vport_ingress_acl_ns_remove(struct mlx5_flow_steering *steering,
int vport_idx);
u32 mlx5_fs_get_capabilities(struct mlx5_core_dev *dev, enum mlx5_flow_namespace_type type);
struct mlx5_flow_root_namespace *find_root(struct fs_node *node);