]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
mlxsw: spectrum_flower: Expose a function to get min and max rule priority
authorJiri Pirko <jiri@mellanox.com>
Sat, 9 May 2020 20:06:03 +0000 (23:06 +0300)
committerJakub Kicinski <kuba@kernel.org>
Sat, 9 May 2020 23:02:43 +0000 (16:02 -0700)
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: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c

index a12ca673c224a1d7145bac77e306ca04fc5c6d45..d9a963c77401192202f94be7fd21ccf14d2e116b 100644 (file)
@@ -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);
index c61f78e30397ca15530d4a5ee6f6372c3eab934a..47da9ee0045d9840a1e622409db3e7d1f11ca54a 100644 (file)
@@ -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)
index a6e30e020b5cf3de0b0915821130e50dbb11e0e5..5c020403342f937e65b061f908bbfe8b570d32b9 100644 (file)
@@ -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;
 
index 96437992b102a5627cbc6589809d545f225c7fd5..a41df10ade9bf41a86f4063ab51382e63954336a 100644 (file)
@@ -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,
index 0897ca1967ab934e7ce0478cb6785bd285c476bf..18d22217e4356fc9b727703709ab14373e896ecc 100644 (file)
@@ -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;
+}