Skip to content

Commit 5df7e45

Browse files
dmertmanJeff Kirsher
authored andcommitted
ice: Change pf state behavior to protect reset path
Currently, there is no bit, or set of bits, that protect the entirety of the reset path. If the reset is originated by the driver, then the relevant one of the following bits will be set when the reset is scheduled: __ICE_PFR_REQ __ICE_CORER_REQ __ICE_GLOBR_REQ This bit will not be cleared until after the rebuild has completed. If the reset is originated by the FW, then the first the driver knows of it will be the reception of the OICR interrupt. The __ICE_RESET_OICR_RECV bit will be set in the interrupt handler. This will also be the indicator in a SW originated reset that we have completed the pre-OICR tasks and have informed the FW that a reset was requested. To utilize these bits, change the function: ice_is_reset_recovery_pending() to be: ice_is_reset_in_progress() The new function will check all of the above bits in the pf->state and will return a true if one or more of these bits are set. Signed-off-by: Dave Ertman <[email protected]> Signed-off-by: Anirudh Venkataramanan <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 37bb839 commit 5df7e45

File tree

4 files changed

+31
-30
lines changed

4 files changed

+31
-30
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ enum ice_state {
124124
__ICE_DOWN,
125125
__ICE_NEEDS_RESTART,
126126
__ICE_PREPARED_FOR_RESET, /* set by driver when prepared */
127-
__ICE_RESET_RECOVERY_PENDING, /* set by driver when reset starts */
127+
__ICE_RESET_OICR_RECV, /* set by driver after rcv reset OICR */
128128
__ICE_PFR_REQ, /* set by driver and peers */
129129
__ICE_CORER_REQ, /* set by driver and peers */
130130
__ICE_GLOBR_REQ, /* set by driver and peers */

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,7 +2250,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
22502250
* currently. This is done to avoid check_flush_dependency() warning
22512251
* on this wq
22522252
*/
2253-
if (vsi->netdev && !ice_is_reset_recovery_pending(pf->state)) {
2253+
if (vsi->netdev && !ice_is_reset_in_progress(pf->state)) {
22542254
unregister_netdev(vsi->netdev);
22552255
free_netdev(vsi->netdev);
22562256
vsi->netdev = NULL;
@@ -2280,7 +2280,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
22802280
* free VSI netdev when PF is not in reset recovery pending state,\
22812281
* for ex: during rmmod.
22822282
*/
2283-
if (!ice_is_reset_recovery_pending(pf->state))
2283+
if (!ice_is_reset_in_progress(pf->state))
22842284
ice_vsi_clear(vsi);
22852285

22862286
return 0;
@@ -2367,10 +2367,13 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
23672367
}
23682368

23692369
/**
2370-
* ice_is_reset_recovery_pending - schedule a reset
2370+
* ice_is_reset_in_progress - check for a reset in progress
23712371
* @state: pf state field
23722372
*/
2373-
bool ice_is_reset_recovery_pending(unsigned long *state)
2373+
bool ice_is_reset_in_progress(unsigned long *state)
23742374
{
2375-
return test_bit(__ICE_RESET_RECOVERY_PENDING, state);
2375+
return test_bit(__ICE_RESET_OICR_RECV, state) ||
2376+
test_bit(__ICE_PFR_REQ, state) ||
2377+
test_bit(__ICE_CORER_REQ, state) ||
2378+
test_bit(__ICE_GLOBR_REQ, state);
23762379
}

drivers/net/ethernet/intel/ice/ice_lib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id);
5454

5555
int ice_vsi_rebuild(struct ice_vsi *vsi);
5656

57-
bool ice_is_reset_recovery_pending(unsigned long *state);
57+
bool ice_is_reset_in_progress(unsigned long *state);
5858

5959
void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
6060

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -364,21 +364,17 @@ static void ice_do_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
364364
dev_dbg(dev, "reset_type 0x%x requested\n", reset_type);
365365
WARN_ON(in_interrupt());
366366

367-
/* PFR is a bit of a special case because it doesn't result in an OICR
368-
* interrupt. Set pending bit here which otherwise gets set in the
369-
* OICR handler.
370-
*/
371-
if (reset_type == ICE_RESET_PFR)
372-
set_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
373-
374367
ice_prepare_for_reset(pf);
375368

376369
/* trigger the reset */
377370
if (ice_reset(hw, reset_type)) {
378371
dev_err(dev, "reset %d failed\n", reset_type);
379372
set_bit(__ICE_RESET_FAILED, pf->state);
380-
clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
373+
clear_bit(__ICE_RESET_OICR_RECV, pf->state);
381374
clear_bit(__ICE_PREPARED_FOR_RESET, pf->state);
375+
clear_bit(__ICE_PFR_REQ, pf->state);
376+
clear_bit(__ICE_CORER_REQ, pf->state);
377+
clear_bit(__ICE_GLOBR_REQ, pf->state);
382378
return;
383379
}
384380

@@ -389,8 +385,8 @@ static void ice_do_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
389385
if (reset_type == ICE_RESET_PFR) {
390386
pf->pfr_count++;
391387
ice_rebuild(pf);
392-
clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
393388
clear_bit(__ICE_PREPARED_FOR_RESET, pf->state);
389+
clear_bit(__ICE_PFR_REQ, pf->state);
394390
}
395391
}
396392

@@ -405,14 +401,14 @@ static void ice_reset_subtask(struct ice_pf *pf)
405401
/* When a CORER/GLOBR/EMPR is about to happen, the hardware triggers an
406402
* OICR interrupt. The OICR handler (ice_misc_intr) determines what type
407403
* of reset is pending and sets bits in pf->state indicating the reset
408-
* type and __ICE_RESET_RECOVERY_PENDING. So, if the latter bit is set
404+
* type and __ICE_RESET_OICR_RECV. So, if the latter bit is set
409405
* prepare for pending reset if not already (for PF software-initiated
410406
* global resets the software should already be prepared for it as
411407
* indicated by __ICE_PREPARED_FOR_RESET; for global resets initiated
412408
* by firmware or software on other PFs, that bit is not set so prepare
413409
* for the reset now), poll for reset done, rebuild and return.
414410
*/
415-
if (ice_is_reset_recovery_pending(pf->state)) {
411+
if (test_bit(__ICE_RESET_OICR_RECV, pf->state)) {
416412
clear_bit(__ICE_GLOBR_RECV, pf->state);
417413
clear_bit(__ICE_CORER_RECV, pf->state);
418414
if (!test_bit(__ICE_PREPARED_FOR_RESET, pf->state))
@@ -428,19 +424,22 @@ static void ice_reset_subtask(struct ice_pf *pf)
428424
/* clear bit to resume normal operations, but
429425
* ICE_NEEDS_RESTART bit is set incase rebuild failed
430426
*/
431-
clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
427+
clear_bit(__ICE_RESET_OICR_RECV, pf->state);
432428
clear_bit(__ICE_PREPARED_FOR_RESET, pf->state);
429+
clear_bit(__ICE_PFR_REQ, pf->state);
430+
clear_bit(__ICE_CORER_REQ, pf->state);
431+
clear_bit(__ICE_GLOBR_REQ, pf->state);
433432
}
434433

435434
return;
436435
}
437436

438437
/* No pending resets to finish processing. Check for new resets */
439-
if (test_and_clear_bit(__ICE_PFR_REQ, pf->state))
438+
if (test_bit(__ICE_PFR_REQ, pf->state))
440439
reset_type = ICE_RESET_PFR;
441-
if (test_and_clear_bit(__ICE_CORER_REQ, pf->state))
440+
if (test_bit(__ICE_CORER_REQ, pf->state))
442441
reset_type = ICE_RESET_CORER;
443-
if (test_and_clear_bit(__ICE_GLOBR_REQ, pf->state))
442+
if (test_bit(__ICE_GLOBR_REQ, pf->state))
444443
reset_type = ICE_RESET_GLOBR;
445444
/* If no valid reset type requested just return */
446445
if (reset_type == ICE_RESET_INVAL)
@@ -1029,7 +1028,7 @@ static void ice_service_task(struct work_struct *work)
10291028
ice_reset_subtask(pf);
10301029

10311030
/* bail if a reset/recovery cycle is pending or rebuild failed */
1032-
if (ice_is_reset_recovery_pending(pf->state) ||
1031+
if (ice_is_reset_in_progress(pf->state) ||
10331032
test_bit(__ICE_SUSPENDED, pf->state) ||
10341033
test_bit(__ICE_NEEDS_RESTART, pf->state)) {
10351034
ice_service_task_complete(pf);
@@ -1250,8 +1249,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
12501249
* We also make note of which reset happened so that peer
12511250
* devices/drivers can be informed.
12521251
*/
1253-
if (!test_and_set_bit(__ICE_RESET_RECOVERY_PENDING,
1254-
pf->state)) {
1252+
if (!test_and_set_bit(__ICE_RESET_OICR_RECV, pf->state)) {
12551253
if (reset == ICE_RESET_CORER)
12561254
set_bit(__ICE_CORER_RECV, pf->state);
12571255
else if (reset == ICE_RESET_GLOBR)
@@ -1265,7 +1263,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
12651263
* is received and set back to false after the driver
12661264
* has determined that the hardware is out of reset.
12671265
*
1268-
* __ICE_RESET_RECOVERY_PENDING in pf->state indicates
1266+
* __ICE_RESET_OICR_RECV in pf->state indicates
12691267
* that a post reset rebuild is required before the
12701268
* driver is operational again. This is set above.
12711269
*
@@ -1355,7 +1353,7 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
13551353
* lost during reset. Note that this function is called only during
13561354
* rebuild path and not while reset is in progress.
13571355
*/
1358-
if (ice_is_reset_recovery_pending(pf->state))
1356+
if (ice_is_reset_in_progress(pf->state))
13591357
goto skip_req_irq;
13601358

13611359
/* reserve one vector in irq_tracker for misc interrupts */
@@ -1637,7 +1635,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
16371635
struct ice_vsi *vsi;
16381636
int status = 0;
16391637

1640-
if (ice_is_reset_recovery_pending(pf->state))
1638+
if (ice_is_reset_in_progress(pf->state))
16411639
return -EBUSY;
16421640

16431641
vsi = ice_pf_vsi_setup(pf, pf->hw.port_info);
@@ -2203,7 +2201,7 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi)
22032201
}
22042202

22052203
if (test_bit(__ICE_DOWN, pf->state) ||
2206-
ice_is_reset_recovery_pending(pf->state)) {
2204+
ice_is_reset_in_progress(pf->state)) {
22072205
netdev_err(netdev, "can't set mac %pM. device not ready\n",
22082206
mac);
22092207
return -EBUSY;
@@ -3256,7 +3254,7 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
32563254
}
32573255
/* if a reset is in progress, wait for some time for it to complete */
32583256
do {
3259-
if (ice_is_reset_recovery_pending(pf->state)) {
3257+
if (ice_is_reset_in_progress(pf->state)) {
32603258
count++;
32613259
usleep_range(1000, 2000);
32623260
} else {

0 commit comments

Comments
 (0)