]> www.infradead.org Git - users/hch/misc.git/commitdiff
net/mlx5: FS, Convert vport acls root namespaces to xarray
authorSaeed Mahameed <saeedm@nvidia.com>
Fri, 29 Aug 2025 22:37:16 +0000 (15:37 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 2 Sep 2025 13:18:16 +0000 (15:18 +0200)
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>
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h

index cb165085a4c10cfad575edd6fd84b0bec305676b..386acf248970e90cf39c138b545256a3d37b8cb2 100644 (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 mlx5_vport_acl_root_ns *vport_ns;
+
+       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
+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;
+
+       /* 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;
 
-       steering->esw_egress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL);
-       if (!steering->esw_egress_root_ns[vport])
+       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_egress_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;
 }
 
-static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering, int vport)
+int mlx5_fs_vport_egress_acl_ns_add(struct mlx5_flow_steering *steering,
+                                   u16 vport_idx)
 {
-       struct fs_prio *prio;
+       return mlx5_fs_add_vport_acl_root_ns(steering,
+                                            &steering->esw_egress_root_ns,
+                                            FS_FT_ESW_EGRESS_ACL, vport_idx);
+}
 
-       steering->esw_ingress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL);
-       if (!steering->esw_ingress_root_ns[vport])
-               return -ENOMEM;
+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);
+}
 
-       /* create 1 prio*/
-       prio = fs_create_prio(&steering->esw_ingress_root_ns[vport]->ns, 0, 1);
-       return PTR_ERR_OR_ZERO(prio);
+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)
index 500826229b0beb5573085b94fe28ce31e053a5db..a7642d9fc11851b4d4a1d2523dfce090d56a0a76 100644 (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);