[PATCH 19.11] net/cxgbe: fix Tx queue stuck with mbuf chain coalescing

Christian Ehrhardt christian.ehrhardt at canonical.com
Wed Aug 3 11:52:26 CEST 2022


On Sat, Jul 16, 2022 at 3:04 PM Rahul Lakkireddy
<rahul.lakkireddy at chelsio.com> wrote:
>
> [ upstream commit 151e828f6427667faf3fdfaa00d14a65c7f57cd6 ]

Thank you,
your patch was in time, but sadly a few fell through the cracks on my side.
(and many more just arrived too late).

Your patch is applied to the WIP branch now, but currently testing of
-rc1 is going on which I do not want to disrupt.

If we need an -rc2 anyway or generally have the time to do an -rc2
without too much disruption it will be in 19.11.13, otherwise it is
already queued for 19.11.14

> When trying to coalesce mbufs with chain on Tx side, it is possible
> to get stuck during queue wrap around. When coalescing this mbuf
> chain fails, the Tx path returns EBUSY and when the same packet
> is retried again, it couldn't get coalesced again, and the loop
> repeats. Fix by pushing the packet through the normal Tx path.
> Also use FW_ETH_TX_PKTS_WR to handle mbufs with chain for FW
> to optimize.
>
> Fixes: 6c2809628cd5 ("net/cxgbe: improve latency for slow traffic")
> Cc: stable at dpdk.org
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy at chelsio.com>
> ---
>  drivers/net/cxgbe/sge.c | 38 +++++++++++++++++++++++---------------
>  1 file changed, 23 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
> index 61ee218be..f3ff576cf 100644
> --- a/drivers/net/cxgbe/sge.c
> +++ b/drivers/net/cxgbe/sge.c
> @@ -793,9 +793,9 @@ static inline void txq_advance(struct sge_txq *q, unsigned int n)
>
>  #define MAX_COALESCE_LEN 64000
>
> -static inline int wraps_around(struct sge_txq *q, int ndesc)
> +static inline bool wraps_around(struct sge_txq *q, int ndesc)
>  {
> -       return (q->pidx + ndesc) > q->size ? 1 : 0;
> +       return (q->pidx + ndesc) > q->size ? true : false;
>  }
>
>  static void tx_timer_cb(void *data)
> @@ -846,7 +846,6 @@ static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap,
>
>         /* fill the pkts WR header */
>         wr = (void *)&q->desc[q->pidx];
> -       wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR));
>         vmwr = (void *)&q->desc[q->pidx];
>
>         wr_mid = V_FW_WR_LEN16(DIV_ROUND_UP(q->coalesce.flits, 2));
> @@ -856,8 +855,11 @@ static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap,
>         wr->npkt = q->coalesce.idx;
>         wr->r3 = 0;
>         if (is_pf4(adap)) {
> -               wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR));
>                 wr->type = q->coalesce.type;
> +               if (likely(wr->type != 0))
> +                       wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR));
> +               else
> +                       wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_WR));
>         } else {
>                 wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_VM_WR));
>                 vmwr->r4 = 0;
> @@ -936,13 +938,16 @@ static inline int should_tx_packet_coalesce(struct sge_eth_txq *txq,
>                 ndesc = DIV_ROUND_UP(q->coalesce.flits + flits, 8);
>                 credits = txq_avail(q) - ndesc;
>
> +               if (unlikely(wraps_around(q, ndesc)))
> +                       return 0;
> +
>                 /* If we are wrapping or this is last mbuf then, send the
>                  * already coalesced mbufs and let the non-coalesce pass
>                  * handle the mbuf.
>                  */
> -               if (unlikely(credits < 0 || wraps_around(q, ndesc))) {
> +               if (unlikely(credits < 0)) {
>                         ship_tx_pkt_coalesce_wr(adap, txq);
> -                       return 0;
> +                       return -EBUSY;
>                 }
>
>                 /* If the max coalesce len or the max WR len is reached
> @@ -966,8 +971,12 @@ static inline int should_tx_packet_coalesce(struct sge_eth_txq *txq,
>         ndesc = flits_to_desc(q->coalesce.flits + flits);
>         credits = txq_avail(q) - ndesc;
>
> -       if (unlikely(credits < 0 || wraps_around(q, ndesc)))
> +       if (unlikely(wraps_around(q, ndesc)))
>                 return 0;
> +
> +       if (unlikely(credits < 0))
> +               return -EBUSY;
> +
>         q->coalesce.flits += wr_size / sizeof(__be64);
>         q->coalesce.type = type;
>         q->coalesce.ptr = (unsigned char *)&q->desc[q->pidx] +
> @@ -1110,7 +1119,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>         unsigned int flits, ndesc, cflits;
>         int l3hdr_len, l4hdr_len, eth_xtra_len;
>         int len, last_desc;
> -       int credits;
> +       int should_coal, credits;
>         u32 wr_mid;
>         u64 cntrl, *end;
>         bool v6;
> @@ -1141,9 +1150,9 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>         /* align the end of coalesce WR to a 512 byte boundary */
>         txq->q.coalesce.max = (8 - (txq->q.pidx & 7)) * 8;
>
> -       if (!((m->ol_flags & PKT_TX_TCP_SEG) ||
> -                       m->pkt_len > RTE_ETHER_MAX_LEN)) {
> -               if (should_tx_packet_coalesce(txq, mbuf, &cflits, adap)) {
> +       if ((m->ol_flags & PKT_TX_TCP_SEG) == 0) {
> +               should_coal = should_tx_packet_coalesce(txq, mbuf, &cflits, adap);
> +               if (should_coal > 0) {
>                         if (unlikely(map_mbuf(mbuf, addr) < 0)) {
>                                 dev_warn(adap, "%s: mapping err for coalesce\n",
>                                          __func__);
> @@ -1152,8 +1161,8 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>                         }
>                         return tx_do_packet_coalesce(txq, mbuf, cflits, adap,
>                                                      pi, addr, nb_pkts);
> -               } else {
> -                       return -EBUSY;
> +               } else if (should_coal < 0) {
> +                       return should_coal;
>                 }
>         }
>
> @@ -1200,8 +1209,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>                 end = (u64 *)vmwr + flits;
>         }
>
> -       len = 0;
> -       len += sizeof(*cpl);
> +       len = sizeof(*cpl);
>
>         /* Coalescing skipped and we send through normal path */
>         if (!(m->ol_flags & PKT_TX_TCP_SEG)) {
> --
> 2.27.0
>


-- 
Christian Ehrhardt
Senior Staff Engineer, Ubuntu Server
Canonical Ltd


More information about the stable mailing list