mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
ibmvnic: retry reset if there are no other resets
Normally, if a reset fails due to failover or other communication error there is another reset (eg: FAILOVER) in the queue and we would process that reset. But if we are unable to communicate with PHYP or VIOS after H_FREE_CRQ, there would be no other resets in the queue and the adapter would be in an undefined state even though it was in the OPEN state earlier. While starting the reset we set the carrier to off state so we won't even get the timeout resets. If the last queued reset fails, retry it as a hard reset (after the usual 60 second settling time). Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com> Reviewed-by: Dany Madden <drt@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b2bc814817
commit
4f408e1fa6
@ -2420,9 +2420,10 @@ out:
|
|||||||
|
|
||||||
static void __ibmvnic_reset(struct work_struct *work)
|
static void __ibmvnic_reset(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct ibmvnic_rwi *rwi;
|
|
||||||
struct ibmvnic_adapter *adapter;
|
struct ibmvnic_adapter *adapter;
|
||||||
bool saved_state = false;
|
bool saved_state = false;
|
||||||
|
struct ibmvnic_rwi *tmprwi;
|
||||||
|
struct ibmvnic_rwi *rwi;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reset_state;
|
u32 reset_state;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -2489,7 +2490,7 @@ static void __ibmvnic_reset(struct work_struct *work)
|
|||||||
} else {
|
} else {
|
||||||
rc = do_reset(adapter, rwi, reset_state);
|
rc = do_reset(adapter, rwi, reset_state);
|
||||||
}
|
}
|
||||||
kfree(rwi);
|
tmprwi = rwi;
|
||||||
adapter->last_reset_time = jiffies;
|
adapter->last_reset_time = jiffies;
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -2497,8 +2498,23 @@ static void __ibmvnic_reset(struct work_struct *work)
|
|||||||
|
|
||||||
rwi = get_next_rwi(adapter);
|
rwi = get_next_rwi(adapter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is another reset queued, free the previous rwi
|
||||||
|
* and process the new reset even if previous reset failed
|
||||||
|
* (the previous reset could have failed because of a fail
|
||||||
|
* over for instance, so process the fail over).
|
||||||
|
*
|
||||||
|
* If there are no resets queued and the previous reset failed,
|
||||||
|
* the adapter would be in an undefined state. So retry the
|
||||||
|
* previous reset as a hard reset.
|
||||||
|
*/
|
||||||
|
if (rwi)
|
||||||
|
kfree(tmprwi);
|
||||||
|
else if (rc)
|
||||||
|
rwi = tmprwi;
|
||||||
|
|
||||||
if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
|
if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
|
||||||
rwi->reset_reason == VNIC_RESET_MOBILITY))
|
rwi->reset_reason == VNIC_RESET_MOBILITY || rc))
|
||||||
adapter->force_reset_recovery = true;
|
adapter->force_reset_recovery = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user