Thread (3 messages) flat view 3 messages, 2 authors, 21d ago

Re: [PATCH net] net: bnxt: ring the doorbell when SW USO exits early

From: Michael Chan <michael.chan@broadcom.com>
Date: 2026-08-18 22:36:56
Also in: lkml, stable

On Tue, Aug 18, 2026 at 2:15 PM Joe Damato [off-list ref] wrote:
quoted hunk ↗ jump to hunk
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index bc7b37cb74a7..b6cc755f7a04 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -459,8 +459,7 @@ u16 bnxt_xmit_get_cfa_action(struct sk_buff *skb)
        return md_dst->u.port_info.port_id;
 }

-static void bnxt_txr_db_kick(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
-                            u16 prod)
+void bnxt_txr_db_kick(struct bnxt *bp, struct bnxt_tx_ring_info *txr, u16 prod)
 {
        /* Sync BD data before updating doorbell */
        wmb();
@@ -485,6 +484,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct bnxt_sw_tx_bd *tx_buf;
        __le32 lflags = 0;
        skb_frag_t *frag;
+       netdev_tx_t ret;

        i = skb_get_queue_mapping(skb);
        if (unlikely(i >= bp->tx_nr_rings)) {
@@ -510,8 +510,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
        if (skb_is_gso(skb) &&
            (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) &&
-           !(bp->flags & BNXT_FLAG_UDP_GSO_CAP))
-               return bnxt_sw_udp_gso_xmit(bp, txr, txq, skb);
+           !(bp->flags & BNXT_FLAG_UDP_GSO_CAP)) {
+               /* if the USO code exits early (for example, it returns
+                * NETDEV_TX_BUSY) make sure we ring any outstanding doorbells
+                * for any BDs in the ring before returning.
+                */
+               ret = bnxt_sw_udp_gso_xmit(bp, txr, txq, skb);
+               if (txr->kick_pending)
+                       bnxt_txr_db_kick(bp, txr, txr->tx_prod);
+
+               return ret;
+       }

        free_size = bnxt_tx_avail(bp, txr);
        if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index dc8ec5e5733e..60fbe3cabcf9 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -3009,6 +3009,8 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
 void bnxt_tx_disable(struct bnxt *bp);
 void bnxt_tx_enable(struct bnxt *bp);
 u16 bnxt_xmit_get_cfa_action(struct sk_buff *skb);
+void bnxt_txr_db_kick(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+                     u16 prod);
 void bnxt_sched_reset_txr(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
                          u16 curr);
 void bnxt_report_link(struct bnxt *bp);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c
index f317f60414e8..3c58b1d94ac9 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c
@@ -223,9 +223,7 @@ netdev_tx_t bnxt_sw_udp_gso_xmit(struct bnxt *bp,
        netdev_tx_sent_queue(txq, skb->len);

        WRITE_ONCE(txr->tx_prod, prod);
-       /* Sync BDs before doorbell */
-       wmb();
-       bnxt_db_write(bp, &txr->tx_db, prod);
+       bnxt_txr_db_kick(bp, txr, prod);
The patch looks good to me.  But a slightly simpler approach is to
just set txr->kick_pending here.  Upon return, the new logic above
will always ring the doorbell for the success case.  By doing this, we
don't need to export bnxt_txr_db_kick().

But your patch is fine too, so:
Reviewed-by: Michael Chan <michael.chan@broadcom.com>

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help