Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2f2a1fd authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

mlxsw: spectrum: Implement chain template hinting



Since cld_flower provides information about the filter template for
specific chain, use this information in order to prepare a region.
Use the template to find out what elements are going to be used
and pass that down to mlxsw_sp_acl_tcam_group_add(). Later on, when the
first filter is inserted, the mlxsw_sp_acl_tcam_group_use_patterns()
function would use this element usage information instead of looking
up a pattern.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 34738452
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -1455,6 +1455,11 @@ mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block,
		return 0;
		return 0;
	case TC_CLSFLOWER_STATS:
	case TC_CLSFLOWER_STATS:
		return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f);
		return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f);
	case TC_CLSFLOWER_TMPLT_CREATE:
		return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f);
	case TC_CLSFLOWER_TMPLT_DESTROY:
		mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f);
		return 0;
	default:
	default:
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;
	}
	}
+8 −1
Original line number Original line Diff line number Diff line
@@ -543,7 +543,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ruleset *
struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
			 struct mlxsw_sp_acl_block *block, u32 chain_index,
			 struct mlxsw_sp_acl_block *block, u32 chain_index,
			 enum mlxsw_sp_acl_profile profile);
			 enum mlxsw_sp_acl_profile profile,
			 struct mlxsw_afk_element_usage *tmplt_elusage);
void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
			      struct mlxsw_sp_acl_ruleset *ruleset);
			      struct mlxsw_sp_acl_ruleset *ruleset);
u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset);
u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset);
@@ -667,6 +668,12 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
			  struct mlxsw_sp_acl_block *block,
			  struct mlxsw_sp_acl_block *block,
			  struct tc_cls_flower_offload *f);
			  struct tc_cls_flower_offload *f);
int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp,
				 struct mlxsw_sp_acl_block *block,
				 struct tc_cls_flower_offload *f);
void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
				   struct mlxsw_sp_acl_block *block,
				   struct tc_cls_flower_offload *f);


/* spectrum_qdisc.c */
/* spectrum_qdisc.c */
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port);
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port);
+8 −4
Original line number Original line Diff line number Diff line
@@ -317,7 +317,8 @@ int mlxsw_sp_acl_block_unbind(struct mlxsw_sp *mlxsw_sp,
static struct mlxsw_sp_acl_ruleset *
static struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
			    struct mlxsw_sp_acl_block *block, u32 chain_index,
			    struct mlxsw_sp_acl_block *block, u32 chain_index,
			    const struct mlxsw_sp_acl_profile_ops *ops)
			    const struct mlxsw_sp_acl_profile_ops *ops,
			    struct mlxsw_afk_element_usage *tmplt_elusage)
{
{
	struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
	struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
	struct mlxsw_sp_acl_ruleset *ruleset;
	struct mlxsw_sp_acl_ruleset *ruleset;
@@ -337,7 +338,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
	if (err)
	if (err)
		goto err_rhashtable_init;
		goto err_rhashtable_init;


	err = ops->ruleset_add(mlxsw_sp, &acl->tcam, ruleset->priv);
	err = ops->ruleset_add(mlxsw_sp, &acl->tcam, ruleset->priv,
			       tmplt_elusage);
	if (err)
	if (err)
		goto err_ops_ruleset_add;
		goto err_ops_ruleset_add;


@@ -419,7 +421,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ruleset *
struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
			 struct mlxsw_sp_acl_block *block, u32 chain_index,
			 struct mlxsw_sp_acl_block *block, u32 chain_index,
			 enum mlxsw_sp_acl_profile profile)
			 enum mlxsw_sp_acl_profile profile,
			 struct mlxsw_afk_element_usage *tmplt_elusage)
{
{
	const struct mlxsw_sp_acl_profile_ops *ops;
	const struct mlxsw_sp_acl_profile_ops *ops;
	struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
	struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
@@ -434,7 +437,8 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
		mlxsw_sp_acl_ruleset_ref_inc(ruleset);
		mlxsw_sp_acl_ruleset_ref_inc(ruleset);
		return ruleset;
		return ruleset;
	}
	}
	return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops);
	return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops,
					   tmplt_elusage);
}
}


void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
+22 −3
Original line number Original line Diff line number Diff line
@@ -189,6 +189,8 @@ struct mlxsw_sp_acl_tcam_group {
	struct mlxsw_sp_acl_tcam_group_ops *ops;
	struct mlxsw_sp_acl_tcam_group_ops *ops;
	const struct mlxsw_sp_acl_tcam_pattern *patterns;
	const struct mlxsw_sp_acl_tcam_pattern *patterns;
	unsigned int patterns_count;
	unsigned int patterns_count;
	bool tmplt_elusage_set;
	struct mlxsw_afk_element_usage tmplt_elusage;
};
};


struct mlxsw_sp_acl_tcam_chunk {
struct mlxsw_sp_acl_tcam_chunk {
@@ -234,13 +236,19 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp,
			    struct mlxsw_sp_acl_tcam *tcam,
			    struct mlxsw_sp_acl_tcam *tcam,
			    struct mlxsw_sp_acl_tcam_group *group,
			    struct mlxsw_sp_acl_tcam_group *group,
			    const struct mlxsw_sp_acl_tcam_pattern *patterns,
			    const struct mlxsw_sp_acl_tcam_pattern *patterns,
			    unsigned int patterns_count)
			    unsigned int patterns_count,
			    struct mlxsw_afk_element_usage *tmplt_elusage)
{
{
	int err;
	int err;


	group->tcam = tcam;
	group->tcam = tcam;
	group->patterns = patterns;
	group->patterns = patterns;
	group->patterns_count = patterns_count;
	group->patterns_count = patterns_count;
	if (tmplt_elusage) {
		group->tmplt_elusage_set = true;
		memcpy(&group->tmplt_elusage, tmplt_elusage,
		       sizeof(group->tmplt_elusage));
	}
	INIT_LIST_HEAD(&group->region_list);
	INIT_LIST_HEAD(&group->region_list);
	err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
	err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
	if (err)
	if (err)
@@ -449,6 +457,15 @@ mlxsw_sp_acl_tcam_group_use_patterns(struct mlxsw_sp_acl_tcam_group *group,
	const struct mlxsw_sp_acl_tcam_pattern *pattern;
	const struct mlxsw_sp_acl_tcam_pattern *pattern;
	int i;
	int i;


	/* In case the template is set, we don't have to look up the pattern
	 * and just use the template.
	 */
	if (group->tmplt_elusage_set) {
		memcpy(out, &group->tmplt_elusage, sizeof(*out));
		WARN_ON(!mlxsw_afk_element_usage_subset(elusage, out));
		return;
	}

	for (i = 0; i < group->patterns_count; i++) {
	for (i = 0; i < group->patterns_count; i++) {
		pattern = &group->patterns[i];
		pattern = &group->patterns[i];
		mlxsw_afk_element_usage_fill(out, pattern->elements,
		mlxsw_afk_element_usage_fill(out, pattern->elements,
@@ -865,13 +882,15 @@ struct mlxsw_sp_acl_tcam_flower_rule {
static int
static int
mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
				     struct mlxsw_sp_acl_tcam *tcam,
				     struct mlxsw_sp_acl_tcam *tcam,
				     void *ruleset_priv)
				     void *ruleset_priv,
				     struct mlxsw_afk_element_usage *tmplt_elusage)
{
{
	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;


	return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
	return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
					   mlxsw_sp_acl_tcam_patterns,
					   mlxsw_sp_acl_tcam_patterns,
					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT);
					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
					   tmplt_elusage);
}
}


static void
static void
+2 −1
Original line number Original line Diff line number Diff line
@@ -64,7 +64,8 @@ int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_profile_ops {
struct mlxsw_sp_acl_profile_ops {
	size_t ruleset_priv_size;
	size_t ruleset_priv_size;
	int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
	int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
			   struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv);
			   struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
			   struct mlxsw_afk_element_usage *tmplt_elusage);
	void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
	void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
	int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
	int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
			    struct mlxsw_sp_port *mlxsw_sp_port,
			    struct mlxsw_sp_port *mlxsw_sp_port,
Loading