Commit db9f0e8b authored by Sukadev Bhattiprolu's avatar Sukadev Bhattiprolu Committed by David S. Miller

ibmvnic: Allow extra failures before disabling

If auto-priority-failover (APF) is enabled and there are at least two
backing devices of different priorities, some resets like fail-over,
change-param etc can cause at least two back to back failovers. (Failover
from high priority backing device to lower priority one and then back
to the higher priority one if that is still functional).

Depending on the timimg of the two failovers it is possible to trigger
a "hard" reset and for the hard reset to fail due to failovers. When this
occurs, the driver assumes that the network is unstable and disables the
VNIC for a 60-second "settling time". This in turn can cause the ethtool
command to fail with "No such device" while the vnic automatically recovers
a little while later.

Given that it's possible to have two back to back failures, allow for extra
failures before disabling the vnic for the settling time.

Fixes: f15fde9d ("ibmvnic: delay next reset if hard reset fails")
Signed-off-by: default avatarSukadev Bhattiprolu <sukadev@linux.ibm.com>
Reviewed-by: default avatarDany Madden <drt@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 27a8caa5
...@@ -2602,6 +2602,7 @@ static void __ibmvnic_reset(struct work_struct *work) ...@@ -2602,6 +2602,7 @@ static void __ibmvnic_reset(struct work_struct *work)
struct ibmvnic_rwi *rwi; struct ibmvnic_rwi *rwi;
unsigned long flags; unsigned long flags;
u32 reset_state; u32 reset_state;
int num_fails = 0;
int rc = 0; int rc = 0;
adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
...@@ -2655,11 +2656,23 @@ static void __ibmvnic_reset(struct work_struct *work) ...@@ -2655,11 +2656,23 @@ static void __ibmvnic_reset(struct work_struct *work)
rc = do_hard_reset(adapter, rwi, reset_state); rc = do_hard_reset(adapter, rwi, reset_state);
rtnl_unlock(); rtnl_unlock();
} }
if (rc) { if (rc)
/* give backing device time to settle down */ num_fails++;
else
num_fails = 0;
/* If auto-priority-failover is enabled we can get
* back to back failovers during resets, resulting
* in at least two failed resets (from high-priority
* backing device to low-priority one and then back)
* If resets continue to fail beyond that, give the
* adapter some time to settle down before retrying.
*/
if (num_fails >= 3) {
netdev_dbg(adapter->netdev, netdev_dbg(adapter->netdev,
"[S:%s] Hard reset failed, waiting 60 secs\n", "[S:%s] Hard reset failed %d times, waiting 60 secs\n",
adapter_state_to_string(adapter->state)); adapter_state_to_string(adapter->state),
num_fails);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(60 * HZ); schedule_timeout(60 * HZ);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment