git: 67a9c8868af3 - stable/14 - net/mlx5: Allow creating autogroups with reserved entries

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 22 Nov 2023 01:51:57 UTC
The branch stable/14 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=67a9c8868af371f3e0b96a18d1f9d54fd2be4b1a

commit 67a9c8868af371f3e0b96a18d1f9d54fd2be4b1a
Author:     Mark Bloch <mbloch@nvidia.com>
AuthorDate: 2023-02-19 14:16:43 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-11-22 01:40:28 +0000

    net/mlx5: Allow creating autogroups with reserved entries
    
    (cherry picked from commit 0a5db6bb3a953bd22f53f3607ae6853487548532)
---
 sys/dev/mlx5/fs.h                     |  3 ++-
 sys/dev/mlx5/mlx5_core/fs_core.h      |  1 +
 sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c | 22 +++++++++++++++++-----
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/sys/dev/mlx5/fs.h b/sys/dev/mlx5/fs.h
index da1a469d333c..d61a2bb498b7 100644
--- a/sys/dev/mlx5/fs.h
+++ b/sys/dev/mlx5/fs.h
@@ -140,7 +140,8 @@ mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
 				    int prio,
 				    const char *name,
 				    int num_flow_table_entries,
-				    int max_num_groups);
+				    int max_num_groups,
+				    int num_reserved_entries);
 
 struct mlx5_flow_table *
 mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
diff --git a/sys/dev/mlx5/mlx5_core/fs_core.h b/sys/dev/mlx5/mlx5_core/fs_core.h
index dc619fc2d2db..a9273fdab61c 100644
--- a/sys/dev/mlx5/mlx5_core/fs_core.h
+++ b/sys/dev/mlx5/mlx5_core/fs_core.h
@@ -99,6 +99,7 @@ struct mlx5_flow_table {
 		unsigned int		max_types;
 		unsigned int		group_size;
 		unsigned int		num_types;
+		unsigned int		max_fte;
 	} autogroup;
 	unsigned int			max_fte;
 	unsigned int			level;
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
index b59373d48730..dcf93e5fc892 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
@@ -892,12 +892,18 @@ struct mlx5_flow_table *mlx5_create_auto_grouped_flow_table(struct mlx5_flow_nam
 							   int prio,
 							   const char *name,
 							   int num_flow_table_entries,
-							   int max_num_groups)
+							   int max_num_groups,
+							   int num_reserved_entries)
 {
 	struct mlx5_flow_table *ft = NULL;
 	struct fs_prio *fs_prio;
 	bool is_shared_prio;
 
+	if (max_num_groups > (num_flow_table_entries - num_reserved_entries))
+		return ERR_PTR(-EINVAL);
+	if (num_reserved_entries > num_flow_table_entries)
+		return ERR_PTR(-EINVAL);
+
 	fs_prio = find_prio(ns, prio);
 	if (!fs_prio)
 		return ERR_PTR(-EINVAL);
@@ -918,8 +924,9 @@ struct mlx5_flow_table *mlx5_create_auto_grouped_flow_table(struct mlx5_flow_nam
 
 	ft->autogroup.active = true;
 	ft->autogroup.max_types = max_num_groups;
+	ft->autogroup.max_fte = num_flow_table_entries - num_reserved_entries;
 	/* We save place for flow groups in addition to max types */
-	ft->autogroup.group_size = ft->max_fte / (max_num_groups + 1);
+	ft->autogroup.group_size = ft->autogroup.max_fte / (max_num_groups + 1);
 
 	if (is_shared_prio)
 		ft->shared_refcount = 1;
@@ -1109,11 +1116,13 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
 {
 	struct mlx5_flow_group *fg;
 	struct mlx5_core_dev *dev = fs_get_dev(&ft->base);
+	unsigned int start_index;
 
+	start_index = MLX5_GET(create_flow_group_in, in, start_flow_index);
 	if (!dev)
 		return ERR_PTR(-ENODEV);
 
-	if (ft->autogroup.active)
+	if (ft->autogroup.active && start_index < ft->autogroup.max_fte)
 		return ERR_PTR(-EPERM);
 
 	fg = fs_create_fg(dev, ft, ft->fgs.prev, in, 1);
@@ -1132,7 +1141,9 @@ static void fs_del_fg(struct mlx5_flow_group *fg)
 	dev = fs_get_dev(&parent_ft->base);
 	WARN_ON(!dev);
 
-	if (parent_ft->autogroup.active && fg->max_ftes == parent_ft->autogroup.group_size)
+	if (parent_ft->autogroup.active &&
+	    fg->max_ftes == parent_ft->autogroup.group_size &&
+	    fg->start_index < parent_ft->autogroup.max_fte)
 		parent_ft->autogroup.num_types--;
 
 	if (mlx5_cmd_fs_destroy_fg(dev, parent_ft->vport,
@@ -1423,6 +1434,7 @@ static struct mlx5_flow_group *create_autogroup(struct mlx5_flow_table *ft,
 	u32 *in;
 	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
 	void *match_criteria_addr;
+	u32 max_fte = ft->autogroup.max_fte;
 
 	if (!ft->autogroup.active)
 		return ERR_PTR(-ENOENT);
@@ -1459,7 +1471,7 @@ static struct mlx5_flow_group *create_autogroup(struct mlx5_flow_table *ft,
 		prev = &g->base.list;
 	}
 
-	if (candidate_index + group_size > ft->max_fte) {
+	if (candidate_index + group_size > max_fte) {
 		ret = ERR_PTR(-ENOSPC);
 		goto out;
 	}