[PATCH 7.1 094/271] bnxt_en: Determine and store default RX ring in vnic structure
Greg Kroah-Hartman <[email protected]>
| Newsgroups | dev.linux.lists.patches,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
7.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Shravya KN <[email protected]> [ Upstream commit 53f01cd594e223aabb538d5288e60111523c96f2 ] Each VNIC has a default RX ring. The purpose of the default RX ring is to provide a destination for any packets that cannot be parsed by the RSS logic. Up until now, the default RX ring is always Ring 0. We neglected to take care of this default RX ring when adding the queue restart feature. If ring 0 (default ring) is re-started, it may now have a new FW ring ID after freeing the old one and allocating a new one. The VNIC now may have a stale default ring and it may generate an internal exception. This exception may appear in dmesg: FW reported unknown error type 10 The best way to resolve this issue is to use a more appropriate ring for the default ring instead of always ring 0. Ring 0 may not even be in the RSS table, especially on a new RSS context. This patch adds the logic to determine and store the proper default RX ring for a VNIC. For an RSS VNIC, the default ring is the lowest ring number in the RSS table. The next patch will add proper logic to update the VNIC if the default ring changes after queue restart. Reviewed-by: Kalesh AP <[email protected]> Reviewed-by: Pavan Chebbi <[email protected]> Signed-off-by: Shravya KN <[email protected]> Signed-off-by: Michael Chan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Stable-dep-of: 0b137529a899 ("bnxt_en: Refresh VNIC default ring on queue restart if needed") Signed-off-by: Sasha Levin <[email protected]> --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 33 +++++++++++++++-------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 2fbc98fa14f62..4ea6adfc5c22a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6704,25 +6704,36 @@ int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings) static void bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic) { bool no_rss = !(vnic->flags & BNXT_VNIC_RSS_FLAG); - u16 i, j; + u16 i, j, min_j = bp->rx_nr_rings - 1; if (!vnic->rss_table) - return; + goto skip_rss_tbl; /* Fill the RSS indirection table with ring group ids */ for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++) { if (!no_rss) j = bp->rss_indir_tbl[i]; + min_j = min(j, min_j); vnic->rss_table[i] = cpu_to_le16(vnic->fw_grp_ids[j]); } + +skip_rss_tbl: + if (vnic->rss_table && !no_rss) + vnic->default_rx_ring = min_j; + else if (vnic->flags & BNXT_VNIC_RFS_FLAG) + vnic->default_rx_ring = vnic->vnic_id - 1; + else if ((vnic->vnic_id == 1) && BNXT_CHIP_TYPE_NITRO_A0(bp)) + vnic->default_rx_ring = bp->rx_nr_rings - 1; + else + vnic->default_rx_ring = 0; } static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) { + u16 tbl_size, i, min_j = bp->rx_nr_rings - 1; __le16 *ring_tbl = vnic->rss_table; struct bnxt_rx_ring_info *rxr; - u16 tbl_size, i; tbl_size = bnxt_get_rxfh_indir_size(bp->dev); @@ -6735,6 +6746,7 @@ static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp, j = ethtool_rxfh_context_indir(vnic->rss_ctx)[i]; else j = bp->rss_indir_tbl[i]; + min_j = min(j, min_j); rxr = &bp->rx_ring[j]; ring_id = rxr->rx_ring_struct.fw_ring_id; @@ -6742,6 +6754,7 @@ static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp, ring_id = bnxt_cp_ring_for_rx(bp, rxr); *ring_tbl++ = cpu_to_le16(ring_id); } + vnic->default_rx_ring = min_j; } static void @@ -6938,8 +6951,9 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) return rc; if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { - struct bnxt_rx_ring_info *rxr = &bp->rx_ring[0]; + struct bnxt_rx_ring_info *rxr; + rxr = &bp->rx_ring[vnic->default_rx_ring]; req->default_rx_ring_id = cpu_to_le16(rxr->rx_ring_struct.fw_ring_id); req->default_cmpl_ring_id = @@ -6972,13 +6986,7 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) req->cos_rule = cpu_to_le16(0xffff); } - if (vnic->flags & BNXT_VNIC_RSS_FLAG) - ring = 0; - else if (vnic->flags & BNXT_VNIC_RFS_FLAG) - ring = vnic->vnic_id - 1; - else if ((vnic->vnic_id == 1) && BNXT_CHIP_TYPE_NITRO_A0(bp)) - ring = bp->rx_nr_rings - 1; - + ring = vnic->default_rx_ring; grp_idx = bp->rx_ring[ring].bnapi->index; req->dflt_ring_grp = cpu_to_le16(bp->grp_info[grp_idx].fw_grp_id); req->lb_rule = cpu_to_le16(0xffff); @@ -11171,6 +11179,9 @@ static int bnxt_setup_nitroa0_vnic(struct bnxt *bp) return rc; } + /* Setup the proper default RX ring */ + bnxt_fill_hw_rss_tbl(bp, vnic); + rc = bnxt_hwrm_vnic_cfg(bp, vnic); if (rc) { netdev_err(bp->dev, "Cannot allocate special vnic for NS2 A0: %x\n", diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index fa13cee557798..8e04cc934c32b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1334,6 +1334,7 @@ struct bnxt_vnic_info { #define BNXT_VNIC_RSSCTX_FLAG 0x40 struct ethtool_rxfh_context *rss_ctx; u32 vnic_id; + u16 default_rx_ring; }; struct bnxt_rss_ctx { -- 2.53.0