From: Xueming Li Date: Thu, 4 Nov 2021 12:33:13 +0000 (+0800) Subject: net/mlx5: split Rx queue into shareable and private X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4cda06c3c35e;hp=53232e3b05a88eedb35ac67ce22ea9b25b37e8a1;p=dpdk.git net/mlx5: split Rx queue into shareable and private 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 Acked-by: Viacheslav Ovsiienko --- diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index dc15688f21..374cc9757a 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -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); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 74af88ec19..4e99fe7d06 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -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. */ diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 81fa8845bb..cde505955d 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -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) { diff --git a/drivers/net/mlx5/mlx5_rx.h b/drivers/net/mlx5/mlx5_rx.h index 69b1263339..fa24f5cdf3 100644 --- a/drivers/net/mlx5/mlx5_rx.h +++ b/drivers/net/mlx5/mlx5_rx.h @@ -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); diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index b2e4389ad6..00df245a5c 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -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; }