Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bnxt_en-3-bug-fixes'

Michael Chan says:

====================
bnxt_en: 3 bug fixes

The first one fixes a memory corruption issue that can happen when
FW resources change during ifdown with TCs created. The next two
fix FW resource reservation logic for TX rings and stats context.
====================

Link: https://patch.msgid.link/20250825175927.459987-1-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+30 -6
+30 -6
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 8016 8016 } 8017 8017 rx_rings = min_t(int, rx_rings, hwr.grp); 8018 8018 hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings); 8019 - if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp)) 8019 + if (bnxt_ulp_registered(bp->edev) && 8020 + hwr.stat > bnxt_get_ulp_stat_ctxs(bp)) 8020 8021 hwr.stat -= bnxt_get_ulp_stat_ctxs(bp); 8021 8022 hwr.cp = min_t(int, hwr.cp, hwr.stat); 8022 8023 rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh); ··· 8025 8024 hwr.rx = rx_rings << 1; 8026 8025 tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx); 8027 8026 hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings; 8027 + if (hwr.tx != bp->tx_nr_rings) { 8028 + netdev_warn(bp->dev, 8029 + "Able to reserve only %d out of %d requested TX rings\n", 8030 + hwr.tx, bp->tx_nr_rings); 8031 + } 8028 8032 bp->tx_nr_rings = hwr.tx; 8029 8033 8030 8034 /* If we cannot reserve all the RX rings, reset the RSS map only ··· 12857 12851 return rc; 12858 12852 } 12859 12853 12854 + static int bnxt_tx_nr_rings(struct bnxt *bp) 12855 + { 12856 + return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc : 12857 + bp->tx_nr_rings_per_tc; 12858 + } 12859 + 12860 + static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp) 12861 + { 12862 + return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings; 12863 + } 12864 + 12860 12865 static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) 12861 12866 { 12862 12867 int rc = 0; ··· 12885 12868 if (rc) 12886 12869 return rc; 12887 12870 12871 + /* Make adjustments if reserved TX rings are less than requested */ 12872 + bp->tx_nr_rings -= bp->tx_nr_rings_xdp; 12873 + bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); 12874 + if (bp->tx_nr_rings_xdp) { 12875 + bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc; 12876 + bp->tx_nr_rings += bp->tx_nr_rings_xdp; 12877 + } 12888 12878 rc = bnxt_alloc_mem(bp, irq_re_init); 12889 12879 if (rc) { 12890 12880 netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); ··· 16349 16325 bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings); 16350 16326 bp->rx_nr_rings = bp->cp_nr_rings; 16351 16327 bp->tx_nr_rings_per_tc = bp->cp_nr_rings; 16352 - bp->tx_nr_rings = bp->tx_nr_rings_per_tc; 16328 + bp->tx_nr_rings = bnxt_tx_nr_rings(bp); 16353 16329 } 16354 16330 16355 16331 static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) ··· 16381 16357 bnxt_trim_dflt_sh_rings(bp); 16382 16358 else 16383 16359 bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings; 16384 - bp->tx_nr_rings = bp->tx_nr_rings_per_tc; 16360 + bp->tx_nr_rings = bnxt_tx_nr_rings(bp); 16385 16361 16386 16362 avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings; 16387 16363 if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) { ··· 16394 16370 rc = __bnxt_reserve_rings(bp); 16395 16371 if (rc && rc != -ENODEV) 16396 16372 netdev_warn(bp->dev, "Unable to reserve tx rings\n"); 16397 - bp->tx_nr_rings_per_tc = bp->tx_nr_rings; 16373 + bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); 16398 16374 if (sh) 16399 16375 bnxt_trim_dflt_sh_rings(bp); 16400 16376 ··· 16403 16379 rc = __bnxt_reserve_rings(bp); 16404 16380 if (rc && rc != -ENODEV) 16405 16381 netdev_warn(bp->dev, "2nd rings reservation failed.\n"); 16406 - bp->tx_nr_rings_per_tc = bp->tx_nr_rings; 16382 + bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); 16407 16383 } 16408 16384 if (BNXT_CHIP_TYPE_NITRO_A0(bp)) { 16409 16385 bp->rx_nr_rings++; ··· 16437 16413 if (rc) 16438 16414 goto init_dflt_ring_err; 16439 16415 16440 - bp->tx_nr_rings_per_tc = bp->tx_nr_rings; 16416 + bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); 16441 16417 16442 16418 bnxt_set_dflt_rfs(bp); 16443 16419