Commit 2533e726 authored by Yevgeny Kliteynik's avatar Yevgeny Kliteynik Committed by Saeed Mahameed
Browse files

net/mlx5: DR, Split chunk allocation to HW-dependent ways



This way we are able to allocate chunk for modify_headers from 2 types:
STEv0 that is allocated from the action area, and STEv1 that is allocating
the chunks from the special area for patterns.

Signed-off-by: default avatarMuhammad Sammar <muhammads@nvidia.com>
Signed-off-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarAlex Vesker <valex@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent da5d0027
Loading
Loading
Loading
Loading
+4 −18
Original line number Diff line number Diff line
@@ -1961,7 +1961,6 @@ static int dr_action_create_modify_action(struct mlx5dr_domain *dmn,
					  __be64 actions[],
					  struct mlx5dr_action *action)
{
	struct mlx5dr_icm_chunk *chunk;
	u32 max_hw_actions;
	u32 num_hw_actions;
	u32 num_sw_actions;
@@ -1978,15 +1977,9 @@ static int dr_action_create_modify_action(struct mlx5dr_domain *dmn,
		return -EINVAL;
	}

	chunk = mlx5dr_icm_alloc_chunk(dmn->action_icm_pool, DR_CHUNK_SIZE_16);
	if (!chunk)
		return -ENOMEM;

	hw_actions = kcalloc(1, max_hw_actions * DR_MODIFY_ACTION_SIZE, GFP_KERNEL);
	if (!hw_actions) {
		ret = -ENOMEM;
		goto free_chunk;
	}
	if (!hw_actions)
		return -ENOMEM;

	ret = dr_actions_convert_modify_header(action,
					       max_hw_actions,
@@ -1998,15 +1991,11 @@ static int dr_action_create_modify_action(struct mlx5dr_domain *dmn,
	if (ret)
		goto free_hw_actions;

	action->rewrite->chunk = chunk;
	action->rewrite->modify_ttl = modify_ttl;
	action->rewrite->data = (u8 *)hw_actions;
	action->rewrite->num_of_actions = num_hw_actions;
	action->rewrite->index = (mlx5dr_icm_pool_get_chunk_icm_addr(chunk) -
				  dmn->info.caps.hdr_modify_icm_addr) /
				  DR_ACTION_CACHE_LINE_SIZE;

	ret = mlx5dr_send_postsend_action(dmn, action);
	ret = mlx5dr_ste_alloc_modify_hdr(action);
	if (ret)
		goto free_hw_actions;

@@ -2014,8 +2003,6 @@ static int dr_action_create_modify_action(struct mlx5dr_domain *dmn,

free_hw_actions:
	kfree(hw_actions);
free_chunk:
	mlx5dr_icm_free_chunk(chunk);
	return ret;
}

@@ -2171,8 +2158,7 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action)
		refcount_dec(&action->reformat->dmn->refcount);
		break;
	case DR_ACTION_TYP_MODIFY_HDR:
		mlx5dr_icm_free_chunk(action->rewrite->chunk);
		kfree(action->rewrite->data);
		mlx5dr_ste_free_modify_hdr(action);
		refcount_dec(&action->rewrite->dmn->refcount);
		break;
	case DR_ACTION_TYP_SAMPLER:
+57 −0
Original line number Diff line number Diff line
@@ -633,6 +633,63 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
						 used_hw_action_num);
}

static int
dr_ste_alloc_modify_hdr_chunk(struct mlx5dr_action *action)
{
	struct mlx5dr_domain *dmn = action->rewrite->dmn;
	u32 chunk_size;
	int ret;

	chunk_size = ilog2(roundup_pow_of_two(action->rewrite->num_of_actions));

	/* HW modify action index granularity is at least 64B */
	chunk_size = max_t(u32, chunk_size, DR_CHUNK_SIZE_8);

	action->rewrite->chunk = mlx5dr_icm_alloc_chunk(dmn->action_icm_pool,
							chunk_size);
	if (!action->rewrite->chunk)
		return -ENOMEM;

	action->rewrite->index = (mlx5dr_icm_pool_get_chunk_icm_addr(action->rewrite->chunk) -
				  dmn->info.caps.hdr_modify_icm_addr) /
				 DR_ACTION_CACHE_LINE_SIZE;

	ret = mlx5dr_send_postsend_action(action->rewrite->dmn, action);
	if (ret)
		goto free_chunk;

	return 0;

free_chunk:
	mlx5dr_icm_free_chunk(action->rewrite->chunk);
	return -ENOMEM;
}

static void dr_ste_free_modify_hdr_chunk(struct mlx5dr_action *action)
{
	mlx5dr_icm_free_chunk(action->rewrite->chunk);
}

int mlx5dr_ste_alloc_modify_hdr(struct mlx5dr_action *action)
{
	struct mlx5dr_domain *dmn = action->rewrite->dmn;

	if (mlx5dr_domain_is_support_ptrn_arg(dmn))
		return dmn->ste_ctx->alloc_modify_hdr_chunk(action);

	return dr_ste_alloc_modify_hdr_chunk(action);
}

void mlx5dr_ste_free_modify_hdr(struct mlx5dr_action *action)
{
	struct mlx5dr_domain *dmn = action->rewrite->dmn;

	if (mlx5dr_domain_is_support_ptrn_arg(dmn))
		return dmn->ste_ctx->dealloc_modify_hdr_chunk(action);

	return dr_ste_free_modify_hdr_chunk(action);
}

static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn,
				       struct mlx5dr_match_spec *spec)
{
+2 −0
Original line number Diff line number Diff line
@@ -195,6 +195,8 @@ struct mlx5dr_ste_ctx {
					u8 *hw_action,
					u32 hw_action_sz,
					u16 *used_hw_action_num);
	int (*alloc_modify_hdr_chunk)(struct mlx5dr_action *action);
	void (*dealloc_modify_hdr_chunk)(struct mlx5dr_action *action);

	/* Send */
	void (*prepare_for_postsend)(u8 *hw_ste_p, u32 ste_size);
+29 −0
Original line number Diff line number Diff line
@@ -2176,6 +2176,32 @@ dr_ste_v1_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build *sb,
	sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag;
}

int dr_ste_v1_alloc_modify_hdr_ptrn_arg(struct mlx5dr_action *action)
{
	struct mlx5dr_ptrn_mgr *ptrn_mgr;

	ptrn_mgr = action->rewrite->dmn->ptrn_mgr;
	if (!ptrn_mgr)
		return -EOPNOTSUPP;

	action->rewrite->ptrn =
		mlx5dr_ptrn_cache_get_pattern(ptrn_mgr,
					      action->rewrite->num_of_actions,
					      action->rewrite->data);
	if (!action->rewrite->ptrn) {
		mlx5dr_err(action->rewrite->dmn, "Failed to get pattern\n");
		return -EAGAIN;
	}

	return 0;
}

void dr_ste_v1_free_modify_hdr_ptrn_arg(struct mlx5dr_action *action)
{
	mlx5dr_ptrn_cache_put_pattern(action->rewrite->dmn->ptrn_mgr,
				      action->rewrite->ptrn);
}

static struct mlx5dr_ste_ctx ste_ctx_v1 = {
	/* Builders */
	.build_eth_l2_src_dst_init	= &dr_ste_v1_build_eth_l2_src_dst_init,
@@ -2232,6 +2258,9 @@ static struct mlx5dr_ste_ctx ste_ctx_v1 = {
	.set_action_add			= &dr_ste_v1_set_action_add,
	.set_action_copy		= &dr_ste_v1_set_action_copy,
	.set_action_decap_l3_list	= &dr_ste_v1_set_action_decap_l3_list,
	.alloc_modify_hdr_chunk		= &dr_ste_v1_alloc_modify_hdr_ptrn_arg,
	.dealloc_modify_hdr_chunk	= &dr_ste_v1_free_modify_hdr_ptrn_arg,

	/* Send */
	.prepare_for_postsend		= &dr_ste_v1_prepare_for_postsend,
};
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ void dr_ste_v1_set_action_copy(u8 *d_action, u8 dst_hw_field, u8 dst_shifter,
			       u8 dst_len, u8 src_hw_field, u8 src_shifter);
int dr_ste_v1_set_action_decap_l3_list(void *data, u32 data_sz, u8 *hw_action,
				       u32 hw_action_sz, u16 *used_hw_action_num);
int dr_ste_v1_alloc_modify_hdr_ptrn_arg(struct mlx5dr_action *action);
void dr_ste_v1_free_modify_hdr_ptrn_arg(struct mlx5dr_action *action);
void dr_ste_v1_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb,
					 struct mlx5dr_match_param *mask);
void dr_ste_v1_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb,
Loading