net/mlx5: split Rx queue into shareable and private
authorXueming Li <xuemingl@nvidia.com>
Thu, 4 Nov 2021 12:33:13 +0000 (20:33 +0800)
committerRaslan Darawsheh <rasland@nvidia.com>
Thu, 4 Nov 2021 21:55:45 +0000 (22:55 +0100)
To prepare shared Rx queue, splits RxQ data into shareable and private.
Struct mlx5_rxq_priv is per queue data.
Struct mlx5_rxq_ctrl is shared queue resources and data.

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_rx.h
drivers/net/mlx5/mlx5_rxq.c

index dc15688..374cc97 100644 (file)
@@ -1700,6 +1700,10 @@ mlx5_dev_close(struct rte_eth_dev *dev)
                mlx5_free(dev->intr_handle);
                dev->intr_handle = NULL;
        }
+       if (priv->rxq_privs != NULL) {
+               mlx5_free(priv->rxq_privs);
+               priv->rxq_privs = NULL;
+       }
        if (priv->txqs != NULL) {
                /* XXX race condition if mlx5_tx_burst() is still running. */
                rte_delay_us_sleep(1000);
index 74af88e..4e99fe7 100644 (file)
@@ -1345,6 +1345,8 @@ enum mlx5_txq_modify_type {
        MLX5_TXQ_MOD_ERR2RDY, /* modify state from error to ready. */
 };
 
+struct mlx5_rxq_priv;
+
 /* HW objects operations structure. */
 struct mlx5_obj_ops {
        int (*rxq_obj_modify_vlan_strip)(struct mlx5_rxq_obj *rxq_obj, int on);
@@ -1408,7 +1410,8 @@ struct mlx5_priv {
        /* RX/TX queues. */
        unsigned int rxqs_n; /* RX queues array size. */
        unsigned int txqs_n; /* TX queues array size. */
-       struct mlx5_rxq_data *(*rxqs)[]; /* RX queues. */
+       struct mlx5_rxq_priv *(*rxq_privs)[]; /* RX queue non-shared data. */
+       struct mlx5_rxq_data *(*rxqs)[]; /* (Shared) RX queues. */
        struct mlx5_txq_data *(*txqs)[]; /* TX queues. */
        struct rte_mempool *mprq_mp; /* Mempool for Multi-Packet RQ. */
        struct rte_eth_rss_conf rss_conf; /* RSS configuration. */
index 81fa884..cde5059 100644 (file)
@@ -104,6 +104,16 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
               MLX5_RSS_HASH_KEY_LEN);
        priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN;
        priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
+       priv->rxq_privs = mlx5_realloc(priv->rxq_privs,
+                                      MLX5_MEM_RTE | MLX5_MEM_ZERO,
+                                      sizeof(void *) * rxqs_n, 0,
+                                      SOCKET_ID_ANY);
+       if (priv->rxq_privs == NULL) {
+               DRV_LOG(ERR, "port %u cannot allocate rxq private data",
+                       dev->data->port_id);
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
        priv->rxqs = (void *)dev->data->rx_queues;
        priv->txqs = (void *)dev->data->tx_queues;
        if (txqs_n != priv->txqs_n) {
index 69b1263..fa24f5c 100644 (file)
@@ -150,10 +150,14 @@ struct mlx5_rxq_ctrl {
        struct mlx5_rxq_data rxq; /* Data path structure. */
        LIST_ENTRY(mlx5_rxq_ctrl) next; /* Pointer to the next element. */
        uint32_t refcnt; /* Reference counter. */
+       LIST_HEAD(priv, mlx5_rxq_priv) owners; /* Owner rxq list. */
        struct mlx5_rxq_obj *obj; /* Verbs/DevX elements. */
+       struct mlx5_dev_ctx_shared *sh; /* Shared context. */
        struct mlx5_priv *priv; /* Back pointer to private data. */
        enum mlx5_rxq_type type; /* Rxq type. */
        unsigned int socket; /* CPU socket ID for allocations. */
+       uint32_t share_group; /* Group ID of shared RXQ. */
+       uint16_t share_qid; /* Shared RxQ ID in group. */
        unsigned int irq:1; /* Whether IRQ is enabled. */
        uint32_t flow_mark_n; /* Number of Mark/Flag flows using this Queue. */
        uint32_t flow_tunnels_n[MLX5_FLOW_TUNNEL]; /* Tunnels counters. */
@@ -163,6 +167,14 @@ struct mlx5_rxq_ctrl {
        uint32_t hairpin_status; /* Hairpin binding status. */
 };
 
+/* RX queue private data. */
+struct mlx5_rxq_priv {
+       uint16_t idx; /* Queue index. */
+       struct mlx5_rxq_ctrl *ctrl; /* Shared Rx Queue. */
+       LIST_ENTRY(mlx5_rxq_priv) owner_entry; /* Entry in shared rxq_ctrl. */
+       struct mlx5_priv *priv; /* Back pointer to private data. */
+};
+
 /* mlx5_rxq.c */
 
 extern uint8_t rss_hash_default_key[];
@@ -186,13 +198,14 @@ void mlx5_rx_intr_vec_disable(struct rte_eth_dev *dev);
 int mlx5_rx_intr_enable(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int mlx5_rx_intr_disable(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int mlx5_rxq_obj_verify(struct rte_eth_dev *dev);
-struct mlx5_rxq_ctrl *mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx,
+struct mlx5_rxq_ctrl *mlx5_rxq_new(struct rte_eth_dev *dev,
+                                  struct mlx5_rxq_priv *rxq,
                                   uint16_t desc, unsigned int socket,
                                   const struct rte_eth_rxconf *conf,
                                   const struct rte_eth_rxseg_split *rx_seg,
                                   uint16_t n_seg);
 struct mlx5_rxq_ctrl *mlx5_rxq_hairpin_new
-       (struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
+       (struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq, uint16_t desc,
         const struct rte_eth_hairpin_conf *hairpin_conf);
 struct mlx5_rxq_ctrl *mlx5_rxq_get(struct rte_eth_dev *dev, uint16_t idx);
 int mlx5_rxq_release(struct rte_eth_dev *dev, uint16_t idx);
index b2e4389..00df245 100644 (file)
@@ -674,6 +674,7 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                    struct rte_mempool *mp)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_rxq_priv *rxq;
        struct mlx5_rxq_ctrl *rxq_ctrl;
        struct rte_eth_rxseg_split *rx_seg =
                                (struct rte_eth_rxseg_split *)conf->rx_seg;
@@ -708,10 +709,23 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
        res = mlx5_rx_queue_pre_setup(dev, idx, &desc);
        if (res)
                return res;
-       rxq_ctrl = mlx5_rxq_new(dev, idx, desc, socket, conf, rx_seg, n_seg);
+       rxq = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*rxq), 0,
+                         SOCKET_ID_ANY);
+       if (!rxq) {
+               DRV_LOG(ERR, "port %u unable to allocate rx queue index %u private data",
+                       dev->data->port_id, idx);
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
+       rxq->priv = priv;
+       rxq->idx = idx;
+       (*priv->rxq_privs)[idx] = rxq;
+       rxq_ctrl = mlx5_rxq_new(dev, rxq, desc, socket, conf, rx_seg, n_seg);
        if (!rxq_ctrl) {
-               DRV_LOG(ERR, "port %u unable to allocate queue index %u",
+               DRV_LOG(ERR, "port %u unable to allocate rx queue index %u",
                        dev->data->port_id, idx);
+               mlx5_free(rxq);
+               (*priv->rxq_privs)[idx] = NULL;
                rte_errno = ENOMEM;
                return -rte_errno;
        }
@@ -741,6 +755,7 @@ mlx5_rx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
                            const struct rte_eth_hairpin_conf *hairpin_conf)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_rxq_priv *rxq;
        struct mlx5_rxq_ctrl *rxq_ctrl;
        int res;
 
@@ -776,14 +791,27 @@ mlx5_rx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
                        return -rte_errno;
                }
        }
-       rxq_ctrl = mlx5_rxq_hairpin_new(dev, idx, desc, hairpin_conf);
+       rxq = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*rxq), 0,
+                         SOCKET_ID_ANY);
+       if (!rxq) {
+               DRV_LOG(ERR, "port %u unable to allocate hairpin rx queue index %u private data",
+                       dev->data->port_id, idx);
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
+       rxq->priv = priv;
+       rxq->idx = idx;
+       (*priv->rxq_privs)[idx] = rxq;
+       rxq_ctrl = mlx5_rxq_hairpin_new(dev, rxq, desc, hairpin_conf);
        if (!rxq_ctrl) {
-               DRV_LOG(ERR, "port %u unable to allocate queue index %u",
+               DRV_LOG(ERR, "port %u unable to allocate hairpin queue index %u",
                        dev->data->port_id, idx);
+               mlx5_free(rxq);
+               (*priv->rxq_privs)[idx] = NULL;
                rte_errno = ENOMEM;
                return -rte_errno;
        }
-       DRV_LOG(DEBUG, "port %u adding Rx queue %u to list",
+       DRV_LOG(DEBUG, "port %u adding hairpin Rx queue %u to list",
                dev->data->port_id, idx);
        (*priv->rxqs)[idx] = &rxq_ctrl->rxq;
        return 0;
@@ -1319,8 +1347,8 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint16_t idx,
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param idx
- *   RX queue index.
+ * @param rxq
+ *   RX queue private data.
  * @param desc
  *   Number of descriptors to configure in queue.
  * @param socket
@@ -1330,10 +1358,12 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint16_t idx,
  *   A DPDK queue object on success, NULL otherwise and rte_errno is set.
  */
 struct mlx5_rxq_ctrl *
-mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
+mlx5_rxq_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
+            uint16_t desc,
             unsigned int socket, const struct rte_eth_rxconf *conf,
             const struct rte_eth_rxseg_split *rx_seg, uint16_t n_seg)
 {
+       uint16_t idx = rxq->idx;
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_rxq_ctrl *tmpl;
        unsigned int mb_len = rte_pktmbuf_data_room_size(rx_seg[0].mp);
@@ -1377,6 +1407,9 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                rte_errno = ENOMEM;
                return NULL;
        }
+       LIST_INIT(&tmpl->owners);
+       rxq->ctrl = tmpl;
+       LIST_INSERT_HEAD(&tmpl->owners, rxq, owner_entry);
        MLX5_ASSERT(n_seg && n_seg <= MLX5_MAX_RXQ_NSEG);
        /*
         * Build the array of actual buffer offsets and lengths.
@@ -1610,6 +1643,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
        tmpl->rxq.rss_hash = !!priv->rss_conf.rss_hf &&
                (!!(dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS));
        tmpl->rxq.port_id = dev->data->port_id;
+       tmpl->sh = priv->sh;
        tmpl->priv = priv;
        tmpl->rxq.mp = rx_seg[0].mp;
        tmpl->rxq.elts_n = log2above(desc);
@@ -1637,8 +1671,8 @@ error:
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param idx
- *   RX queue index.
+ * @param rxq
+ *   RX queue.
  * @param desc
  *   Number of descriptors to configure in queue.
  * @param hairpin_conf
@@ -1648,9 +1682,11 @@ error:
  *   A DPDK queue object on success, NULL otherwise and rte_errno is set.
  */
 struct mlx5_rxq_ctrl *
-mlx5_rxq_hairpin_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
+mlx5_rxq_hairpin_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
+                    uint16_t desc,
                     const struct rte_eth_hairpin_conf *hairpin_conf)
 {
+       uint16_t idx = rxq->idx;
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_rxq_ctrl *tmpl;
 
@@ -1660,10 +1696,14 @@ mlx5_rxq_hairpin_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                rte_errno = ENOMEM;
                return NULL;
        }
+       LIST_INIT(&tmpl->owners);
+       rxq->ctrl = tmpl;
+       LIST_INSERT_HEAD(&tmpl->owners, rxq, owner_entry);
        tmpl->type = MLX5_RXQ_TYPE_HAIRPIN;
        tmpl->socket = SOCKET_ID_ANY;
        tmpl->rxq.rss_hash = 0;
        tmpl->rxq.port_id = dev->data->port_id;
+       tmpl->sh = priv->sh;
        tmpl->priv = priv;
        tmpl->rxq.mp = NULL;
        tmpl->rxq.elts_n = log2above(desc);
@@ -1717,6 +1757,7 @@ mlx5_rxq_release(struct rte_eth_dev *dev, uint16_t idx)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_rxq_ctrl *rxq_ctrl;
+       struct mlx5_rxq_priv *rxq = (*priv->rxq_privs)[idx];
 
        if (priv->rxqs == NULL || (*priv->rxqs)[idx] == NULL)
                return 0;
@@ -1736,9 +1777,12 @@ mlx5_rxq_release(struct rte_eth_dev *dev, uint16_t idx)
        if (!__atomic_load_n(&rxq_ctrl->refcnt, __ATOMIC_RELAXED)) {
                if (rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD)
                        mlx5_mr_btree_free(&rxq_ctrl->rxq.mr_ctrl.cache_bh);
+               LIST_REMOVE(rxq, owner_entry);
                LIST_REMOVE(rxq_ctrl, next);
                mlx5_free(rxq_ctrl);
                (*priv->rxqs)[idx] = NULL;
+               mlx5_free(rxq);
+               (*priv->rxq_privs)[idx] = NULL;
        }
        return 0;
 }