]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx4: convert Rx path to work queues
authorAdrien Mazarguil <adrien.mazarguil@6wind.com>
Thu, 12 Oct 2017 12:19:39 +0000 (14:19 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 13 Oct 2017 00:18:48 +0000 (01:18 +0100)
Work queues (WQs) are lower-level than standard queue pairs (QPs). They are
dedicated to one traffic direction and have to be used in conjunction with
indirection tables and special "hash" QPs to get the same level of
functionality.

These extra objects however are the building blocks for RSS support brought
by subsequent commits, as a single "hash" QP can manage several WQs through
an indirection table according to a hash algorithm and other parameters.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/mlx4_rxq.c
drivers/net/mlx4/mlx4_rxtx.c
drivers/net/mlx4/mlx4_rxtx.h

index a27399ae54325f9ae34454e913fd523b572f21af..b04a1046004fe33cbfafd38774152aef1da39867 100644 (file)
@@ -61,6 +61,9 @@
 /** Maximum size for inline data. */
 #define MLX4_PMD_MAX_INLINE 0
 
+/** Fixed RSS hash key size in bytes. Cannot be modified. */
+#define MLX4_RSS_HASH_KEY_SIZE 40
+
 /**
  * Maximum number of cached Memory Pools (MPs) per TX queue. Each RTE MP
  * from which buffers are to be transmitted will have to be mapped by this
index 9978e5db43ced8914b478a8218e935e0acefcd61..171fe3f5abe394617a79173fbc311ed6ba7d3313 100644 (file)
@@ -268,18 +268,64 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                      (void *)dev, strerror(rte_errno));
                goto error;
        }
-       rxq->qp = ibv_create_qp
-               (priv->pd,
-                &(struct ibv_qp_init_attr){
-                       .send_cq = rxq->cq,
-                       .recv_cq = rxq->cq,
-                       .cap = {
-                               .max_recv_wr =
-                                       RTE_MIN(priv->device_attr.max_qp_wr,
-                                               desc),
-                               .max_recv_sge = 1,
+       rxq->wq = ibv_create_wq
+               (priv->ctx,
+                &(struct ibv_wq_init_attr){
+                       .wq_type = IBV_WQT_RQ,
+                       .max_wr = RTE_MIN(priv->device_attr.max_qp_wr, desc),
+                       .max_sge = 1,
+                       .pd = priv->pd,
+                       .cq = rxq->cq,
+                });
+       if (!rxq->wq) {
+               rte_errno = errno ? errno : EINVAL;
+               ERROR("%p: WQ creation failure: %s",
+                     (void *)dev, strerror(rte_errno));
+               goto error;
+       }
+       ret = ibv_modify_wq
+               (rxq->wq,
+                &(struct ibv_wq_attr){
+                       .attr_mask = IBV_WQ_ATTR_STATE,
+                       .wq_state = IBV_WQS_RDY,
+                });
+       if (ret) {
+               rte_errno = ret;
+               ERROR("%p: WQ state to IBV_WPS_RDY failed: %s",
+                     (void *)dev, strerror(rte_errno));
+               goto error;
+       }
+       rxq->ind = ibv_create_rwq_ind_table
+               (priv->ctx,
+                &(struct ibv_rwq_ind_table_init_attr){
+                       .log_ind_tbl_size = 0,
+                       .ind_tbl = (struct ibv_wq *[]){
+                               rxq->wq,
                        },
+                       .comp_mask = 0,
+                });
+       if (!rxq->ind) {
+               rte_errno = errno ? errno : EINVAL;
+               ERROR("%p: indirection table creation failure: %s",
+                     (void *)dev, strerror(errno));
+               goto error;
+       }
+       rxq->qp = ibv_create_qp_ex
+               (priv->ctx,
+                &(struct ibv_qp_init_attr_ex){
+                       .comp_mask = (IBV_QP_INIT_ATTR_PD |
+                                     IBV_QP_INIT_ATTR_RX_HASH |
+                                     IBV_QP_INIT_ATTR_IND_TABLE),
                        .qp_type = IBV_QPT_RAW_PACKET,
+                       .pd = priv->pd,
+                       .rwq_ind_tbl = rxq->ind,
+                       .rx_hash_conf = {
+                               .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
+                               .rx_hash_key_len = MLX4_RSS_HASH_KEY_SIZE,
+                               .rx_hash_key =
+                                       (uint8_t [MLX4_RSS_HASH_KEY_SIZE]){ 0 },
+                               .rx_hash_fields_mask = 0,
+                       },
                 });
        if (!rxq->qp) {
                rte_errno = errno ? errno : EINVAL;
@@ -306,8 +352,8 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                      (void *)dev, strerror(rte_errno));
                goto error;
        }
-       ret = ibv_post_recv(rxq->qp, &(*rxq->elts)[0].wr,
-                           &(struct ibv_recv_wr *){ NULL });
+       ret = ibv_post_wq_recv(rxq->wq, &(*rxq->elts)[0].wr,
+                              &(struct ibv_recv_wr *){ NULL });
        if (ret) {
                rte_errno = ret;
                ERROR("%p: ibv_post_recv() failed: %s",
@@ -373,6 +419,10 @@ mlx4_rx_queue_release(void *dpdk_rxq)
        mlx4_rxq_free_elts(rxq);
        if (rxq->qp)
                claim_zero(ibv_destroy_qp(rxq->qp));
+       if (rxq->ind)
+               claim_zero(ibv_destroy_rwq_ind_table(rxq->ind));
+       if (rxq->wq)
+               claim_zero(ibv_destroy_wq(rxq->wq));
        if (rxq->cq)
                claim_zero(ibv_destroy_cq(rxq->cq));
        if (rxq->channel)
index b5e77771c8ed1f6d4d2dbe037a6531d4507f18cc..859f1bd64bc7896f03cd17a0c7ddccfd2c97e3bf 100644 (file)
@@ -459,7 +459,7 @@ repost:
        /* Repost WRs. */
        *wr_next = NULL;
        assert(wr_head);
-       ret = ibv_post_recv(rxq->qp, wr_head, &wr_bad);
+       ret = ibv_post_wq_recv(rxq->wq, wr_head, &wr_bad);
        if (unlikely(ret)) {
                /* Inability to repost WRs is fatal. */
                DEBUG("%p: recv_burst(): failed (ret=%d)",
index d90f2f994c09f4e90186122e1bf42d02fffff6a8..897fd2a3714e5ea9b680c9419bf5d41e89312685 100644 (file)
@@ -73,6 +73,8 @@ struct rxq {
        struct rte_mempool *mp; /**< Memory pool for allocations. */
        struct ibv_mr *mr; /**< Memory region (for mp). */
        struct ibv_cq *cq; /**< Completion queue. */
+       struct ibv_wq *wq; /**< Work queue. */
+       struct ibv_rwq_ind_table *ind; /**< Indirection table. */
        struct ibv_qp *qp; /**< Queue pair. */
        struct ibv_comp_channel *channel; /**< Rx completion channel. */
        unsigned int port_id; /**< Port ID for incoming packets. */