| From fb68b12250cb30d059a1025c6fb4e9c3f0ec0c98 Mon Sep 17 00:00:00 2001 |
| From: Dave Ertman <david.m.ertman@intel.com> |
| Date: Wed, 13 Feb 2019 10:51:08 -0800 |
| Subject: ice: Prevent unintended multiple chain resets |
| |
| [ Upstream commit 2ebd4428d93a2f6ce0c813b10a1a43b6a8241fe5 ] |
| |
| In the current implementation of ice_reset_subtask, if multiple reset |
| types are set in the pf->state, the most intrusive one is meant to be |
| performed only, but the bits requesting the other types are not being |
| cleared. This would lead to another reset being performed the next time |
| the service task is scheduled. |
| |
| Change the flow of ice_reset_subtask so that all reset request bits in |
| pf->state are cleared, and we still perform the most intrusive of the |
| resets requested. |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/intel/ice/ice_main.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c |
| index ac30288720f71..ba9f88cd138de 100644 |
| --- a/drivers/net/ethernet/intel/ice/ice_main.c |
| +++ b/drivers/net/ethernet/intel/ice/ice_main.c |
| @@ -416,8 +416,14 @@ static void ice_reset_subtask(struct ice_pf *pf) |
| * for the reset now), poll for reset done, rebuild and return. |
| */ |
| if (test_bit(__ICE_RESET_OICR_RECV, pf->state)) { |
| - clear_bit(__ICE_GLOBR_RECV, pf->state); |
| - clear_bit(__ICE_CORER_RECV, pf->state); |
| + /* Perform the largest reset requested */ |
| + if (test_and_clear_bit(__ICE_CORER_RECV, pf->state)) |
| + reset_type = ICE_RESET_CORER; |
| + if (test_and_clear_bit(__ICE_GLOBR_RECV, pf->state)) |
| + reset_type = ICE_RESET_GLOBR; |
| + /* return if no valid reset type requested */ |
| + if (reset_type == ICE_RESET_INVAL) |
| + return; |
| if (!test_bit(__ICE_PREPARED_FOR_RESET, pf->state)) |
| ice_prepare_for_reset(pf); |
| |
| -- |
| 2.20.1 |
| |