Commit dff515a3 authored by Thomas Falcon's avatar Thomas Falcon Committed by David S. Miller

ibmvnic: Harden device login requests

The VNIC driver's "login" command sequence is the final step
in the driver's initialization process with device firmware,
confirming the available device queue resources to be utilized
by the driver. Under high system load, firmware may not respond
to the request in a timely manner or may abort the request. In
such cases, the driver should reattempt the login command
sequence. In case of a device error, the number of retries
is bounded.
Signed-off-by: default avatarThomas Falcon <tlfalcon@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 939a5bf7
...@@ -842,12 +842,13 @@ static int ibmvnic_login(struct net_device *netdev) ...@@ -842,12 +842,13 @@ static int ibmvnic_login(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(30000); unsigned long timeout = msecs_to_jiffies(30000);
int retry_count = 0; int retry_count = 0;
int retries = 10;
bool retry; bool retry;
int rc; int rc;
do { do {
retry = false; retry = false;
if (retry_count > IBMVNIC_MAX_QUEUES) { if (retry_count > retries) {
netdev_warn(netdev, "Login attempts exceeded\n"); netdev_warn(netdev, "Login attempts exceeded\n");
return -1; return -1;
} }
...@@ -862,11 +863,23 @@ static int ibmvnic_login(struct net_device *netdev) ...@@ -862,11 +863,23 @@ static int ibmvnic_login(struct net_device *netdev)
if (!wait_for_completion_timeout(&adapter->init_done, if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) { timeout)) {
netdev_warn(netdev, "Login timed out\n"); netdev_warn(netdev, "Login timed out, retrying...\n");
return -1; retry = true;
adapter->init_done_rc = 0;
retry_count++;
continue;
} }
if (adapter->init_done_rc == PARTIALSUCCESS) { if (adapter->init_done_rc == ABORTED) {
netdev_warn(netdev, "Login aborted, retrying...\n");
retry = true;
adapter->init_done_rc = 0;
retry_count++;
/* FW or device may be busy, so
* wait a bit before retrying login
*/
msleep(500);
} else if (adapter->init_done_rc == PARTIALSUCCESS) {
retry_count++; retry_count++;
release_sub_crqs(adapter, 1); release_sub_crqs(adapter, 1);
......
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