Commit 593bb843 authored by Jiri Pirko's avatar Jiri Pirko Committed by Jakub Kicinski
Browse files

mlxsw: spectrum_flower: Expose a function to get min and max rule priority



Introduce an infrastructure that allows to get minimum and maximum
rule priority for specified chain. This is going to be used by
a subsequent patch to enforce ordering between flower and
matchall filters.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 18aa23b3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -739,6 +739,9 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
			      struct mlxsw_sp_acl_ruleset *ruleset);
u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset);
void mlxsw_sp_acl_ruleset_prio_get(struct mlxsw_sp_acl_ruleset *ruleset,
				   unsigned int *p_min_prio,
				   unsigned int *p_max_prio);

struct mlxsw_sp_acl_rule_info *
mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
@@ -912,6 +915,10 @@ int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
				   struct mlxsw_sp_flow_block *block,
				   struct flow_cls_offload *f);
int mlxsw_sp_flower_prio_get(struct mlxsw_sp *mlxsw_sp,
			     struct mlxsw_sp_flow_block *block,
			     u32 chain_index, unsigned int *p_min_prio,
			     unsigned int *p_max_prio);

/* spectrum_qdisc.c */
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port);
+12 −1
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ struct mlxsw_sp_acl_ruleset {
	struct mlxsw_sp_acl_ruleset_ht_key ht_key;
	struct rhashtable rule_ht;
	unsigned int ref_count;
	unsigned int min_prio;
	unsigned int max_prio;
	unsigned long priv[];
	/* priv has to be always the last item */
};
@@ -178,7 +180,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
		goto err_rhashtable_init;

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

@@ -293,6 +296,14 @@ u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset)
	return ops->ruleset_group_id(ruleset->priv);
}

void mlxsw_sp_acl_ruleset_prio_get(struct mlxsw_sp_acl_ruleset *ruleset,
				   unsigned int *p_min_prio,
				   unsigned int *p_max_prio)
{
	*p_min_prio = ruleset->min_prio;
	*p_max_prio = ruleset->max_prio;
}

struct mlxsw_sp_acl_rule_info *
mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
			  struct mlxsw_afa_block *afa_block)
+34 −5
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ struct mlxsw_sp_acl_tcam_vgroup {
	bool tmplt_elusage_set;
	struct mlxsw_afk_element_usage tmplt_elusage;
	bool vregion_rehash_enabled;
	unsigned int *p_min_prio;
	unsigned int *p_max_prio;
};

struct mlxsw_sp_acl_tcam_rehash_ctx {
@@ -316,13 +318,17 @@ mlxsw_sp_acl_tcam_vgroup_add(struct mlxsw_sp *mlxsw_sp,
			     const struct mlxsw_sp_acl_tcam_pattern *patterns,
			     unsigned int patterns_count,
			     struct mlxsw_afk_element_usage *tmplt_elusage,
			     bool vregion_rehash_enabled)
			     bool vregion_rehash_enabled,
			     unsigned int *p_min_prio,
			     unsigned int *p_max_prio)
{
	int err;

	vgroup->patterns = patterns;
	vgroup->patterns_count = patterns_count;
	vgroup->vregion_rehash_enabled = vregion_rehash_enabled;
	vgroup->p_min_prio = p_min_prio;
	vgroup->p_max_prio = p_max_prio;

	if (tmplt_elusage) {
		vgroup->tmplt_elusage_set = true;
@@ -416,6 +422,21 @@ mlxsw_sp_acl_tcam_vregion_max_prio(struct mlxsw_sp_acl_tcam_vregion *vregion)
	return vchunk->priority;
}

static void
mlxsw_sp_acl_tcam_vgroup_prio_update(struct mlxsw_sp_acl_tcam_vgroup *vgroup)
{
	struct mlxsw_sp_acl_tcam_vregion *vregion;

	if (list_empty(&vgroup->vregion_list))
		return;
	vregion = list_first_entry(&vgroup->vregion_list,
				   typeof(*vregion), list);
	*vgroup->p_min_prio = mlxsw_sp_acl_tcam_vregion_prio(vregion);
	vregion = list_last_entry(&vgroup->vregion_list,
				  typeof(*vregion), list);
	*vgroup->p_max_prio = mlxsw_sp_acl_tcam_vregion_max_prio(vregion);
}

static int
mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
				      struct mlxsw_sp_acl_tcam_group *group,
@@ -1035,6 +1056,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
	}
	list_add_tail(&vchunk->list, pos);
	mutex_unlock(&vregion->lock);
	mlxsw_sp_acl_tcam_vgroup_prio_update(vgroup);

	return vchunk;

@@ -1066,6 +1088,7 @@ mlxsw_sp_acl_tcam_vchunk_destroy(struct mlxsw_sp *mlxsw_sp,
			       mlxsw_sp_acl_tcam_vchunk_ht_params);
	mlxsw_sp_acl_tcam_vregion_put(mlxsw_sp, vchunk->vregion);
	kfree(vchunk);
	mlxsw_sp_acl_tcam_vgroup_prio_update(vgroup);
}

static struct mlxsw_sp_acl_tcam_vchunk *
@@ -1582,14 +1605,17 @@ static int
mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
				     struct mlxsw_sp_acl_tcam *tcam,
				     void *ruleset_priv,
				     struct mlxsw_afk_element_usage *tmplt_elusage)
				     struct mlxsw_afk_element_usage *tmplt_elusage,
				     unsigned int *p_min_prio,
				     unsigned int *p_max_prio)
{
	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;

	return mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
					    mlxsw_sp_acl_tcam_patterns,
					    MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
					    tmplt_elusage, true);
					    tmplt_elusage, true,
					    p_min_prio, p_max_prio);
}

static void
@@ -1698,7 +1724,9 @@ static int
mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
				 struct mlxsw_sp_acl_tcam *tcam,
				 void *ruleset_priv,
				 struct mlxsw_afk_element_usage *tmplt_elusage)
				 struct mlxsw_afk_element_usage *tmplt_elusage,
				 unsigned int *p_min_prio,
				 unsigned int *p_max_prio)
{
	struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
	int err;
@@ -1706,7 +1734,8 @@ mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
	err = mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
					   mlxsw_sp_acl_tcam_patterns,
					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
					   tmplt_elusage, false);
					   tmplt_elusage, false,
					   p_min_prio, p_max_prio);
	if (err)
		return err;

+2 −1
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ struct mlxsw_sp_acl_profile_ops {
	size_t ruleset_priv_size;
	int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
			   struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
			   struct mlxsw_afk_element_usage *tmplt_elusage);
			   struct mlxsw_afk_element_usage *tmplt_elusage,
			   unsigned int *p_min_prio, unsigned int *p_max_prio);
	void (*ruleset_del)(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,
+20 −0
Original line number Diff line number Diff line
@@ -647,3 +647,23 @@ void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
}

int mlxsw_sp_flower_prio_get(struct mlxsw_sp *mlxsw_sp,
			     struct mlxsw_sp_flow_block *block,
			     u32 chain_index, unsigned int *p_min_prio,
			     unsigned int *p_max_prio)
{
	struct mlxsw_sp_acl_ruleset *ruleset;

	ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, block,
					      chain_index,
					      MLXSW_SP_ACL_PROFILE_FLOWER);
	if (IS_ERR(ruleset))
		/* In case there are no flower rules, the caller
		 * receives -ENOENT to indicate there is no need
		 * to check the priorities.
		 */
		return PTR_ERR(ruleset);
	mlxsw_sp_acl_ruleset_prio_get(ruleset, p_min_prio, p_max_prio);
	return 0;
}