RE: [EXTERNAL] Re: [PATCH net] net: mana: Ring doorbell at 4 CQ wraparounds

From: Long Li

Date: Thu Feb 26 2026 - 14:31:12 EST


> Subject: [EXTERNAL] Re: [PATCH net] net: mana: Ring doorbell at 4 CQ
> wraparounds
>
> On 25/02/2026 18:49, Long Li wrote:
> > MANA hardware requires at least one doorbell ring every 8 wraparounds
> > of the CQ. The driver rings the doorbell as a form of flow control to
> > inform hardware that CQEs have been consumed.
> >
> > The NAPI poll functions mana_poll_tx_cq() and mana_poll_rx_cq() can
> > poll up to CQE_POLLING_BUFFER (512) completions per call. If the CQ
> > has fewer than 512 entries, a single poll call can process more than
> > 4 wraparounds without ringing the doorbell. The doorbell threshold
> > check also uses ">" instead of ">=", delaying the ring by one extra
> > CQE beyond 4 wraparounds. Combined, these issues can cause the driver
> > to exceed the 8-wraparound hardware limit, leading to missed
> > completions and stalled queues.
> >
> > Fix this by capping the number of CQEs polled per call to 4
> > wraparounds of the CQ in both TX and RX paths. Also change the
> > doorbell threshold from ">" to ">=" so the doorbell is rung as soon as
> > 4 wraparounds are reached.
> >
> > Cc: stable@xxxxxxxxxxxxxxx
> > Fixes: 58a63729c957 ("net: mana: Fix doorbell out of order violation
> > and avoid unnecessary doorbell rings")
> > Signed-off-by: Long Li <longli@xxxxxxxxxxxxx>
> > ---
> > drivers/net/ethernet/microsoft/mana/mana_en.c | 23 +++++++++++++++----
> > 1 file changed, 18 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > index 9919183ad39e..fe667e0d930d 100644
> > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > @@ -1770,8 +1770,14 @@ static void mana_poll_tx_cq(struct mana_cq *cq)
> > ndev = txq->ndev;
> > apc = netdev_priv(ndev);
> >
> > + /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the
> > + * doorbell can be rung in time for the hardware's requirement
> > + * of at least one doorbell ring every 8 wraparounds.
> > + */
> > comp_read = mana_gd_poll_cq(cq->gdma_cq, completions,
> > - CQE_POLLING_BUFFER);
> > + min_t(u32, (cq->gdma_cq->queue_size /
>
> no need for min_t, simple min() can be used, queue_size is already u32

Thank you, I'm sending v2.

Long

>
> > + COMP_ENTRY_SIZE) * 4,
> > + CQE_POLLING_BUFFER));
> >
> > if (comp_read < 1)
> > return;
> > @@ -2156,7 +2162,14 @@ static void mana_poll_rx_cq(struct mana_cq *cq)
> > struct mana_rxq *rxq = cq->rxq;
> > int comp_read, i;
> >
> > - comp_read = mana_gd_poll_cq(cq->gdma_cq, comp,
> CQE_POLLING_BUFFER);
> > + /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the
> > + * doorbell can be rung in time for the hardware's requirement
> > + * of at least one doorbell ring every 8 wraparounds.
> > + */
> > + comp_read = mana_gd_poll_cq(cq->gdma_cq, comp,
> > + min_t(u32, (cq->gdma_cq->queue_size /
>
> same here
>
> > + COMP_ENTRY_SIZE) * 4,
> > + CQE_POLLING_BUFFER));
> > WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER);
> >
> > rxq->xdp_flush = false;