]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx5: support Rx queue delay drop
authorBing Zhao <bingz@nvidia.com>
Fri, 5 Nov 2021 15:30:38 +0000 (17:30 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 5 Nov 2021 16:04:53 +0000 (17:04 +0100)
For the Ethernet RQs, if there all receiving descriptors are
exhausted, the packets being received will be dropped. This behavior
prevents slow or malicious software entities at the host from
affecting the network. While for hairpin cases, even if there is no
software involved during the packet forwarding from Rx to Tx side,
some hiccup in the hardware or back pressure from Tx side may still
cause the descriptors to be exhausted. In certain scenarios it may be
preferred to configure the device to avoid such packet drops,
assuming the posting of descriptors will resume shortly.

To support this, a new devarg "delay_drop" is introduced. By default,
the delay drop is enabled for hairpin Rx queues and disabled for
standard Rx queues. This value is used as a bit mask:
  - bit 0: enablement of standard Rx queue
  - bit 1: enablement of hairpin Rx queue
And this attribute will be applied to all Rx queues of a device.

The "rq_delay_drop" capability in the HCA_CAP is checked before
creating any queue. If the hardware capabilities do not support
this delay drop, all the Rx queues will still be created without
this attribute, and the devarg setting will be ignored even if it
is specified explicitly. A warning log is used to notify the
application when this occurs.

Signed-off-by: Bing Zhao <bingz@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
doc/guides/nics/mlx5.rst
doc/guides/rel_notes/release_21_11.rst
drivers/common/mlx5/mlx5_devx_cmds.c
drivers/common/mlx5/mlx5_devx_cmds.h
drivers/net/mlx5/linux/mlx5_os.c
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_devx.c
drivers/net/mlx5/mlx5_rx.h

index c8fa1f8f17ccdcb66dcd2050b7e8f601a76cb95e..7500c6c2bdfcae8a906dd48e7f203f75d9cf6bd7 100644 (file)
@@ -61,6 +61,7 @@ Features
 - Multi arch support: x86_64, POWER8, ARMv8, i686.
 - Multiple TX and RX queues.
 - Shared Rx queue.
+- Rx queue delay drop.
 - Support for scattered TX frames.
 - Advanced support for scattered Rx frames with tunable buffer attributes.
 - IPv4, IPv6, TCPv4, TCPv6, UDPv4 and UDPv6 RSS on any number of queues.
@@ -608,6 +609,16 @@ Driver options
   - POWER8 and ARMv8 with ConnectX-4 Lx, ConnectX-5, ConnectX-6, ConnectX-6 Dx,
     ConnectX-6 Lx, BlueField and BlueField-2.
 
+- ``delay_drop`` parameter [int]
+
+  Bitmask value for the Rx queue delay drop attribute. Bit 0 is used for the
+  standard Rx queue and bit 1 is used for the hairpin Rx queue. By default, the
+  delay drop is disabled for all Rx queues. It will be ignored if the port does
+  not support the attribute even if it is enabled explicitly.
+
+  The packets being received will not be dropped immediately when the WQEs are
+  exhausted in a Rx queue with delay drop enabled.
+
 - ``mprq_en`` parameter [int]
 
   A nonzero value enables configuring Multi-Packet Rx queues. Rx queue is
index e48333eeade3a3d039fa9669e2bb7fe9f612bd3f..771122f05f58d82d788a8172e9aa1cf614ea7a63 100644 (file)
@@ -201,6 +201,7 @@ New Features
   Updated the Mellanox mlx5 driver with new features and improvements, including:
 
   * Added implicit mempool registration to avoid data path hiccups (opt-out).
+  * Added delay drop support for Rx queue.
   * Added NIC offloads for the PMD on Windows (TSO, VLAN strip, CRC keep).
   * Added socket direct mode bonding support.
 
index fca1470be7591c6d68773cf2ecd3f93668991312..49db07facc3b9d1398d5f8b2a280e751902af058 100644 (file)
@@ -965,6 +965,7 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
        attr->ct_offload = !!(MLX5_GET64(cmd_hca_cap, hcattr,
                                         general_obj_types) &
                              MLX5_GENERAL_OBJ_TYPES_CAP_CONN_TRACK_OFFLOAD);
+       attr->rq_delay_drop = MLX5_GET(cmd_hca_cap, hcattr, rq_delay_drop);
        if (attr->qos.sup) {
                hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
                                MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
index 344cd7bbf37d0025038f612761715acde259f2ba..447f76f1f99a1c2928fef20fd510022dfda9005d 100644 (file)
@@ -178,6 +178,7 @@ struct mlx5_hca_attr {
        uint32_t swp_csum:1;
        uint32_t swp_lso:1;
        uint32_t lro_max_msg_sz_mode:2;
+       uint32_t rq_delay_drop:1;
        uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS];
        uint16_t lro_min_mss_size;
        uint32_t flex_parser_protocols;
index e0304b685e519025b08ca2ea5739b2b90c82eb47..de880ee4c99ecc4e6c2fac1e54e605c30dae77be 100644 (file)
@@ -1508,6 +1508,15 @@ err_secondary:
                goto error;
 #endif
        }
+       if (config->std_delay_drop || config->hp_delay_drop) {
+               if (!config->hca_attr.rq_delay_drop) {
+                       config->std_delay_drop = 0;
+                       config->hp_delay_drop = 0;
+                       DRV_LOG(WARNING,
+                               "dev_port-%u: Rxq delay drop is not supported",
+                               priv->dev_port);
+               }
+       }
        if (sh->devx) {
                uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
@@ -2077,6 +2086,8 @@ mlx5_os_config_default(struct mlx5_dev_config *config)
        config->decap_en = 1;
        config->log_hp_size = MLX5_ARG_UNSET;
        config->allow_duplicate_pattern = 1;
+       config->std_delay_drop = 0;
+       config->hp_delay_drop = 0;
 }
 
 /**
index 8614b8ffddd68e4e9f9ced5f696ae328a871358a..9c8d1cc76fee7900a43d5175d8115291ee229138 100644 (file)
 /* Device parameter to configure implicit registration of mempool memory. */
 #define MLX5_MR_MEMPOOL_REG_EN "mr_mempool_reg_en"
 
+/* Device parameter to configure the delay drop when creating Rxqs. */
+#define MLX5_DELAY_DROP "delay_drop"
+
 /* Shared memory between primary and secondary processes. */
 struct mlx5_shared_data *mlx5_shared_data;
 
@@ -2091,6 +2094,9 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
                config->decap_en = !!tmp;
        } else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
                config->allow_duplicate_pattern = !!tmp;
+       } else if (strcmp(MLX5_DELAY_DROP, key) == 0) {
+               config->std_delay_drop = tmp & MLX5_DELAY_DROP_STANDARD;
+               config->hp_delay_drop = tmp & MLX5_DELAY_DROP_HAIRPIN;
        } else {
                DRV_LOG(WARNING, "%s: unknown parameter", key);
                rte_errno = EINVAL;
@@ -2153,6 +2159,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
                MLX5_DECAP_EN,
                MLX5_ALLOW_DUPLICATE_PATTERN,
                MLX5_MR_MEMPOOL_REG_EN,
+               MLX5_DELAY_DROP,
                NULL,
        };
        struct rte_kvargs *kvlist;
index 51f45788381eff1e20595a4947785977f606e962..b2022f3300691ffc564329f9f7fa33d8cd9ce594 100644 (file)
@@ -99,6 +99,13 @@ enum mlx5_flow_type {
        MLX5_FLOW_TYPE_MAXI,
 };
 
+/* The mode of delay drop for Rx queues. */
+enum mlx5_delay_drop_mode {
+       MLX5_DELAY_DROP_NONE = 0, /* All disabled. */
+       MLX5_DELAY_DROP_STANDARD = RTE_BIT32(0), /* Standard queues enable. */
+       MLX5_DELAY_DROP_HAIRPIN = RTE_BIT32(1), /* Hairpin queues enable. */
+};
+
 /* Hlist and list callback context. */
 struct mlx5_flow_cb_ctx {
        struct rte_eth_dev *dev;
@@ -264,6 +271,8 @@ struct mlx5_dev_config {
        unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
        unsigned int allow_duplicate_pattern:1;
        /* Allow/Prevent the duplicate rules pattern. */
+       unsigned int std_delay_drop:1; /* Enable standard Rxq delay drop. */
+       unsigned int hp_delay_drop:1; /* Enable hairpin Rxq delay drop. */
        struct {
                unsigned int enabled:1; /* Whether MPRQ is enabled. */
                unsigned int stride_num_n; /* Number of strides. */
index a9f9f4af700d69687721a73a1d6cfa0fc55a24aa..e46f79124d2101887396efa803e47756302744fd 100644 (file)
@@ -277,6 +277,7 @@ mlx5_rxq_create_devx_rq_resources(struct mlx5_rxq_priv *rxq)
                                                MLX5_WQ_END_PAD_MODE_NONE;
        rq_attr.wq_attr.pd = cdev->pdn;
        rq_attr.counter_set_id = priv->counter_set_id;
+       rq_attr.delay_drop_en = rxq_data->delay_drop;
        rq_attr.user_index = rte_cpu_to_be_16(priv->dev_data->port_id);
        if (rxq_data->shared) /* Create RMP based RQ. */
                rxq->devx_rq.rmp = &rxq_ctrl->obj->devx_rmp;
@@ -439,6 +440,8 @@ mlx5_rxq_obj_hairpin_new(struct mlx5_rxq_priv *rxq)
                        attr.wq_attr.log_hairpin_data_sz -
                        MLX5_HAIRPIN_QUEUE_STRIDE;
        attr.counter_set_id = priv->counter_set_id;
+       rxq_ctrl->rxq.delay_drop = priv->config.hp_delay_drop;
+       attr.delay_drop_en = priv->config.hp_delay_drop;
        tmpl->rq = mlx5_devx_cmd_create_rq(priv->sh->cdev->ctx, &attr,
                                           rxq_ctrl->socket);
        if (!tmpl->rq) {
@@ -496,6 +499,7 @@ mlx5_rxq_devx_obj_new(struct mlx5_rxq_priv *rxq)
                DRV_LOG(ERR, "Failed to create CQ.");
                goto error;
        }
+       rxq_data->delay_drop = priv->config.std_delay_drop;
        /* Create RQ using DevX API. */
        ret = mlx5_rxq_create_devx_rq_resources(rxq);
        if (ret) {
@@ -941,6 +945,7 @@ mlx5_rxq_devx_obj_drop_create(struct rte_eth_dev *dev)
                        dev->data->port_id);
                goto error;
        }
+       rxq_ctrl->rxq.delay_drop = 0;
        /* Create RQ using DevX API. */
        ret = mlx5_rxq_create_devx_rq_resources(rxq);
        if (ret != 0) {
index eda6eca8dea2ccc81542a1449c3c6fa8cd60f257..3b797e577a8dfc699cfa650c48c4b32bd9f564c0 100644 (file)
@@ -97,6 +97,7 @@ struct mlx5_rxq_data {
        unsigned int dynf_meta:1; /* Dynamic metadata is configured. */
        unsigned int mcqe_format:3; /* CQE compression format. */
        unsigned int shared:1; /* Shared RXQ. */
+       unsigned int delay_drop:1; /* Enable delay drop. */
        volatile uint32_t *rq_db;
        volatile uint32_t *cq_db;
        uint16_t port_id;