net/mlx5: enlarge maximal flow priority
authorDong Zhou <dongzhou@nvidia.com>
Tue, 12 Jan 2021 06:40:00 +0000 (08:40 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:07 +0000 (18:16 +0100)
Currently, the maximal flow priority in non-root table to user
is 4, it's not enough for user to do some flow match by priority,
such as LPM, for one IPV4 address, we need 32 priorities for each
bit of 32 mask length.

PMD will manage 3 sub-priorities per user priority according to L2,
L3 and L4. The internal priority is 16 bits, user can use priorities
from 0 - 21843.

Those enlarged flow priorities are only used for ingress or egress
flow groups greater than 0 and for any transfer flow group.

Signed-off-by: Dong Zhou <dongzhou@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
doc/guides/nics/mlx5.rst
doc/guides/rel_notes/release_21_02.rst
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_flow_verbs.c

index fc93545..1765952 100644 (file)
@@ -103,6 +103,8 @@ Features
 - RSS support in sample action.
 - E-Switch mirroring and jump.
 - E-Switch mirroring and modify.
+- 21844 flow priorities for ingress or egress flow groups greater than 0 and for any transfer
+  flow group.
 
 Limitations
 -----------
index 2a1f43b..82abb3c 100644 (file)
@@ -116,6 +116,8 @@ New Features
   * Added support for E-Switch mirroring and jump action in the same flow.
   * Added support to handle modify action in correct order regarding the
     mirroring action on E-Switch.
+  * Enlarged the number of flow priorities to 21844 (0 - 21843) for ingress or
+    egress flow groups greater than 0 and for any transfer flow group.
 
 * **Updated Wangxun txgbe driver.**
 
index 5d180fc..0197a07 100644 (file)
@@ -855,6 +855,58 @@ mlx5_flow_ext_mreg_supported(struct rte_eth_dev *dev)
        return config->flow_mreg_c[2] != REG_NON;
 }
 
+/**
+ * Get the lowest priority.
+ *
+ * @param[in] dev
+ *   Pointer to the Ethernet device structure.
+ * @param[in] attributes
+ *   Pointer to device flow rule attributes.
+ *
+ * @return
+ *   The value of lowest priority of flow.
+ */
+uint32_t
+mlx5_get_lowest_priority(struct rte_eth_dev *dev,
+                         const struct rte_flow_attr *attr)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+
+       if (!attr->group && !attr->transfer)
+               return priv->config.flow_prio - 2;
+       return MLX5_NON_ROOT_FLOW_MAX_PRIO - 1;
+}
+
+/**
+ * Calculate matcher priority of the flow.
+ *
+ * @param[in] dev
+ *   Pointer to the Ethernet device structure.
+ * @param[in] attr
+ *   Pointer to device flow rule attributes.
+ * @param[in] subpriority
+ *   The priority based on the items.
+ * @return
+ *   The matcher priority of the flow.
+ */
+uint16_t
+mlx5_get_matcher_priority(struct rte_eth_dev *dev,
+                         const struct rte_flow_attr *attr,
+                         uint32_t subpriority)
+{
+       uint16_t priority = (uint16_t)attr->priority;
+       struct mlx5_priv *priv = dev->data->dev_private;
+
+       if (!attr->group && !attr->transfer) {
+               if (attr->priority == MLX5_FLOW_LOWEST_PRIO_INDICATOR)
+                       priority = priv->config.flow_prio - 1;
+               return mlx5_os_flow_adjust_priority(dev, priority, subpriority);
+       }
+       if (attr->priority == MLX5_FLOW_LOWEST_PRIO_INDICATOR)
+               priority = MLX5_NON_ROOT_FLOW_MAX_PRIO;
+       return priority * 3 + subpriority;
+}
+
 /**
  * Verify the @p item specifications (spec, last, mask) are compatible with the
  * NIC capabilities.
@@ -1669,7 +1721,7 @@ mlx5_flow_validate_attributes(struct rte_eth_dev *dev,
                return rte_flow_error_set(error, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
                                          NULL, "groups is not supported");
-       if (attributes->priority != MLX5_FLOW_PRIO_RSVD &&
+       if (attributes->priority != MLX5_FLOW_LOWEST_PRIO_INDICATOR &&
            attributes->priority >= priority_max)
                return rte_flow_error_set(error, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -3837,7 +3889,7 @@ flow_dv_mreg_create_cb(struct mlx5_hlist *list, uint64_t key,
                };
        } else {
                /* Default rule, wildcard match. */
-               attr.priority = MLX5_FLOW_PRIO_RSVD;
+               attr.priority = MLX5_FLOW_LOWEST_PRIO_INDICATOR;
                items[0] = (struct rte_flow_item){
                        .type = RTE_FLOW_ITEM_TYPE_END,
                };
@@ -5685,7 +5737,7 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
         */
        if (external || dev->data->dev_started ||
            (attr->group == MLX5_FLOW_MREG_CP_TABLE_GROUP &&
-            attr->priority == MLX5_FLOW_PRIO_RSVD)) {
+            attr->priority == MLX5_FLOW_LOWEST_PRIO_INDICATOR)) {
                ret = flow_drv_apply(dev, flow, error);
                if (ret < 0)
                        goto error;
@@ -6185,7 +6237,7 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
        struct mlx5_priv *priv = dev->data->dev_private;
        const struct rte_flow_attr attr = {
                .ingress = 1,
-               .priority = MLX5_FLOW_PRIO_RSVD,
+               .priority = MLX5_FLOW_LOWEST_PRIO_INDICATOR,
        };
        struct rte_flow_item items[] = {
                {
@@ -7070,7 +7122,7 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev)
        for (idx = REG_C_2; idx <= REG_C_7; ++idx) {
                struct rte_flow_attr attr = {
                        .group = MLX5_FLOW_MREG_CP_TABLE_GROUP,
-                       .priority = MLX5_FLOW_PRIO_RSVD,
+                       .priority = MLX5_FLOW_LOWEST_PRIO_INDICATOR,
                        .ingress = 1,
                };
                struct rte_flow_item items[] = {
index 8c705e2..2178a04 100644 (file)
@@ -270,8 +270,15 @@ enum mlx5_feature_name {
 /* UDP port numbers for GENEVE. */
 #define MLX5_UDP_PORT_GENEVE 6081
 
-/* Priority reserved for default flows. */
-#define MLX5_FLOW_PRIO_RSVD ((uint32_t)-1)
+/* Lowest priority indicator. */
+#define MLX5_FLOW_LOWEST_PRIO_INDICATOR ((uint32_t)-1)
+
+/*
+ * Max priority for ingress\egress flow groups
+ * greater than 0 and for any transfer flow group.
+ * From user configation: 0 - 21843.
+ */
+#define MLX5_NON_ROOT_FLOW_MAX_PRIO    (21843 + 1)
 
 /*
  * Number of sub priorities.
@@ -1314,6 +1321,11 @@ uint64_t mlx5_flow_hashfields_adjust(struct mlx5_flow_rss_desc *rss_desc,
 int mlx5_flow_discover_priorities(struct rte_eth_dev *dev);
 uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
                                   uint32_t subpriority);
+uint32_t mlx5_get_lowest_priority(struct rte_eth_dev *dev,
+                                       const struct rte_flow_attr *attr);
+uint16_t mlx5_get_matcher_priority(struct rte_eth_dev *dev,
+                                    const struct rte_flow_attr *attr,
+                                    uint32_t subpriority);
 int mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
                                     enum mlx5_feature_name feature,
                                     uint32_t id,
index b44e9d3..5e34cbe 100644 (file)
@@ -5238,7 +5238,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
                            struct rte_flow_error *error)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
-       uint32_t priority_max = priv->config.flow_prio - 1;
+       uint32_t lowest_priority = mlx5_get_lowest_priority(dev, attributes);
        int ret = 0;
 
 #ifndef HAVE_MLX5DV_DR
@@ -5259,8 +5259,8 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
        if (!table)
                ret = MLX5DV_DR_ACTION_FLAGS_ROOT_LEVEL;
 #endif
-       if (attributes->priority != MLX5_FLOW_PRIO_RSVD &&
-           attributes->priority >= priority_max)
+       if (attributes->priority != MLX5_FLOW_LOWEST_PRIO_INDICATOR &&
+           attributes->priority > lowest_priority)
                return rte_flow_error_set(error, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
                                          NULL,
@@ -10085,7 +10085,6 @@ flow_dv_translate(struct rte_eth_dev *dev,
        uint64_t item_flags = 0;
        uint64_t last_item = 0;
        uint64_t action_flags = 0;
-       uint64_t priority = attr->priority;
        struct mlx5_flow_dv_matcher matcher = {
                .mask = {
                        .size = sizeof(matcher.mask.buf) -
@@ -10158,8 +10157,6 @@ flow_dv_translate(struct rte_eth_dev *dev,
        dev_flow->dv.group = table;
        if (attr->transfer)
                mhdr_res->ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
-       if (priority == MLX5_FLOW_PRIO_RSVD)
-               priority = dev_conf->flow_prio - 1;
        /* number of actions must be set to 0 in case of dirty stack. */
        mhdr_res->actions_num = 0;
        if (is_flow_tunnel_match_rule(dev, attr, items, actions)) {
@@ -11048,9 +11045,8 @@ flow_dv_translate(struct rte_eth_dev *dev,
        /* Register matcher. */
        matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf,
                                    matcher.mask.size);
-       matcher.priority = mlx5_os_flow_adjust_priority(dev,
-                                                       priority,
-                                                       matcher.priority);
+       matcher.priority = mlx5_get_matcher_priority(dev, attr,
+                                       matcher.priority);
        /* reserved field no needs to be set to 0 here. */
        tbl_key.domain = attr->transfer;
        tbl_key.direction = attr->egress;
index 9347490..205b057 100644 (file)
@@ -109,8 +109,11 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
                        dev->data->port_id, priority);
                return -rte_errno;
        }
-       DRV_LOG(INFO, "port %u flow maximum priority: %d",
-               dev->data->port_id, priority);
+       DRV_LOG(INFO, "port %u supported flow priorities:"
+               " 0-%d for ingress or egress root table,"
+               " 0-%d for non-root table or transfer root table.",
+               dev->data->port_id, priority - 2,
+               MLX5_NON_ROOT_FLOW_MAX_PRIO - 1);
        return priority;
 }
 
@@ -1710,7 +1713,7 @@ flow_verbs_translate(struct rte_eth_dev *dev,
 
        MLX5_ASSERT(wks);
        rss_desc = &wks->rss_desc;
-       if (priority == MLX5_FLOW_PRIO_RSVD)
+       if (priority == MLX5_FLOW_LOWEST_PRIO_INDICATOR)
                priority = priv->config.flow_prio - 1;
        for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
                int ret;