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
- smime.p7s [application/pkcs7-signature] 5469 bytes