Skip to content

Commit ffeafa6

Browse files
Srijit Bosekuba-moo
authored andcommitted
bnxt_en: Fix potential data corruption with HW GRO/LRO
Fix the max number of bits passed to find_first_zero_bit() in bnxt_alloc_agg_idx(). We were incorrectly passing the number of long words. find_first_zero_bit() may fail to find a zero bit and cause a wrong ID to be used. If the wrong ID is already in use, this can cause data corruption. Sometimes an error like this can also be seen: bnxt_en 0000:83:00.0 enp131s0np0: TPA end agg_buf 2 != expected agg_bufs 1 Fix it by passing the correct number of bits MAX_TPA_P5. Use DECLARE_BITMAP() to more cleanly define the bitmap. Add a sanity check to warn if a bit cannot be found and reset the ring [MChan]. Fixes: ec4d8e7 ("bnxt_en: Add TPA ID mapping logic for 57500 chips.") Reviewed-by: Ray Jui <[email protected]> Signed-off-by: Srijit Bose <[email protected]> Signed-off-by: Michael Chan <[email protected]> Reviewed-by: Vadim Fedorenko <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 92e6e0a commit ffeafa6

2 files changed

Lines changed: 13 additions & 6 deletions

File tree

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,9 +1482,11 @@ static u16 bnxt_alloc_agg_idx(struct bnxt_rx_ring_info *rxr, u16 agg_id)
14821482
struct bnxt_tpa_idx_map *map = rxr->rx_tpa_idx_map;
14831483
u16 idx = agg_id & MAX_TPA_P5_MASK;
14841484

1485-
if (test_bit(idx, map->agg_idx_bmap))
1486-
idx = find_first_zero_bit(map->agg_idx_bmap,
1487-
BNXT_AGG_IDX_BMAP_SIZE);
1485+
if (test_bit(idx, map->agg_idx_bmap)) {
1486+
idx = find_first_zero_bit(map->agg_idx_bmap, MAX_TPA_P5);
1487+
if (idx >= MAX_TPA_P5)
1488+
return INVALID_HW_RING_ID;
1489+
}
14881490
__set_bit(idx, map->agg_idx_bmap);
14891491
map->agg_id_tbl[agg_id] = idx;
14901492
return idx;
@@ -1548,6 +1550,13 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
15481550
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
15491551
agg_id = TPA_START_AGG_ID_P5(tpa_start);
15501552
agg_id = bnxt_alloc_agg_idx(rxr, agg_id);
1553+
if (unlikely(agg_id == INVALID_HW_RING_ID)) {
1554+
netdev_warn(bp->dev, "Unable to allocate agg ID for ring %d, agg 0x%x\n",
1555+
rxr->bnapi->index,
1556+
TPA_START_AGG_ID_P5(tpa_start));
1557+
bnxt_sched_reset_rxr(bp, rxr);
1558+
return;
1559+
}
15511560
} else {
15521561
agg_id = TPA_START_AGG_ID(tpa_start);
15531562
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,11 +1080,9 @@ struct bnxt_tpa_info {
10801080
struct rx_agg_cmp *agg_arr;
10811081
};
10821082

1083-
#define BNXT_AGG_IDX_BMAP_SIZE (MAX_TPA_P5 / BITS_PER_LONG)
1084-
10851083
struct bnxt_tpa_idx_map {
10861084
u16 agg_id_tbl[1024];
1087-
unsigned long agg_idx_bmap[BNXT_AGG_IDX_BMAP_SIZE];
1085+
DECLARE_BITMAP(agg_idx_bmap, MAX_TPA_P5);
10881086
};
10891087

10901088
struct bnxt_rx_ring_info {

0 commit comments

Comments
 (0)