aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Ertman <david.m.ertman@intel.com>2018-09-19 20:23:11 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-01 15:50:50 -0400
commit5df7e45d54fc99dd7c73e3a1f163cbfafc8b51f5 (patch)
treee5f5b2ee7f628e24ea44992e53dfae836b19831d
parent37bb839012865a4cafc038ec7ee183b873583a7d (diff)
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 <david.m.ertman@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c44
4 files changed, 31 insertions, 30 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index e84a612ffa71..9cce4cb91401 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -124,7 +124,7 @@ enum ice_state {
124 __ICE_DOWN, 124 __ICE_DOWN,
125 __ICE_NEEDS_RESTART, 125 __ICE_NEEDS_RESTART,
126 __ICE_PREPARED_FOR_RESET, /* set by driver when prepared */ 126 __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 */
128 __ICE_PFR_REQ, /* set by driver and peers */ 128 __ICE_PFR_REQ, /* set by driver and peers */
129 __ICE_CORER_REQ, /* set by driver and peers */ 129 __ICE_CORER_REQ, /* set by driver and peers */
130 __ICE_GLOBR_REQ, /* set by driver and peers */ 130 __ICE_GLOBR_REQ, /* set by driver and peers */
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 21e3a3e70329..95588fe0e22f 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2250,7 +2250,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
2250 * currently. This is done to avoid check_flush_dependency() warning 2250 * currently. This is done to avoid check_flush_dependency() warning
2251 * on this wq 2251 * on this wq
2252 */ 2252 */
2253 if (vsi->netdev && !ice_is_reset_recovery_pending(pf->state)) { 2253 if (vsi->netdev && !ice_is_reset_in_progress(pf->state)) {
2254 unregister_netdev(vsi->netdev); 2254 unregister_netdev(vsi->netdev);
2255 free_netdev(vsi->netdev); 2255 free_netdev(vsi->netdev);
2256 vsi->netdev = NULL; 2256 vsi->netdev = NULL;
@@ -2280,7 +2280,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
2280 * free VSI netdev when PF is not in reset recovery pending state,\ 2280 * free VSI netdev when PF is not in reset recovery pending state,\
2281 * for ex: during rmmod. 2281 * for ex: during rmmod.
2282 */ 2282 */
2283 if (!ice_is_reset_recovery_pending(pf->state)) 2283 if (!ice_is_reset_in_progress(pf->state))
2284 ice_vsi_clear(vsi); 2284 ice_vsi_clear(vsi);
2285 2285
2286 return 0; 2286 return 0;
@@ -2367,10 +2367,13 @@ err_vsi:
2367} 2367}
2368 2368
2369/** 2369/**
2370 * ice_is_reset_recovery_pending - schedule a reset 2370 * ice_is_reset_in_progress - check for a reset in progress
2371 * @state: pf state field 2371 * @state: pf state field
2372 */ 2372 */
2373bool ice_is_reset_recovery_pending(unsigned long *state) 2373bool ice_is_reset_in_progress(unsigned long *state)
2374{ 2374{
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);
2376} 2379}
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
index a76cde895bf3..4265464ee3d3 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -54,7 +54,7 @@ ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id);
54 54
55int ice_vsi_rebuild(struct ice_vsi *vsi); 55int ice_vsi_rebuild(struct ice_vsi *vsi);
56 56
57bool ice_is_reset_recovery_pending(unsigned long *state); 57bool ice_is_reset_in_progress(unsigned long *state);
58 58
59void ice_vsi_free_q_vectors(struct ice_vsi *vsi); 59void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
60 60
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 58cb2edd1c74..a3513acd272b 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -364,21 +364,17 @@ static void ice_do_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
364 dev_dbg(dev, "reset_type 0x%x requested\n", reset_type); 364 dev_dbg(dev, "reset_type 0x%x requested\n", reset_type);
365 WARN_ON(in_interrupt()); 365 WARN_ON(in_interrupt());
366 366
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
374 ice_prepare_for_reset(pf); 367 ice_prepare_for_reset(pf);
375 368
376 /* trigger the reset */ 369 /* trigger the reset */
377 if (ice_reset(hw, reset_type)) { 370 if (ice_reset(hw, reset_type)) {
378 dev_err(dev, "reset %d failed\n", reset_type); 371 dev_err(dev, "reset %d failed\n", reset_type);
379 set_bit(__ICE_RESET_FAILED, pf->state); 372 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);
381 clear_bit(__ICE_PREPARED_FOR_RESET, pf->state); 374 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);
382 return; 378 return;
383 } 379 }
384 380
@@ -389,8 +385,8 @@ static void ice_do_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
389 if (reset_type == ICE_RESET_PFR) { 385 if (reset_type == ICE_RESET_PFR) {
390 pf->pfr_count++; 386 pf->pfr_count++;
391 ice_rebuild(pf); 387 ice_rebuild(pf);
392 clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
393 clear_bit(__ICE_PREPARED_FOR_RESET, pf->state); 388 clear_bit(__ICE_PREPARED_FOR_RESET, pf->state);
389 clear_bit(__ICE_PFR_REQ, pf->state);
394 } 390 }
395} 391}
396 392
@@ -405,14 +401,14 @@ static void ice_reset_subtask(struct ice_pf *pf)
405 /* When a CORER/GLOBR/EMPR is about to happen, the hardware triggers an 401 /* When a CORER/GLOBR/EMPR is about to happen, the hardware triggers an
406 * OICR interrupt. The OICR handler (ice_misc_intr) determines what type 402 * OICR interrupt. The OICR handler (ice_misc_intr) determines what type
407 * of reset is pending and sets bits in pf->state indicating the reset 403 * 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
409 * prepare for pending reset if not already (for PF software-initiated 405 * prepare for pending reset if not already (for PF software-initiated
410 * global resets the software should already be prepared for it as 406 * global resets the software should already be prepared for it as
411 * indicated by __ICE_PREPARED_FOR_RESET; for global resets initiated 407 * indicated by __ICE_PREPARED_FOR_RESET; for global resets initiated
412 * by firmware or software on other PFs, that bit is not set so prepare 408 * by firmware or software on other PFs, that bit is not set so prepare
413 * for the reset now), poll for reset done, rebuild and return. 409 * for the reset now), poll for reset done, rebuild and return.
414 */ 410 */
415 if (ice_is_reset_recovery_pending(pf->state)) { 411 if (test_bit(__ICE_RESET_OICR_RECV, pf->state)) {
416 clear_bit(__ICE_GLOBR_RECV, pf->state); 412 clear_bit(__ICE_GLOBR_RECV, pf->state);
417 clear_bit(__ICE_CORER_RECV, pf->state); 413 clear_bit(__ICE_CORER_RECV, pf->state);
418 if (!test_bit(__ICE_PREPARED_FOR_RESET, pf->state)) 414 if (!test_bit(__ICE_PREPARED_FOR_RESET, pf->state))
@@ -428,19 +424,22 @@ static void ice_reset_subtask(struct ice_pf *pf)
428 /* clear bit to resume normal operations, but 424 /* clear bit to resume normal operations, but
429 * ICE_NEEDS_RESTART bit is set incase rebuild failed 425 * ICE_NEEDS_RESTART bit is set incase rebuild failed
430 */ 426 */
431 clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state); 427 clear_bit(__ICE_RESET_OICR_RECV, pf->state);
432 clear_bit(__ICE_PREPARED_FOR_RESET, pf->state); 428 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);
433 } 432 }
434 433
435 return; 434 return;
436 } 435 }
437 436
438 /* No pending resets to finish processing. Check for new resets */ 437 /* 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))
440 reset_type = ICE_RESET_PFR; 439 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))
442 reset_type = ICE_RESET_CORER; 441 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))
444 reset_type = ICE_RESET_GLOBR; 443 reset_type = ICE_RESET_GLOBR;
445 /* If no valid reset type requested just return */ 444 /* If no valid reset type requested just return */
446 if (reset_type == ICE_RESET_INVAL) 445 if (reset_type == ICE_RESET_INVAL)
@@ -1029,7 +1028,7 @@ static void ice_service_task(struct work_struct *work)
1029 ice_reset_subtask(pf); 1028 ice_reset_subtask(pf);
1030 1029
1031 /* bail if a reset/recovery cycle is pending or rebuild failed */ 1030 /* 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) ||
1033 test_bit(__ICE_SUSPENDED, pf->state) || 1032 test_bit(__ICE_SUSPENDED, pf->state) ||
1034 test_bit(__ICE_NEEDS_RESTART, pf->state)) { 1033 test_bit(__ICE_NEEDS_RESTART, pf->state)) {
1035 ice_service_task_complete(pf); 1034 ice_service_task_complete(pf);
@@ -1250,8 +1249,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
1250 * We also make note of which reset happened so that peer 1249 * We also make note of which reset happened so that peer
1251 * devices/drivers can be informed. 1250 * devices/drivers can be informed.
1252 */ 1251 */
1253 if (!test_and_set_bit(__ICE_RESET_RECOVERY_PENDING, 1252 if (!test_and_set_bit(__ICE_RESET_OICR_RECV, pf->state)) {
1254 pf->state)) {
1255 if (reset == ICE_RESET_CORER) 1253 if (reset == ICE_RESET_CORER)
1256 set_bit(__ICE_CORER_RECV, pf->state); 1254 set_bit(__ICE_CORER_RECV, pf->state);
1257 else if (reset == ICE_RESET_GLOBR) 1255 else if (reset == ICE_RESET_GLOBR)
@@ -1265,7 +1263,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
1265 * is received and set back to false after the driver 1263 * is received and set back to false after the driver
1266 * has determined that the hardware is out of reset. 1264 * has determined that the hardware is out of reset.
1267 * 1265 *
1268 * __ICE_RESET_RECOVERY_PENDING in pf->state indicates 1266 * __ICE_RESET_OICR_RECV in pf->state indicates
1269 * that a post reset rebuild is required before the 1267 * that a post reset rebuild is required before the
1270 * driver is operational again. This is set above. 1268 * driver is operational again. This is set above.
1271 * 1269 *
@@ -1355,7 +1353,7 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
1355 * lost during reset. Note that this function is called only during 1353 * lost during reset. Note that this function is called only during
1356 * rebuild path and not while reset is in progress. 1354 * rebuild path and not while reset is in progress.
1357 */ 1355 */
1358 if (ice_is_reset_recovery_pending(pf->state)) 1356 if (ice_is_reset_in_progress(pf->state))
1359 goto skip_req_irq; 1357 goto skip_req_irq;
1360 1358
1361 /* reserve one vector in irq_tracker for misc interrupts */ 1359 /* reserve one vector in irq_tracker for misc interrupts */
@@ -1637,7 +1635,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
1637 struct ice_vsi *vsi; 1635 struct ice_vsi *vsi;
1638 int status = 0; 1636 int status = 0;
1639 1637
1640 if (ice_is_reset_recovery_pending(pf->state)) 1638 if (ice_is_reset_in_progress(pf->state))
1641 return -EBUSY; 1639 return -EBUSY;
1642 1640
1643 vsi = ice_pf_vsi_setup(pf, pf->hw.port_info); 1641 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)
2203 } 2201 }
2204 2202
2205 if (test_bit(__ICE_DOWN, pf->state) || 2203 if (test_bit(__ICE_DOWN, pf->state) ||
2206 ice_is_reset_recovery_pending(pf->state)) { 2204 ice_is_reset_in_progress(pf->state)) {
2207 netdev_err(netdev, "can't set mac %pM. device not ready\n", 2205 netdev_err(netdev, "can't set mac %pM. device not ready\n",
2208 mac); 2206 mac);
2209 return -EBUSY; 2207 return -EBUSY;
@@ -3256,7 +3254,7 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
3256 } 3254 }
3257 /* if a reset is in progress, wait for some time for it to complete */ 3255 /* if a reset is in progress, wait for some time for it to complete */
3258 do { 3256 do {
3259 if (ice_is_reset_recovery_pending(pf->state)) { 3257 if (ice_is_reset_in_progress(pf->state)) {
3260 count++; 3258 count++;
3261 usleep_range(1000, 2000); 3259 usleep_range(1000, 2000);
3262 } else { 3260 } else {