From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id 4D9472BD7 for ; Fri, 25 Mar 2016 11:25:00 +0100 (CET) Received: from glumotte.dev.6wind.com (unknown [10.16.0.195]) by proxy.6wind.com (Postfix) with ESMTP id 79B7C259DA; Fri, 25 Mar 2016 11:24:17 +0100 (CET) From: Olivier Matz To: dev@dpdk.org Cc: bruce.richardson@intel.com, adrien.mazarguil@6wind.com Date: Fri, 25 Mar 2016 11:24:41 +0100 Message-Id: <1458901481-21227-1-git-send-email-olivier.matz@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1458576484-28211-1-git-send-email-olivier.matz@6wind.com> References: <1458576484-28211-1-git-send-email-olivier.matz@6wind.com> Subject: [dpdk-dev] [PATCH v2] mlx4: use dummy rxqs when a non-pow2 number is requested X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Mar 2016 10:25:00 -0000 When using RSS, the number of rxqs has to be a power of two. This is a problem because there is no API in DPDK that makes the application aware of that. A good compromise is to allow the application to request a number of rxqs that is not a power of 2, but having inactive queues that will never receive packets. In this configuration, a warning will be issued to users to let them know that this is not an optimal configuration. Signed-off-by: Olivier Matz Acked-by: Adrien Mazarguil --- drivers/net/mlx4/mlx4.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index cc4e9aa..a183927 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -698,7 +698,7 @@ txq_cleanup(struct txq *txq); static int rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc, - unsigned int socket, const struct rte_eth_rxconf *conf, + unsigned int socket, int inactive, const struct rte_eth_rxconf *conf, struct rte_mempool *mp); static void @@ -734,12 +734,15 @@ dev_configure(struct rte_eth_dev *dev) } if (rxqs_n == priv->rxqs_n) return 0; - if ((rxqs_n & (rxqs_n - 1)) != 0) { - ERROR("%p: invalid number of RX queues (%u)," - " must be a power of 2", - (void *)dev, rxqs_n); - return EINVAL; + if (!rte_is_power_of_2(rxqs_n)) { + unsigned n_active; + + n_active = rte_align32pow2(rxqs_n + 1) >> 1; + WARN("%p: number of RX queues must be a power" + " of 2: %u queues among %u will be active", + (void *)dev, n_active, rxqs_n); } + INFO("%p: RX queues number update: %u -> %u", (void *)dev, priv->rxqs_n, rxqs_n); /* If RSS is enabled, disable it first. */ @@ -775,7 +778,7 @@ dev_configure(struct rte_eth_dev *dev) priv->rss = 1; tmp = priv->rxqs_n; priv->rxqs_n = rxqs_n; - ret = rxq_setup(dev, &priv->rxq_parent, 0, 0, NULL, NULL); + ret = rxq_setup(dev, &priv->rxq_parent, 0, 0, 0, NULL, NULL); if (!ret) return 0; /* Failure, rollback. */ @@ -3466,7 +3469,8 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc, attr.qpg.qpg_type = IBV_EXP_QPG_PARENT; /* TSS isn't necessary. */ attr.qpg.parent_attrib.tss_child_count = 0; - attr.qpg.parent_attrib.rss_child_count = priv->rxqs_n; + attr.qpg.parent_attrib.rss_child_count = + rte_align32pow2(priv->rxqs_n + 1) >> 1; DEBUG("initializing parent RSS queue"); } else { attr.qpg.qpg_type = IBV_EXP_QPG_CHILD_RX; @@ -3689,6 +3693,9 @@ skip_rtr: * Number of descriptors to configure in queue. * @param socket * NUMA socket on which memory must be allocated. + * @param inactive + * If true, the queue is disabled because its index is higher or + * equal to the real number of queues, which must be a power of 2. * @param[in] conf * Thresholds parameters. * @param mp @@ -3699,7 +3706,7 @@ skip_rtr: */ static int rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc, - unsigned int socket, const struct rte_eth_rxconf *conf, + unsigned int socket, int inactive, const struct rte_eth_rxconf *conf, struct rte_mempool *mp) { struct priv *priv = dev->data->dev_private; @@ -3800,7 +3807,7 @@ skip_mr: DEBUG("priv->device_attr.max_sge is %d", priv->device_attr.max_sge); #ifdef RSS_SUPPORT - if (priv->rss) + if (priv->rss && !inactive) tmpl.qp = rxq_setup_qp_rss(priv, tmpl.cq, desc, parent, tmpl.rd); else @@ -3936,6 +3943,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, { struct priv *priv = dev->data->dev_private; struct rxq *rxq = (*priv->rxqs)[idx]; + int inactive = 0; int ret; if (mlx4_is_secondary()) @@ -3967,7 +3975,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, return -ENOMEM; } } - ret = rxq_setup(dev, rxq, desc, socket, conf, mp); + if (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1) + inactive = 1; + ret = rxq_setup(dev, rxq, desc, socket, inactive, conf, mp); if (ret) rte_free(rxq); else { -- 2.1.4