Skip to content

Commit 7011ba3

Browse files
committed
Merge branch 'bnxt_en-fix-max_skb_frags-30'
Michael Chan says: ==================== bnxt_en: Fix MAX_SKB_FRAGS > 30 The driver was written with the assumption that MAX_SKB_FRAGS could not exceed what the NIC can support. About 2 years ago, CONFIG_MAX_SKB_FRAGS was added. The value can exceed what the NIC can support and it may cause TX timeout. These 2 patches will fix the issue. ==================== Link: https://patch.msgid.link/20250321211639.3812992-1-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 3865bec + b91e821 commit 7011ba3

3 files changed

Lines changed: 20 additions & 4 deletions

File tree

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
485485
txr = &bp->tx_ring[bp->tx_ring_map[i]];
486486
prod = txr->tx_prod;
487487

488+
#if (MAX_SKB_FRAGS > TX_MAX_FRAGS)
489+
if (skb_shinfo(skb)->nr_frags > TX_MAX_FRAGS) {
490+
netdev_warn_once(dev, "SKB has too many (%d) fragments, max supported is %d. SKB will be linearized.\n",
491+
skb_shinfo(skb)->nr_frags, TX_MAX_FRAGS);
492+
if (skb_linearize(skb)) {
493+
dev_kfree_skb_any(skb);
494+
dev_core_stats_tx_dropped_inc(dev);
495+
return NETDEV_TX_OK;
496+
}
497+
}
498+
#endif
488499
free_size = bnxt_tx_avail(bp, txr);
489500
if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
490501
/* We must have raced with NAPI cleanup */
@@ -564,7 +575,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
564575
TX_BD_FLAGS_LHINT_512_AND_SMALLER |
565576
TX_BD_FLAGS_COAL_NOW |
566577
TX_BD_FLAGS_PACKET_END |
567-
(2 << TX_BD_FLAGS_BD_CNT_SHIFT));
578+
TX_BD_CNT(2));
568579

569580
if (skb->ip_summed == CHECKSUM_PARTIAL)
570581
tx_push1->tx_bd_hsize_lflags =
@@ -639,7 +650,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
639650

640651
dma_unmap_addr_set(tx_buf, mapping, mapping);
641652
flags = (len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_LONG_TX_BD |
642-
((last_frag + 2) << TX_BD_FLAGS_BD_CNT_SHIFT);
653+
TX_BD_CNT(last_frag + 2);
643654

644655
txbd->tx_bd_haddr = cpu_to_le64(mapping);
645656
txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 2 + last_frag);

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ struct tx_bd {
8282
#define TX_OPAQUE_PROD(bp, opq) ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\
8383
(bp)->tx_ring_mask)
8484

85+
#define TX_BD_CNT(n) (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT)
86+
87+
#define TX_MAX_BD_CNT 32
88+
89+
#define TX_MAX_FRAGS (TX_MAX_BD_CNT - 2)
90+
8591
struct tx_bd_ext {
8692
__le32 tx_bd_hsize_lflags;
8793
#define TX_BD_FLAGS_TCP_UDP_CHKSUM (1 << 0)

drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
4848
tx_buf->page = virt_to_head_page(xdp->data);
4949

5050
txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
51-
flags = (len << TX_BD_LEN_SHIFT) |
52-
((num_frags + 1) << TX_BD_FLAGS_BD_CNT_SHIFT) |
51+
flags = (len << TX_BD_LEN_SHIFT) | TX_BD_CNT(num_frags + 1) |
5352
bnxt_lhint_arr[len >> 9];
5453
txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
5554
txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 1 + num_frags);

0 commit comments

Comments
 (0)