From: Edwin Brossette <edwin.brosse...@6wind.com>

When the MTU configured is lower than maximum mbuf size (all packet data
can be stored in a single mbuf), then rx buffer size is configured with
MTU + some overhead. A flooring is applied to this value to align it,
meaning its actual value is going to be lower than expected.

This is a considerable design flaw, because a data packet fitting
exactly the MTU might not fit in the rx buffer. What is observed in this
case is that the nic splits the datagram in two segments, essentially
doing Rx scatter. However, the qede pmd does not expect gather scatter
in this case and does not use the required function: it uses
qede_recv_pkts_regular() which is not capable of handling this case.

Thus, we end up with malformed packet with m->nb_segs = 2 and
m->next = NULL. This means the last part of the data is missing.

CEIL max_rx_pktlen instead of FLOORing it. Also change the check on
max_rx_pktlen > bufsz in qede_rx_queue_setup(): if this ceiling would
make max_rx_pktlen exceed mbuf size, then force enable scatter-gather
mode.

Fixes: 318d7da3122b ("net/qede: fix Rx buffer size calculation")
CC: sta...@dpdk.org

Signed-off-by: Edwin Brossette <edwin.brosse...@6wind.com>
Acked-by: Didier Pallard <didier.pall...@6wind.com>
---
 drivers/net/qede/qede_rxtx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index ea77f09e18be..2a6f1290ad4a 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -111,7 +111,7 @@ qede_calc_rx_buf_size(struct rte_eth_dev *dev, uint16_t 
mbufsz,
                rx_buf_size = max_frame_size;
 
        /* Align to cache-line size if needed */
-       return QEDE_FLOOR_TO_CACHE_LINE_SIZE(rx_buf_size);
+       return QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
 }
 
 static struct qede_rx_queue *
@@ -237,7 +237,7 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qid,
        /* cache align the mbuf size to simplify rx_buf_size calculation */
        bufsz = QEDE_FLOOR_TO_CACHE_LINE_SIZE(bufsz);
        if ((rxmode->offloads & RTE_ETH_RX_OFFLOAD_SCATTER)     ||
-           max_rx_pktlen > bufsz) {
+           QEDE_CEIL_TO_CACHE_LINE_SIZE(max_rx_pktlen) > bufsz) {
                if (!dev->data->scattered_rx) {
                        DP_INFO(edev, "Forcing scatter-gather mode\n");
                        dev->data->scattered_rx = 1;
-- 
2.35.0.4.g44a5d4affccf

Reply via email to