The bonding driver creates a minimal-sized Rx ring as part of the setup,
using the driver default parameters as it does so. However, for some
cases the default values need adjustment for absolute minimal sized
rings which can cause failures - for example, having an free threshold
of 32 is too large for a ring of size 64.

Unfortunately, the drivers themselves cannot properly handle this by
adjusting their defaults because:
a) the defaults are returned from info_get which gets called before the
desired ring-size is known
b) the replacement of the NULL rxconf value, which indicates use of
defaults, happens at the ethdev level, so the driver is unaware of the
source of the requested parameters - whether they are explicitly set by
the user or substituted by ethdev layer.

Therefore, we modify the bonding PMD to clamp the free thresh value to
ring_size / 4 which should work in all cases.

Fixes: 4da0705bf896 ("net/bonding: fix dedicated queue setup")
Cc: [email protected]

Signed-off-by: Bruce Richardson <[email protected]>
---
 drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c 
b/drivers/net/bonding/rte_eth_bond_pmd.c
index b7bab6bc99..96725071da 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1701,11 +1701,18 @@ member_configure_slow_queue(struct rte_eth_dev 
*bonding_eth_dev,
                if (member_info.rx_desc_lim.nb_min != 0)
                        nb_rx_desc = member_info.rx_desc_lim.nb_min;
 
-               /* Configure slow Rx queue */
+               /* Configure slow Rx queue.
+                * Use explicit conf rather than NULL so we can clamp 
rx_free_thresh:
+                * with a minimum-sized ring the default rx_free_thresh may be 
too large
+                * for some drivers to work correctly, so clamp it to ring_size 
/ 4.
+                */
+               struct rte_eth_rxconf slow_rx_conf = member_info.default_rxconf;
+               if (slow_rx_conf.rx_free_thresh > nb_rx_desc / 4)
+                       slow_rx_conf.rx_free_thresh = nb_rx_desc / 4;
                errval = rte_eth_rx_queue_setup(member_eth_dev->data->port_id,
                                internals->mode4.dedicated_queues.rx_qid, 
nb_rx_desc,
                                
rte_eth_dev_socket_id(member_eth_dev->data->port_id),
-                               NULL, port->slow_pool);
+                               &slow_rx_conf, port->slow_pool);
                if (errval != 0) {
                        RTE_BOND_LOG(ERR,
                                        "rte_eth_rx_queue_setup: port=%d 
queue_id %d, err (%d)",
-- 
2.51.0

Reply via email to