Commit 0234362d authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-mlx5-hws-optimize-matchers-icm-usage'

Mark Bloch says:

====================
net/mlx5: HWS, Optimize matchers ICM usage

This series optimizes ICM usage for unidirectional rules and
empty matchers and with the last patch we make hardware steering
the default FDB steering provider for NICs that don't support software
steering.

Hardware steering (HWS) uses a type of rule table container (RTC) that
is unidirectional, so matchers consist of two RTCs to accommodate
bidirectional rules.

This small series enables resizing the two RTCs independently by
tracking the number of rules separately. For extreme cases where all
rules are unidirectional, this results in saving close to half the
memory footprint.

Results for inserting 1M unidirectional rules using a simple module:

			Pages		Memory
Before this patch:	300k		1.5GiB
After this patch:	160k		900MiB

The 'Pages' column measures the number of 4KiB pages the device requests
for itself (the ICM).

The 'Memory' column is the difference between peak usage and baseline
usage (before starting the test) as reported by `free -h`.

In addition, second to last patch of the series handles a case where all
the matcher's rules were deleted: the large RTCs of the matcher are no
longer required, and we can save some more ICM by shrinking the matcher
to its initial size.

Finally the last patch makes hardware steering the default mode
when in swichdev for NICs that don't have software steering support.
====================

Link: https://patch.msgid.link/20250703185431.445571-1-mbloch@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4b62261d a9aec713
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3919,6 +3919,8 @@ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev)

	if (mlx5_fs_dr_is_supported(dev))
		steering->mode = MLX5_FLOW_STEERING_MODE_SMFS;
	else if (mlx5_fs_hws_is_supported(dev))
		steering->mode = MLX5_FLOW_STEERING_MODE_HMFS;
	else
		steering->mode = MLX5_FLOW_STEERING_MODE_DMFS;

+2 −5
Original line number Diff line number Diff line
@@ -1358,12 +1358,9 @@ mlx5hws_action_create_modify_header(struct mlx5hws_context *ctx,
}

struct mlx5hws_action *
mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx,
				 size_t num_dest,
mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx, size_t num_dest,
				 struct mlx5hws_action_dest_attr *dests,
				 bool ignore_flow_level,
				 u32 flow_source,
				 u32 flags)
				 bool ignore_flow_level, u32 flags)
{
	struct mlx5hws_cmd_set_fte_dest *dest_list = NULL;
	struct mlx5hws_cmd_ft_create_attr ft_attr = {0};
+348 −181

File changed.

Preview size limit exceeded, changes collapsed.

+12 −3
Original line number Diff line number Diff line
@@ -19,6 +19,13 @@
#define MLX5HWS_BWC_POLLING_TIMEOUT 60

struct mlx5hws_bwc_matcher_complex_data;

struct mlx5hws_bwc_matcher_size {
	u8 size_log;
	atomic_t num_of_rules;
	atomic_t rehash_required;
};

struct mlx5hws_bwc_matcher {
	struct mlx5hws_matcher *matcher;
	struct mlx5hws_match_template *mt;
@@ -27,10 +34,9 @@ struct mlx5hws_bwc_matcher {
	struct mlx5hws_bwc_matcher *complex_first_bwc_matcher;
	u8 num_of_at;
	u8 size_of_at_array;
	u8 size_log;
	u32 priority;
	atomic_t num_of_rules;
	atomic_t rehash_required;
	struct mlx5hws_bwc_matcher_size rx_size;
	struct mlx5hws_bwc_matcher_size tx_size;
	struct list_head *rules;
};

@@ -39,7 +45,10 @@ struct mlx5hws_bwc_rule {
	struct mlx5hws_rule *rule;
	struct mlx5hws_bwc_rule *isolated_bwc_rule;
	struct mlx5hws_bwc_complex_rule_hash_node *complex_hash_node;
	u32 flow_source;
	u16 bwc_queue_idx;
	bool skip_rx;
	bool skip_tx;
	struct list_head list_node;
};

+9 −11
Original line number Diff line number Diff line
@@ -99,17 +99,19 @@ hws_debug_dump_matcher_attr(struct seq_file *f, struct mlx5hws_matcher *matcher)
{
	struct mlx5hws_matcher_attr *attr = &matcher->attr;

	seq_printf(f, "%d,0x%llx,%d,%d,%d,%d,%d,%d,%d,%d\n",
	seq_printf(f, "%d,0x%llx,%d,%d,%d,%d,%d,%d,%d,%d,-1,-1,%d,%d\n",
		   MLX5HWS_DEBUG_RES_TYPE_MATCHER_ATTR,
		   HWS_PTR_TO_ID(matcher),
		   attr->priority,
		   attr->mode,
		   attr->table.sz_row_log,
		   attr->table.sz_col_log,
		   attr->size[MLX5HWS_MATCHER_SIZE_TYPE_RX].table.sz_row_log,
		   attr->size[MLX5HWS_MATCHER_SIZE_TYPE_RX].table.sz_col_log,
		   attr->optimize_using_rule_idx,
		   attr->optimize_flow_src,
		   attr->insert_mode,
		   attr->distribute_mode);
		   attr->distribute_mode,
		   attr->size[MLX5HWS_MATCHER_SIZE_TYPE_TX].table.sz_row_log,
		   attr->size[MLX5HWS_MATCHER_SIZE_TYPE_TX].table.sz_col_log);

	return 0;
}
@@ -118,7 +120,6 @@ static int hws_debug_dump_matcher(struct seq_file *f, struct mlx5hws_matcher *ma
{
	enum mlx5hws_table_type tbl_type = matcher->tbl->type;
	struct mlx5hws_cmd_ft_query_attr ft_attr = {0};
	struct mlx5hws_pool *ste_pool;
	u64 icm_addr_0 = 0;
	u64 icm_addr_1 = 0;
	u32 ste_0_id = -1;
@@ -133,12 +134,9 @@ static int hws_debug_dump_matcher(struct seq_file *f, struct mlx5hws_matcher *ma
		   matcher->end_ft_id,
		   matcher->col_matcher ? HWS_PTR_TO_ID(matcher->col_matcher) : 0);

	ste_pool = matcher->match_ste.pool;
	if (ste_pool) {
		ste_0_id = mlx5hws_pool_get_base_id(ste_pool);
	ste_0_id = matcher->match_ste.ste_0_base;
	if (tbl_type == MLX5HWS_TABLE_TYPE_FDB)
			ste_1_id = mlx5hws_pool_get_base_mirror_id(ste_pool);
	}
		ste_1_id = matcher->match_ste.ste_1_base;

	seq_printf(f, ",%d,%d,%d,%d",
		   matcher->match_ste.rtc_0_id,
Loading