This patch adds the new port affinity item supports in PMD: RTE_FLOW_ITEM_TYPE_PORT_AFFINITY.
This patch adds the validation function for the new item, it works for NIC-RX rules on ROOT-table only. Signed-off-by: Jiawei Wang <jiaw...@nvidia.com> --- doc/guides/nics/features/mlx5.ini | 1 + doc/guides/nics/mlx5.rst | 4 +- drivers/net/mlx5/linux/mlx5_os.c | 2 + drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.h | 3 + drivers/net/mlx5/mlx5_flow_dv.c | 95 +++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_flow_hw.c | 14 +++++ 7 files changed, 119 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini index 62fd330e2b..a7766221c9 100644 --- a/doc/guides/nics/features/mlx5.ini +++ b/doc/guides/nics/features/mlx5.ini @@ -87,6 +87,7 @@ vlan = Y vxlan = Y vxlan_gpe = Y represented_port = Y +port_affinity = Y [rte_flow actions] age = I diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 85a2b422c5..fe33c2a895 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -106,6 +106,7 @@ Features - Sub-Function representors. - Sub-Function. - Matching on represented port. +- Matching on port affinity. Limitations @@ -595,10 +596,11 @@ Limitations - key - sequence - Matching on checksum and sequence needs MLNX_OFED 5.6+. +- Matching on checksum and sequence needs MLNX_OFED 5.6+. - The NIC egress flow rules on representor port are not supported. +- Match on port affinity is supported NIC ingress flow in group 0 only. Statistics ---------- diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index 3fea72013f..babc7d2f94 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -1406,6 +1406,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, sh->lag_rx_port_affinity_en = 1; DRV_LOG(DEBUG, "LAG Rx Port Affinity enabled"); } + priv->num_lag_ports = hca_attr->num_lag_ports; + DRV_LOG(DEBUG, "The number of lag ports is %d", priv->num_lag_ports); } /* Process parameters and store port configuration on priv structure. */ err = mlx5_port_args_config(priv, mkvlist, &priv->config); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index dc4d1a8686..52f1592035 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -1739,6 +1739,7 @@ struct mlx5_priv { unsigned int mtr_reg_share:1; /* Whether support meter REG_C share. */ unsigned int lb_used:1; /* Loopback queue is referred to. */ uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */ + uint32_t num_lag_ports:4; /* Number of ports can be bonded. */ uint16_t domain_id; /* Switch domain identifier. */ uint16_t vport_id; /* Associated VF vport index (if any). */ uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 7148c10e96..13cf9b7d76 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -264,6 +264,9 @@ enum mlx5_feature_name { /* IPSEC syndrome item */ #define MLX5_FLOW_ITEM_IPSEC_SYNDROME (UINT64_C(1) << 46) +/* Port affinity item */ +#define MLX5_FLOW_ITEM_PORT_AFFINITY (UINT64_C(1) << 47) + /* Outer Masks. */ #define MLX5_FLOW_LAYER_OUTER_L3 \ (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 310fb7c5c3..62a6fb496d 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3888,6 +3888,74 @@ flow_dv_validate_item_ipsec_syndrome(struct rte_eth_dev *dev, return 0; } +/** + * Validate Port affinity item. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] item + * Item specification. + * @param[in] attr + * Attributes of flow that includes this item. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_dv_validate_item_port_affinity(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + const struct rte_flow_item_port_affinity *spec = item->spec; + const struct rte_flow_item_port_affinity *mask = item->mask; + struct rte_flow_item_port_affinity nic_mask = { + .affinity = UINT8_MAX + }; + int ret; + + if (!priv->sh->lag_rx_port_affinity_en) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "Unsupported port affinity with Older FW"); + if (!attr->ingress || attr->transfer || attr->group) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, + item->spec, + "port affinity is supported with NIC-RX on Root"); + if (!spec) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, + item->spec, + "data cannot be empty"); + if (spec->affinity == 0) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, + item->spec, + "zero affinity number not supported"); + if (spec->affinity > priv->num_lag_ports) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, + item->spec, + "exceed max affinity number in lag ports"); + if (!mask) + mask = &rte_flow_item_port_affinity_mask; + if (!mask->affinity) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, NULL, + "mask cannot be zero"); + ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, + (const uint8_t *)&nic_mask, + sizeof(struct rte_flow_item_port_affinity), + MLX5_ITEM_RANGE_NOT_ACCEPTED, error); + if (ret < 0) + return ret; + return 0; +} + int flow_dv_encap_decap_match_cb(void *tool_ctx __rte_unused, struct mlx5_list_entry *entry, void *cb_ctx) @@ -7679,6 +7747,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; last_item = MLX5_FLOW_ITEM_IPSEC_SYNDROME; break; + case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY: + ret = flow_dv_validate_item_port_affinity(dev, items, + attr, error); + if (ret < 0) + return ret; + last_item = MLX5_FLOW_ITEM_PORT_AFFINITY; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, @@ -10978,6 +11053,22 @@ flow_dv_translate_item_ipsec_syndrome(void *key, spec->syndrome & mask->syndrome); } +static void +flow_dv_translate_item_port_affinity(void *key, + const struct rte_flow_item *item, + uint32_t key_type) +{ + const struct rte_flow_item_port_affinity *affinity_v; + const struct rte_flow_item_port_affinity *affinity_m; + void *misc_v; + + MLX5_ITEM_UPDATE(item, key_type, affinity_v, affinity_m, + &rte_flow_item_port_affinity_mask); + misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); + MLX5_SET(fte_match_set_misc, misc_v, lag_rx_port_affinity, + affinity_v->affinity & affinity_m->affinity); +} + static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 }; #define HEADER_IS_ZERO(match_criteria, headers) \ @@ -13779,6 +13870,10 @@ flow_dv_translate_items(struct rte_eth_dev *dev, flow_dv_translate_item_ipsec_syndrome(key, items, key_type); last_item = MLX5_FLOW_ITEM_IPSEC_SYNDROME; break; + case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY: + flow_dv_translate_item_port_affinity(key, items, key_type); + last_item = MLX5_FLOW_ITEM_PORT_AFFINITY; + break; default: break; } diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 0705002d99..2e93dcf801 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -5015,6 +5015,20 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev, "Unsupported meter color register"); break; } + case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY: + { + if (!priv->sh->lag_rx_port_affinity_en) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "Unsupported port affinity with Older FW"); + if (!attr->ingress || attr->transfer) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "Port affinity item not supported" + " with egress or transfer" + " attribute"); + break; + } case RTE_FLOW_ITEM_TYPE_VOID: case RTE_FLOW_ITEM_TYPE_ETH: case RTE_FLOW_ITEM_TYPE_VLAN: -- 2.18.1