From: Wenzhuo Lu Date: Thu, 24 Mar 2016 15:22:04 +0000 (+0000) Subject: ixgbe: fix dropping packets from unsupported Tx queues X-Git-Tag: spdx-start~7171 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=96c0450dff86b54834b2ac212feac60382659caa;p=dpdk.git ixgbe: fix dropping packets from unsupported Tx queues Ixgbe HW supports 128 TX queues. However, the full 128 queues are only available in VT and DCB mode. In normal default "none" mode (VT/DCB off) the maximum number of available queues is only 64. The driver doesn't check the mode when reporting the available number of queues, allowing more that 64 queues to be used in all cases. If a queue no. >=64 is used in default mode, the TX packets will be dropped silently. This change adds a check to forbid using a queue number larger than 64 during device configuration (in default mode), so that the problem is reported as early as possible. Fixes: 27b609cbd1c6 ("ethdev: move the multi-queue mode check to specific drivers") Signed-off-by: Wenzhuo Lu Signed-off-by: Pablo de Lara Acked-by: John McNamara --- diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst index b3229ed747..a4f54a5273 100644 --- a/doc/guides/rel_notes/release_16_04.rst +++ b/doc/guides/rel_notes/release_16_04.rst @@ -343,6 +343,12 @@ Drivers The driver now set the MDIO clock speed prior to initializing PHY ops and again after the MAC reset. +* **ixgbe: Fixed maximum number of available TX queues.** + + In IXGBE, the maximum number of TX queues varies depending on the NIC operating + mode. This was not being updated in the device information, providing + an incorrect number in some cases. + * **i40e: Generated MAC address for each VFs.** It generates a MAC address for each VFs during PF host initialization, diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 0d5a4e8d05..8ed6cafa50 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -1864,6 +1864,7 @@ static int ixgbe_check_mq_mode(struct rte_eth_dev *dev) { struct rte_eth_conf *dev_conf = &dev->data->dev_conf; + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint16_t nb_rx_q = dev->data->nb_rx_queues; uint16_t nb_tx_q = dev->data->nb_tx_queues; @@ -2005,6 +2006,21 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev) return -EINVAL; } } + + /* + * When DCB/VT is off, maximum number of queues changes, + * except for 82598EB, which remains constant. + */ + if (dev_conf->txmode.mq_mode == ETH_MQ_TX_NONE && + hw->mac.type != ixgbe_mac_82598EB) { + if (nb_tx_q > IXGBE_NONE_MODE_TX_NB_QUEUES) { + PMD_INIT_LOG(ERR, + "Neither VT nor DCB are enabled, " + "nb_tx_q > %d.", + IXGBE_NONE_MODE_TX_NB_QUEUES); + return -EINVAL; + } + } } return 0; } @@ -2859,9 +2875,19 @@ static void ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_eth_conf *dev_conf = &dev->data->dev_conf; dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues; dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues; + if (RTE_ETH_DEV_SRIOV(dev).active == 0) { + /* + * When DCB/VT is off, maximum number of queues changes, + * except for 82598EB, which remains constant. + */ + if (dev_conf->txmode.mq_mode == ETH_MQ_TX_NONE && + hw->mac.type != ixgbe_mac_82598EB) + dev_info->max_tx_queues = IXGBE_NONE_MODE_TX_NB_QUEUES; + } dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL register */ dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */ dev_info->max_mac_addrs = hw->mac.num_rar_entries; diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h index b75e7959b9..a7b1eb51f9 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.h +++ b/drivers/net/ixgbe/ixgbe_ethdev.h @@ -61,6 +61,7 @@ #define IXGBE_MAX_RX_QUEUE_NUM 128 #define IXGBE_VMDQ_DCB_NB_QUEUES IXGBE_MAX_RX_QUEUE_NUM #define IXGBE_DCB_NB_QUEUES IXGBE_MAX_RX_QUEUE_NUM +#define IXGBE_NONE_MODE_TX_NB_QUEUES 64 #ifndef NBBY #define NBBY 8 /* number of bits in a byte */