Skip to content

Commit 4045296

Browse files
Michael Chankuba-moo
authored andcommitted
bnxt_en: Fix DIM shutdown
DIM work will call the firmware to adjust the coalescing parameters on the RX rings. We should cancel DIM work before we call the firmware to free the RX rings. Otherwise, FW will reject the call from DIM work if the RX ring has been freed. This will generate an error message like this: bnxt_en 0000:21:00.1 ens2f1np1: hwrm req_type 0x53 seq id 0x6fca error 0x2 and cause unnecessary concern for the user. It is also possible to modify the coalescing parameters of the wrong ring if the ring has been re-allocated. To prevent this, cancel DIM work right before freeing the RX rings. We also have to add a check in NAPI poll to not schedule DIM if the RX rings are shutting down. Check that the VNIC is active before we schedule DIM. The VNIC is always disabled before we free the RX rings. Fixes: 0bc0b97 ("bnxt_en: cleanup DIM work on device shutdown") Reviewed-by: Hongguang Gao <[email protected]> Reviewed-by: Kalesh AP <[email protected]> Reviewed-by: Somnath Kotur <[email protected]> Signed-off-by: Michael Chan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c8dafb0 commit 4045296

File tree

1 file changed

+33
-5
lines changed
  • drivers/net/ethernet/broadcom/bnxt

1 file changed

+33
-5
lines changed

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

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,6 +2897,13 @@ static int bnxt_hwrm_handler(struct bnxt *bp, struct tx_cmp *txcmp)
28972897
return 0;
28982898
}
28992899

2900+
static bool bnxt_vnic_is_active(struct bnxt *bp)
2901+
{
2902+
struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
2903+
2904+
return vnic->fw_vnic_id != INVALID_HW_RING_ID && vnic->mru > 0;
2905+
}
2906+
29002907
static irqreturn_t bnxt_msix(int irq, void *dev_instance)
29012908
{
29022909
struct bnxt_napi *bnapi = dev_instance;
@@ -3164,7 +3171,7 @@ static int bnxt_poll(struct napi_struct *napi, int budget)
31643171
break;
31653172
}
31663173
}
3167-
if (bp->flags & BNXT_FLAG_DIM) {
3174+
if ((bp->flags & BNXT_FLAG_DIM) && bnxt_vnic_is_active(bp)) {
31683175
struct dim_sample dim_sample = {};
31693176

31703177
dim_update_sample(cpr->event_ctr,
@@ -3295,7 +3302,7 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)
32953302
poll_done:
32963303
cpr_rx = &cpr->cp_ring_arr[0];
32973304
if (cpr_rx->cp_ring_type == BNXT_NQ_HDL_TYPE_RX &&
3298-
(bp->flags & BNXT_FLAG_DIM)) {
3305+
(bp->flags & BNXT_FLAG_DIM) && bnxt_vnic_is_active(bp)) {
32993306
struct dim_sample dim_sample = {};
33003307

33013308
dim_update_sample(cpr->event_ctr,
@@ -7266,6 +7273,26 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
72667273
return rc;
72677274
}
72687275

7276+
static void bnxt_cancel_dim(struct bnxt *bp)
7277+
{
7278+
int i;
7279+
7280+
/* DIM work is initialized in bnxt_enable_napi(). Proceed only
7281+
* if NAPI is enabled.
7282+
*/
7283+
if (!bp->bnapi || test_bit(BNXT_STATE_NAPI_DISABLED, &bp->state))
7284+
return;
7285+
7286+
/* Make sure NAPI sees that the VNIC is disabled */
7287+
synchronize_net();
7288+
for (i = 0; i < bp->rx_nr_rings; i++) {
7289+
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
7290+
struct bnxt_napi *bnapi = rxr->bnapi;
7291+
7292+
cancel_work_sync(&bnapi->cp_ring.dim.work);
7293+
}
7294+
}
7295+
72697296
static int hwrm_ring_free_send_msg(struct bnxt *bp,
72707297
struct bnxt_ring_struct *ring,
72717298
u32 ring_type, int cmpl_ring_id)
@@ -7366,6 +7393,7 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
73667393
}
73677394
}
73687395

7396+
bnxt_cancel_dim(bp);
73697397
for (i = 0; i < bp->rx_nr_rings; i++) {
73707398
bnxt_hwrm_rx_ring_free(bp, &bp->rx_ring[i], close_path);
73717399
bnxt_hwrm_rx_agg_ring_free(bp, &bp->rx_ring[i], close_path);
@@ -11309,8 +11337,6 @@ static void bnxt_disable_napi(struct bnxt *bp)
1130911337
if (bnapi->in_reset)
1131011338
cpr->sw_stats->rx.rx_resets++;
1131111339
napi_disable(&bnapi->napi);
11312-
if (bnapi->rx_ring)
11313-
cancel_work_sync(&cpr->dim.work);
1131411340
}
1131511341
}
1131611342

@@ -15572,8 +15598,10 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
1557215598
bnxt_hwrm_vnic_update(bp, vnic,
1557315599
VNIC_UPDATE_REQ_ENABLES_MRU_VALID);
1557415600
}
15575-
15601+
/* Make sure NAPI sees that the VNIC is disabled */
15602+
synchronize_net();
1557615603
rxr = &bp->rx_ring[idx];
15604+
cancel_work_sync(&rxr->bnapi->cp_ring.dim.work);
1557715605
bnxt_hwrm_rx_ring_free(bp, rxr, false);
1557815606
bnxt_hwrm_rx_agg_ring_free(bp, rxr, false);
1557915607
rxr->rx_next_cons = 0;

0 commit comments

Comments
 (0)