> 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: [email protected]
> > Fixes: 58a63729c957 ("net: mana: Fix doorbell out of order violation
> > and avoid unnecessary doorbell rings")
> > Signed-off-by: Long Li <[email protected]>
> > ---
> >   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;

Reply via email to