Skip to content

Commit 5dacc94

Browse files
pavanchebbikuba-moo
authored andcommitted
bnxt_en: Update MRU and RSS table of RSS contexts on queue reset
The commit under the Fixes tag below which updates the VNICs' RSS and MRU during .ndo_queue_start(), needs to be extended to cover any non-default RSS contexts which have their own VNICs. Without this step, packets that are destined to a non-default RSS context may be dropped after .ndo_queue_start(). We further optimize this scheme by updating the VNIC only if the RX ring being restarted is in the RSS table of the VNIC. Updating the VNIC (in particular setting the MRU to 0) will momentarily stop all traffic to all rings in the RSS table. Any VNIC that has the RX ring excluded from the RSS table can skip this step and avoid the traffic disruption. Note that this scheme is just an improvement. A VNIC with multiple rings in the RSS table will still see traffic disruptions to all rings in the RSS table when one of the rings is being restarted. We are working on a FW scheme that will improve upon this further. Fixes: 5ac066b ("bnxt_en: Fix queue start to update vnic RSS table") Reported-by: David Wei <dw@davidwei.uk> Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Link: https://patch.msgid.link/20250613231841.377988-4-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent e11baae commit 5dacc94

1 file changed

Lines changed: 51 additions & 5 deletions

File tree

  • drivers/net/ethernet/broadcom/bnxt

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

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10780,11 +10780,39 @@ void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
1078010780
bp->num_rss_ctx--;
1078110781
}
1078210782

10783+
static bool bnxt_vnic_has_rx_ring(struct bnxt *bp, struct bnxt_vnic_info *vnic,
10784+
int rxr_id)
10785+
{
10786+
u16 tbl_size = bnxt_get_rxfh_indir_size(bp->dev);
10787+
int i, vnic_rx;
10788+
10789+
/* Ntuple VNIC always has all the rx rings. Any change of ring id
10790+
* must be updated because a future filter may use it.
10791+
*/
10792+
if (vnic->flags & BNXT_VNIC_NTUPLE_FLAG)
10793+
return true;
10794+
10795+
for (i = 0; i < tbl_size; i++) {
10796+
if (vnic->flags & BNXT_VNIC_RSSCTX_FLAG)
10797+
vnic_rx = ethtool_rxfh_context_indir(vnic->rss_ctx)[i];
10798+
else
10799+
vnic_rx = bp->rss_indir_tbl[i];
10800+
10801+
if (rxr_id == vnic_rx)
10802+
return true;
10803+
}
10804+
10805+
return false;
10806+
}
10807+
1078310808
static int bnxt_set_vnic_mru_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic,
10784-
u16 mru)
10809+
u16 mru, int rxr_id)
1078510810
{
1078610811
int rc;
1078710812

10813+
if (!bnxt_vnic_has_rx_ring(bp, vnic, rxr_id))
10814+
return 0;
10815+
1078810816
if (mru) {
1078910817
rc = bnxt_hwrm_vnic_set_rss_p5(bp, vnic, true);
1079010818
if (rc) {
@@ -10800,6 +10828,24 @@ static int bnxt_set_vnic_mru_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic,
1080010828
return 0;
1080110829
}
1080210830

10831+
static int bnxt_set_rss_ctx_vnic_mru(struct bnxt *bp, u16 mru, int rxr_id)
10832+
{
10833+
struct ethtool_rxfh_context *ctx;
10834+
unsigned long context;
10835+
int rc;
10836+
10837+
xa_for_each(&bp->dev->ethtool->rss_ctx, context, ctx) {
10838+
struct bnxt_rss_ctx *rss_ctx = ethtool_rxfh_context_priv(ctx);
10839+
struct bnxt_vnic_info *vnic = &rss_ctx->vnic;
10840+
10841+
rc = bnxt_set_vnic_mru_p5(bp, vnic, mru, rxr_id);
10842+
if (rc)
10843+
return rc;
10844+
}
10845+
10846+
return 0;
10847+
}
10848+
1080310849
static void bnxt_hwrm_realloc_rss_ctx_vnic(struct bnxt *bp)
1080410850
{
1080510851
bool set_tpa = !!(bp->flags & BNXT_FLAG_TPA);
@@ -16002,12 +16048,11 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
1600216048
for (i = 0; i < bp->nr_vnics; i++) {
1600316049
vnic = &bp->vnic_info[i];
1600416050

16005-
rc = bnxt_set_vnic_mru_p5(bp, vnic, mru);
16051+
rc = bnxt_set_vnic_mru_p5(bp, vnic, mru, idx);
1600616052
if (rc)
1600716053
return rc;
1600816054
}
16009-
16010-
return 0;
16055+
return bnxt_set_rss_ctx_vnic_mru(bp, mru, idx);
1601116056

1601216057
err_reset:
1601316058
netdev_err(bp->dev, "Unexpected HWRM error during queue start rc: %d\n",
@@ -16030,8 +16075,9 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
1603016075
for (i = 0; i < bp->nr_vnics; i++) {
1603116076
vnic = &bp->vnic_info[i];
1603216077

16033-
bnxt_set_vnic_mru_p5(bp, vnic, 0);
16078+
bnxt_set_vnic_mru_p5(bp, vnic, 0, idx);
1603416079
}
16080+
bnxt_set_rss_ctx_vnic_mru(bp, 0, idx);
1603516081
/* Make sure NAPI sees that the VNIC is disabled */
1603616082
synchronize_net();
1603716083
rxr = &bp->rx_ring[idx];

0 commit comments

Comments
 (0)