Re: [PATCH net-next 2/2] ibmvnic: Update firmware error reporting with cause string

2018-08-06 Thread Nathan Fontenot



On 08/06/2018 09:39 PM, Thomas Falcon wrote:

Print a string instead of the error code. Since there is a
possibility that the driver can recover, classify it as a
warning instead of an error.

Signed-off-by: Thomas Falcon 
---
  drivers/net/ethernet/ibm/ibmvnic.c | 34 ++
  1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 109e4a58efad..dafdd4ade705 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3825,15 +3825,41 @@ static void handle_query_ip_offload_rsp(struct 
ibmvnic_adapter *adapter)
ibmvnic_send_crq(adapter, );
  }

+static const char *ibmvnic_fw_err_cause(u16 cause)
+{
+   switch (cause) {
+   case ADAPTER_PROBLEM:
+   return "adapter problem";
+   case BUS_PROBLEM:
+   return "bus problem";
+   case FW_PROBLEM:
+   return "firmware problem";
+   case DD_PROBLEM:
+   return "device driver problem";
+   case EEH_RECOVERY:
+   return "EEH recovery";
+   case FW_UPDATED:
+   return "firmware updated";
+   case LOW_MEMORY:
+   return "low Memory";
+   default:
+   return "unknown";
+   }
+}
+
  static void handle_error_indication(union ibmvnic_crq *crq,
struct ibmvnic_adapter *adapter)
  {
struct device *dev = >vdev->dev;
+   u16 cause;
+
+   cause = be16_to_cpu(crq->error_indication.error_cause);

-   dev_err(dev, "Firmware reports %serror, cause %d\n",
-   crq->error_indication.flags
-   & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
-   be16_to_cpu(crq->error_indication.error_cause));
+   dev_warn_ratelimited(dev,
+"Firmware reports %serror, cause: %s. Starting 
recovery...\n",


   ^^^

You're going to want a space between after the %s here.

-Nathan


+crq->error_indication.flags
+   & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
+ibmvnic_fw_err_cause(cause));

if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
ibmvnic_reset(adapter, VNIC_RESET_FATAL);





[PATCH net] ibmvnic: Only do H_EOI for mobility events

2018-05-22 Thread Nathan Fontenot
When enabling the sub-CRQ IRQ a previous update sent a H_EOI prior
to the enablement to clear any pending interrupts that may be present
across a partition migration. This fixed a firmware bug where a
migration could erroneously indicate that a H_EOI was pending.

The H_EOI should only be sent when enabling during a mobility
event though. Doing so at other time could wrong and can produce
extra driver output when IRQs are enabled when doing TX completion.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4bb4646a5f92..62cd3602c633 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2617,18 +2617,21 @@ static int enable_scrq_irq(struct ibmvnic_adapter 
*adapter,
 {
struct device *dev = >vdev->dev;
unsigned long rc;
-   u64 val;
 
if (scrq->hw_irq > 0x1ULL) {
dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
return 1;
}
 
-   val = (0xff00) | scrq->hw_irq;
-   rc = plpar_hcall_norets(H_EOI, val);
-   if (rc)
-   dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
-   val, rc);
+   if (adapter->resetting &&
+   adapter->reset_reason == VNIC_RESET_MOBILITY) {
+   u64 val = (0xff00) | scrq->hw_irq;
+
+   rc = plpar_hcall_norets(H_EOI, val);
+   if (rc)
+   dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
+   val, rc);
+   }
 
rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);



[PATCH v2 net 1/2] ibmvnic: Handle all login error conditions

2018-04-11 Thread Nathan Fontenot
There is a bug in handling the possible return codes from sending the
login CRQ. The current code treats any non-success return value,
minus failure to send the crq and a timeout waiting for a login response,
as a need to re-send the login CRQ. This can put the drive in an
infinite loop of trying to login when getting return values other
that a partial success such as a return code of aborted. For these
scenarios the login will not ever succeed at this point and the
driver would need to be reset again.

To resolve this loop trying to login is updated to only retry the
login if the driver gets a return code of a partial success. Other
return codes are treated as an error and the driver returns an error
from ibmvnic_login().

To avoid infinite looping in the partial success return cases, the
number of retries is capped at the maximum number of supported
queues. This value was chosen because the driver does a renegotiation
of capabilities which sets the number of queues possible and allows
the driver to attempt a login for possible value for the number
of queues supported.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   55 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |1 -
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index aad5658d79d5..c6d5e9448eef 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(3);
-   struct device *dev = >vdev->dev;
+   int retry_count = 0;
int rc;
 
do {
-   if (adapter->renegotiate) {
-   adapter->renegotiate = false;
+   if (retry_count > IBMVNIC_MAX_QUEUES) {
+   netdev_warn(netdev, "Login attempts exceeded\n");
+   return -1;
+   }
+
+   adapter->init_done_rc = 0;
+   reinit_completion(>init_done);
+   rc = send_login(adapter);
+   if (rc) {
+   netdev_warn(netdev, "Unable to login\n");
+   return rc;
+   }
+
+   if (!wait_for_completion_timeout(>init_done,
+timeout)) {
+   netdev_warn(netdev, "Login timed out\n");
+   return -1;
+   }
+
+   if (adapter->init_done_rc == PARTIALSUCCESS) {
+   retry_count++;
release_sub_crqs(adapter, 1);
 
+   adapter->init_done_rc = 0;
reinit_completion(>init_done);
send_cap_queries(adapter);
if (!wait_for_completion_timeout(>init_done,
 timeout)) {
-   dev_err(dev, "Capabilities query timeout\n");
+   netdev_warn(netdev,
+   "Capabilities query timed out\n");
return -1;
}
+
rc = init_sub_crqs(adapter);
if (rc) {
-   dev_err(dev,
-   "Initialization of SCRQ's failed\n");
+   netdev_warn(netdev,
+   "SCRQ initialization failed\n");
return -1;
}
+
rc = init_sub_crq_irqs(adapter);
if (rc) {
-   dev_err(dev,
-   "Initialization of SCRQ's irqs 
failed\n");
+   netdev_warn(netdev,
+   "SCRQ irq initialization failed\n");
return -1;
}
-   }
-
-   reinit_completion(>init_done);
-   rc = send_login(adapter);
-   if (rc) {
-   dev_err(dev, "Unable to attempt device login\n");
-   return rc;
-   } else if (!wait_for_completion_timeout(>init_done,
-timeout)) {
-   dev_err(dev, "Login timeout\n");
+   } else if (adapter->init_done_rc) {
+   netdev_warn(netdev, "Adapter login failed\n");
return -1;

[PATCH v2 net 0/2] ibmvnic: Fix parameter change request handling

2018-04-11 Thread Nathan Fontenot
When updating parameters for the ibmvnic driver there is a possibility
of entering an infinite loop if a return value other that a partial
success is received from sending the login CRQ.

Also, a deadlock can occur on the rtnl lock if netdev_notify_peers()
is called during driver reset for a parameter change reset.

This patch set corrects both of these issues by updating the return
code handling in ibmvnic_login() nand gaurding against calling
netdev_notify_peers() for parameter change requests.

-Nathan

Updates for V2: Correct spelling mistakes in commit messages.
---

Nathan Fontenot (2):
  ibmvnic: Handle all login error conditions
  ibmvnic: Do not notify peers on parameter change resets


 drivers/net/ethernet/ibm/ibmvnic.c |   58 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |1 -
 2 files changed, 37 insertions(+), 22 deletions(-)



[PATCH v2 net 2/2] ibmvnic: Do not notify peers on parameter change resets

2018-04-11 Thread Nathan Fontenot
When attempting to change the driver parameters, such as the MTU
value or number of queues, do not call netdev_notify_peers().
Doing so will deadlock on the rtnl_lock.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index c6d5e9448eef..fdca1ea5bbf9 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1843,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
for (i = 0; i < adapter->req_rx_queues; i++)
napi_schedule(>napi[i]);
 
-   if (adapter->reset_reason != VNIC_RESET_FAILOVER)
+   if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+   adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
netdev_notify_peers(netdev);
 
netif_carrier_on(netdev);



Re: [PATCH net 1/2] ibmvnic: Handle all login error conditions

2018-04-11 Thread Nathan Fontenot
On 04/11/2018 10:07 AM, David Miller wrote:
> From: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> Date: Wed, 11 Apr 2018 09:37:21 -0500
> 
>> There is a bug in handling the possible return codes from sending the
>> login CRQ. The current code treats any non-success return value,
>> minus failure to send the crq and a timeout waiting for a login response,
>> as a need to re-send the login CRQ. This can put the drive in an
>^
> 
> "driver"
> 
>> inifinite loop of trying to login when getting return values other
>   ^
> 
> "infinite"
> 
>> that a partial success such as a return code of aborted. For these
>> scenarios the login will not ever succeed at this point and the
>> driver would need to be reset again.
>>
>> To resolve this loop trying to login is updated to only retry the
>> login if the driver gets a return code of a partial success. Other
>> return coes are treated as an error and the driver returns an error
>  
> 
> "codes"
> 
>> from ibmvnic_login().
>>
>> To avoid infinite looping in the partial success return cases, the
>> number of retries is capped at the maximum number of supported
>> queues. This value was chosen because the driver does a renegatiation
>   ^
> 
> "renegotiation"
> 
>> of capabilities which sets the number of queus possible and allows
>^
> 
> "queues"
> 

Oh man, complete spelling failure. resending.

-Nathan



[PATCH net 0/2] ibmvnic: Fix parameter change request handling

2018-04-11 Thread Nathan Fontenot
When updating parameters for the ibmvnic driver there is a possibility
of entering an infinite loop if a return value other that a partial
success is received from sending the login CRQ.

Also, a deadlock can occur on the rtnl lock if netdev_notify_peers()
is called during driver reset for a parameter change reset.

This patch set corrects both of these issues by updating the return
code handling in ibmvnic_login() nand gaurding against calling
netdev_notify_peers() for parameter change requests.

-Nathan
---

Nathan Fontenot (2):
  ibmvnic: Handle all login error conditions
  ibmvnic: Do not notify peers on parameter change resets


 drivers/net/ethernet/ibm/ibmvnic.c |   58 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |1 -
 2 files changed, 37 insertions(+), 22 deletions(-)



[PATCH net 2/2] ibmvnic: Do not notify peers on parameter change resets

2018-04-11 Thread Nathan Fontenot
When attempting to change the driver parameters, such as the MTU
value or number of queues, do not call netdev_notify_peers().
Doing so will deadlock on the rtnl_lock.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index c6d5e9448eef..fdca1ea5bbf9 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1843,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
for (i = 0; i < adapter->req_rx_queues; i++)
napi_schedule(>napi[i]);
 
-   if (adapter->reset_reason != VNIC_RESET_FAILOVER)
+   if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+   adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
netdev_notify_peers(netdev);
 
netif_carrier_on(netdev);



[PATCH net 1/2] ibmvnic: Handle all login error conditions

2018-04-11 Thread Nathan Fontenot
There is a bug in handling the possible return codes from sending the
login CRQ. The current code treats any non-success return value,
minus failure to send the crq and a timeout waiting for a login response,
as a need to re-send the login CRQ. This can put the drive in an
inifinite loop of trying to login when getting return values other
that a partial success such as a return code of aborted. For these
scenarios the login will not ever succeed at this point and the
driver would need to be reset again.

To resolve this loop trying to login is updated to only retry the
login if the driver gets a return code of a partial success. Other
return coes are treated as an error and the driver returns an error
from ibmvnic_login().

To avoid infinite looping in the partial success return cases, the
number of retries is capped at the maximum number of supported
queues. This value was chosen because the driver does a renegatiation
of capabilities which sets the number of queus possible and allows
the driver to attempt a login for possible value for the number
of queues supported.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   55 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |1 -
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index aad5658d79d5..c6d5e9448eef 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(3);
-   struct device *dev = >vdev->dev;
+   int retry_count = 0;
int rc;
 
do {
-   if (adapter->renegotiate) {
-   adapter->renegotiate = false;
+   if (retry_count > IBMVNIC_MAX_QUEUES) {
+   netdev_warn(netdev, "Login attempts exceeded\n");
+   return -1;
+   }
+
+   adapter->init_done_rc = 0;
+   reinit_completion(>init_done);
+   rc = send_login(adapter);
+   if (rc) {
+   netdev_warn(netdev, "Unable to login\n");
+   return rc;
+   }
+
+   if (!wait_for_completion_timeout(>init_done,
+timeout)) {
+   netdev_warn(netdev, "Login timed out\n");
+   return -1;
+   }
+
+   if (adapter->init_done_rc == PARTIALSUCCESS) {
+   retry_count++;
release_sub_crqs(adapter, 1);
 
+   adapter->init_done_rc = 0;
reinit_completion(>init_done);
send_cap_queries(adapter);
if (!wait_for_completion_timeout(>init_done,
 timeout)) {
-   dev_err(dev, "Capabilities query timeout\n");
+   netdev_warn(netdev,
+   "Capabilities query timed out\n");
return -1;
}
+
rc = init_sub_crqs(adapter);
if (rc) {
-   dev_err(dev,
-   "Initialization of SCRQ's failed\n");
+   netdev_warn(netdev,
+   "SCRQ initialization failed\n");
return -1;
}
+
rc = init_sub_crq_irqs(adapter);
if (rc) {
-   dev_err(dev,
-   "Initialization of SCRQ's irqs 
failed\n");
+   netdev_warn(netdev,
+   "SCRQ irq initialization failed\n");
return -1;
}
-   }
-
-   reinit_completion(>init_done);
-   rc = send_login(adapter);
-   if (rc) {
-   dev_err(dev, "Unable to attempt device login\n");
-   return rc;
-   } else if (!wait_for_completion_timeout(>init_done,
-timeout)) {
-   dev_err(dev, "Login timeout\n");
+   } else if (adapter->init_done_rc) {
+   netdev_warn(netdev, "Adapter login failed\n");
return -1;

[PATCH net-next] ibmvnic: Split counters for scrq/pools/napi

2018-02-21 Thread Nathan Fontenot
The approach of one counter to rule them all when tracking the number
of active sub-crqs, pools, and napi has problems handling some failover
scenarios. This is due to the split in initializing the sub crqs,
pools and napi in different places and the placement of updating
the active counts.

This patch simplifies this by having a counter for tx and rx
sub-crqs, pools, and napi.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   38 
 drivers/net/ethernet/ibm/ibmvnic.h |7 +--
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 1703b881252f..8ca88f7cc661 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -461,7 +461,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->rx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
+   for (i = 0; i < adapter->num_active_rx_pools; i++) {
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
@@ -484,6 +484,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
+   adapter->num_active_rx_pools = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -508,6 +509,8 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
+   adapter->num_active_rx_pools = rxadd_subcrqs;
+
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
 
@@ -608,7 +611,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->tx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
+   for (i = 0; i < adapter->num_active_tx_pools; i++) {
netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
@@ -619,6 +622,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
+   adapter->num_active_tx_pools = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -635,6 +639,8 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
+   adapter->num_active_tx_pools = tx_subcrqs;
+
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
 
@@ -745,6 +751,7 @@ static int init_napi(struct ibmvnic_adapter *adapter)
   ibmvnic_poll, NAPI_POLL_WEIGHT);
}
 
+   adapter->num_active_rx_napi = adapter->req_rx_queues;
return 0;
 }
 
@@ -755,7 +762,7 @@ static void release_napi(struct ibmvnic_adapter *adapter)
if (!adapter->napi)
return;
 
-   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
+   for (i = 0; i < adapter->num_active_rx_napi; i++) {
if (>napi[i]) {
netdev_dbg(adapter->netdev,
   "Releasing napi[%d]\n", i);
@@ -765,6 +772,7 @@ static void release_napi(struct ibmvnic_adapter *adapter)
 
kfree(adapter->napi);
adapter->napi = NULL;
+   adapter->num_active_rx_napi = 0;
 }
 
 static int ibmvnic_login(struct net_device *netdev)
@@ -998,10 +1006,6 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 
rc = init_tx_pools(netdev);
-
-   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
-   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
-
return rc;
 }
 
@@ -1706,9 +1710,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
 
release_napi(adapter);
init_napi(adapter);
-
-   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
-   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {
rc = reset_tx_pools(adapter);
if (rc)
@@ -2398,19 +2399,10 @@ static struct ibmvnic_sub_crq_queue 
*init_sub_crq_queue(struct ibmvnic_adapter
 
 static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free)
 {
-   u64 num_tx_scrqs, num_rx_scrqs;
int i;
 
-   if (adapter->state == VNIC_PROBED) {
-   num_tx_scrqs = adapter->req_tx_queues;
-   num_rx_scrqs = adapter->req_rx_queues;
-   } else {
-   num_tx_scrqs = adapter->num_active_tx_scrqs;
-   num_rx_scrqs 

[PATCH net-next ] ibmvnic: Correct goto target for tx irq initialization failure

2018-02-20 Thread Nathan Fontenot
When a failure occurs during initialization of the tx sub crq
irqs, we should branch to the cleanup of the tx irqs. The current
code branches to the rx irq cleanup and attempts to cleanup the
rx irqs which have not been initialized.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 996f47568f9e..3c7b02de7e56 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2585,7 +2585,7 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter 
*adapter)
dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n",
scrq->irq, rc);
irq_dispose_mapping(scrq->irq);
-   goto req_rx_irq_failed;
+   goto req_tx_irq_failed;
}
}
 



[PATCH V3 net-next 5/5] ibmvnic: Allocate max queues stats buffers

2018-02-19 Thread Nathan Fontenot
To avoid losing any stats when the number of sub-crqs change, allocate
the max number of stats buffers so a stats buffer exists all possible
sub-crqs.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 94d4486dde81..40cba315a523 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -361,14 +361,14 @@ static void release_stats_buffers(struct ibmvnic_adapter 
*adapter)
 static int init_stats_buffers(struct ibmvnic_adapter *adapter)
 {
adapter->tx_stats_buffers =
-   kcalloc(adapter->req_tx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_tx_queue_stats),
GFP_KERNEL);
if (!adapter->tx_stats_buffers)
return -ENOMEM;
 
adapter->rx_stats_buffers =
-   kcalloc(adapter->req_rx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_rx_queue_stats),
GFP_KERNEL);
if (!adapter->rx_stats_buffers)



Re: [PATCH V2 net-next 3/5] ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change

2018-02-19 Thread Nathan Fontenot
On 02/19/2018 01:16 PM, David Miller wrote:
> From: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> Date: Sun, 18 Feb 2018 19:34:47 -0600
> 
>> @@ -2241,24 +2241,27 @@ static int reset_sub_crq_queues(struct 
>> ibmvnic_adapter *adapter)
>>  }
>>  
>>  static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
>> -  struct ibmvnic_sub_crq_queue *scrq)
>> +  struct ibmvnic_sub_crq_queue *scrq,
>> +  int do_h_free)
>>  {
> 
> Please use 'bool' and true/false for do_h_free.

Version 3 sent with this update.

-Nathan

> 
> Thank you.
> 



[PATCH V3 net-next 2/5] ibmvnic: Move active sub-crq count settings

2018-02-19 Thread Nathan Fontenot
Inpreparation for using the active scrq count to track more active
resources, move the setting of the active count to after initialization
occurs in initial driver init and during driver reset.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index ca2e3fbfd848..9cfbb20b5ac1 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -484,7 +484,6 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,8 +508,6 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_scrqs = 0;
-
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
 
@@ -554,8 +551,6 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_scrqs = rxadd_subcrqs;
-
return 0;
 }
 
@@ -624,7 +619,6 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,8 +635,6 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_scrqs = 0;
-
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
 
@@ -690,8 +682,6 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_scrqs = tx_subcrqs;
-
return 0;
 }
 
@@ -975,6 +965,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 
rc = init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
+
return rc;
 }
 
@@ -1646,6 +1640,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
release_tx_pools(adapter);
init_rx_pools(netdev);
init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {
rc = reset_tx_pools(adapter);
if (rc)



[PATCH V3 net-next 1/5] ibmvnic: Rename active queue count variables

2018-02-19 Thread Nathan Fontenot
Rename the tx/rx active pool variables to be tx/rx active scrq
counts. The tx/rx pools are per sub-crq so this is a more appropriate
name. This also is a preparatory step for using thiese variables
for handling updates to sub-crqs and napi based on the active
count.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   16 
 drivers/net/ethernet/ibm/ibmvnic.h |4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 27447260215d..ca2e3fbfd848 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -461,7 +461,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->rx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_rx_pools; i++) {
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
@@ -484,7 +484,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,7 +509,7 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
@@ -554,7 +554,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_pools = rxadd_subcrqs;
+   adapter->num_active_rx_scrqs = rxadd_subcrqs;
 
return 0;
 }
@@ -613,7 +613,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->tx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_tx_pools; i++) {
+   for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
@@ -624,7 +624,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,7 +641,7 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
@@ -690,7 +690,7 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_pools = tx_subcrqs;
+   adapter->num_active_tx_scrqs = tx_subcrqs;
 
return 0;
 }
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index fe21a6e2ddae..c6d0b4afe899 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1091,8 +1091,8 @@ struct ibmvnic_adapter {
u64 opt_rxba_entries_per_subcrq;
__be64 tx_rx_desc_req;
u8 map_id;
-   u64 num_active_rx_pools;
-   u64 num_active_tx_pools;
+   u64 num_active_rx_scrqs;
+   u64 num_active_tx_scrqs;
 
struct tasklet_struct tasklet;
enum vnic_state state;



[PATCH V3 net-next 3/5] ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change

2018-02-19 Thread Nathan Fontenot
When the driver resets it is possible that the number of tx/rx
sub-crqs can change. This patch handles this so that the driver does
not try to access non-existent sub-crqs.

The count for releasing sub crqs depends on the adapter state. The
active queue count is not set in probe, so if we are relasing in probe
state we use the request queue count.

Additionally, a parameter is added to release_sub_crqs() so that
we know if the h_call to free the sub-crq needs to be made. In
the reset path we have to do a reset of the main crq, which is
a free followed by a register of the main crq. The free of main
crq results in all of the sub crq's being free'ed. When updating
sub-crq count in the reset path we do not want to h_free the
sub-crqs, they are already free'ed.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

Updates for V3: Change do_h_free parameter to bool

Updates for V2: Use the correct scrq count for releasing scrqs
when adapter is in probed state.

 drivers/net/ethernet/ibm/ibmvnic.c |   78 
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 9cfbb20b5ac1..2741b06b8ec4 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
 
 static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
 static int ibmvnic_remove(struct vio_dev *);
-static void release_sub_crqs(struct ibmvnic_adapter *);
+static void release_sub_crqs(struct ibmvnic_adapter *, bool);
 static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
 static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
 static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
@@ -740,7 +740,7 @@ static int ibmvnic_login(struct net_device *netdev)
do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
 
reinit_completion(>init_done);
send_cap_queries(adapter);
@@ -1602,7 +1602,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
adapter->wait_for_reset) {
release_resources(adapter);
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
release_crq_queue(adapter);
}
 
@@ -2241,24 +2241,27 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter 
*adapter)
 }
 
 static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
- struct ibmvnic_sub_crq_queue *scrq)
+ struct ibmvnic_sub_crq_queue *scrq,
+ bool do_h_free)
 {
struct device *dev = >vdev->dev;
long rc;
 
netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
 
-   /* Close the sub-crqs */
-   do {
-   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
-   adapter->vdev->unit_address,
-   scrq->crq_num);
-   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+   if (do_h_free) {
+   /* Close the sub-crqs */
+   do {
+   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
+   adapter->vdev->unit_address,
+   scrq->crq_num);
+   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
 
-   if (rc) {
-   netdev_err(adapter->netdev,
-  "Failed to release sub-CRQ %16lx, rc = %ld\n",
-  scrq->crq_num, rc);
+   if (rc) {
+   netdev_err(adapter->netdev,
+  "Failed to release sub-CRQ %16lx, rc = 
%ld\n",
+  scrq->crq_num, rc);
+   }
}
 
dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
@@ -2326,12 +2329,21 @@ static struct ibmvnic_sub_crq_queue 
*init_sub_crq_queue(struct ibmvnic_adapter
return NULL;
 }
 
-static void release_sub_crqs(struct ibmvnic_adapter *adapter)
+static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free)
 {
+   u64 num_tx_scrqs, num_rx_scrqs;
int i;
 
+   if (adapter->state == VNIC_PROBED) {
+   num_tx_scrqs = adapter->req_tx_queues;
+   num_rx_scrqs = adapter->req_rx_queues;
+   } else {
+   num_tx_scrqs = adapter->num_active_tx_scrqs;
+   num_rx_scrqs = adapter->num_active_rx_scrqs;
+   }
+
if (adapter->tx_scrq) {
-   for (i = 0; i < adapter->req_t

[PATCH V3 net-next 4/5] ibmvnic: Make napi usage dynamic

2018-02-19 Thread Nathan Fontenot
In order to handle the number of rx sub crqs changing during a driver
reset, the ibmvnic driver also needs to update the number of napi.
To do this the code to init and free napi's is moved to their own
routines so they can be called during the reset process.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   67 
 1 file changed, 45 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 2741b06b8ec4..94d4486dde81 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -730,6 +730,43 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
adapter->napi_enabled = false;
 }
 
+static int init_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   adapter->napi = kcalloc(adapter->req_rx_queues,
+   sizeof(struct napi_struct), GFP_KERNEL);
+   if (!adapter->napi)
+   return -ENOMEM;
+
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Adding napi[%d]\n", i);
+   netif_napi_add(adapter->netdev, >napi[i],
+  ibmvnic_poll, NAPI_POLL_WEIGHT);
+   }
+
+   return 0;
+}
+
+static void release_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   if (!adapter->napi)
+   return;
+
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
+   netif_napi_del(>napi[i]);
+   }
+   }
+
+   kfree(adapter->napi);
+   adapter->napi = NULL;
+}
+
 static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -783,8 +820,6 @@ static int ibmvnic_login(struct net_device *netdev)
 
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
-   int i;
-
release_vpd_data(adapter);
 
release_tx_pools(adapter);
@@ -793,16 +828,7 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
release_stats_token(adapter);
release_stats_buffers(adapter);
release_error_buffers(adapter);
-
-   if (adapter->napi) {
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i]) {
-   netdev_dbg(adapter->netdev,
-  "Releasing napi[%d]\n", i);
-   netif_napi_del(>napi[i]);
-   }
-   }
-   }
+   release_napi(adapter);
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
@@ -921,7 +947,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
 static int init_resources(struct ibmvnic_adapter *adapter)
 {
struct net_device *netdev = adapter->netdev;
-   int i, rc;
+   int rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -947,16 +973,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
}
 
adapter->map_id = 1;
-   adapter->napi = kcalloc(adapter->req_rx_queues,
-   sizeof(struct napi_struct), GFP_KERNEL);
-   if (!adapter->napi)
-   return -ENOMEM;
 
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   netdev_dbg(netdev, "Adding napi[%d]\n", i);
-   netif_napi_add(netdev, >napi[i], ibmvnic_poll,
-  NAPI_POLL_WEIGHT);
-   }
+   rc = init_napi(adapter);
+   if (rc)
+   return rc;
 
send_map_query(adapter);
 
@@ -1641,6 +1661,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
init_rx_pools(netdev);
init_tx_pools(netdev);
 
+   release_napi(adapter);
+   init_napi(adapter);
+
adapter->num_active_tx_scrqs = adapter->req_tx_queues;
adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {



[PATCH V3 net-next 0/5] ibmvnic: Make driver resources dynamic

2018-02-19 Thread Nathan Fontenot
The ibmvnic driver needs to be able to handle the number of tx/rx
sub-crqs changing during a reset of the driver. To do this several
changes need to be made. First the num_active_[tx|rx]_pools
counters need to be re-named to num_active_[tc|rx]_scrqs, and
updated after resource initialization.

With this change we can now release and init the sub crqs and napi
(for rx sub crqs) when the number of sub crqs change.

Lastly, the stats buffer allocation is updated to always allocate
the maximum number of sub-crqs count of stats buffers.

-Nathan
---

Updates for V3:
Patch 3/5 - Make do_h_free parameter a bool

Updates for V2: 
Patch 3/5 - Use correct queue count when driver is in probed state
for releasing sub crqs.


Nathan Fontenot (5):
  ibmvnic: Rename active queue count variables
  ibmvnic: Move active sub-crq count settings
  ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change
  ibmvnic: Make napi usage dynamic
  ibmvnic: Allocate max queues stats buffers


 drivers/net/ethernet/ibm/ibmvnic.c |  170 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |4 -
 2 files changed, 110 insertions(+), 64 deletions(-)



Re: [PATCH net-next3/5] ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change

2018-02-18 Thread Nathan Fontenot
On 02/17/2018 05:32 PM, Nathan Fontenot wrote:
> When the driver resets it is possible that the number of tx/rx
> sub-crqs can change. This patch handles this so that the driver does
> not try to access non-existent sub-crqs.
> 
> Additionally, a parameter is added to release_sub_crqs() so that
> we know if the h_call to free the sub-crq needs to be made. In
> the reset path we have to do a reset of the main crq, which is
> a free followed by a register of the main crq. The free of main
> crq results in all of the sub crq's being free'ed. When updating
> sub-crq count in the reset path we do not want to h_free the
> sub-crqs, they are already free'ed.

This patch has a bug in that it does not use the correct queue count
when releasing the sub crqs when the driver is in the probed state.

A version 2 of the patch set will be sent.

-Nathan

> 
> Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> ---
>  drivers/net/ethernet/ibm/ibmvnic.c |   69 
> ++--
>  1 file changed, 43 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 9cfbb20b5ac1..a3079d5c072c 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
> 
>  static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
>  static int ibmvnic_remove(struct vio_dev *);
> -static void release_sub_crqs(struct ibmvnic_adapter *);
> +static void release_sub_crqs(struct ibmvnic_adapter *, int);
>  static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
>  static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
>  static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
> @@ -740,7 +740,7 @@ static int ibmvnic_login(struct net_device *netdev)
>   do {
>   if (adapter->renegotiate) {
>   adapter->renegotiate = false;
> - release_sub_crqs(adapter);
> + release_sub_crqs(adapter, 1);
> 
>   reinit_completion(>init_done);
>   send_cap_queries(adapter);
> @@ -1602,7 +1602,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
>   if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
>   adapter->wait_for_reset) {
>   release_resources(adapter);
> - release_sub_crqs(adapter);
> + release_sub_crqs(adapter, 1);
>   release_crq_queue(adapter);
>   }
> 
> @@ -2241,24 +2241,27 @@ static int reset_sub_crq_queues(struct 
> ibmvnic_adapter *adapter)
>  }
> 
>  static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
> -   struct ibmvnic_sub_crq_queue *scrq)
> +   struct ibmvnic_sub_crq_queue *scrq,
> +   int do_h_free)
>  {
>   struct device *dev = >vdev->dev;
>   long rc;
> 
>   netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
> 
> - /* Close the sub-crqs */
> - do {
> - rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
> - adapter->vdev->unit_address,
> - scrq->crq_num);
> - } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
> + if (do_h_free) {
> + /* Close the sub-crqs */
> + do {
> + rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
> + adapter->vdev->unit_address,
> + scrq->crq_num);
> + } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
> 
> - if (rc) {
> - netdev_err(adapter->netdev,
> -"Failed to release sub-CRQ %16lx, rc = %ld\n",
> -scrq->crq_num, rc);
> + if (rc) {
> + netdev_err(adapter->netdev,
> +"Failed to release sub-CRQ %16lx, rc = 
> %ld\n",
> +scrq->crq_num, rc);
> + }
>   }
> 
>   dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
> @@ -2326,12 +2329,12 @@ static struct ibmvnic_sub_crq_queue 
> *init_sub_crq_queue(struct ibmvnic_adapter
>   return NULL;
>  }
> 
> -static void release_sub_crqs(struct ibmvnic_adapter *adapter)
> +static void release_sub_crqs(struct ibmvnic_adapter *adapter, int do_h_free)
>  {
>   int i;
> 
>   if (adapter->tx_scrq) {
> - for (i = 0; i < adapter->req_tx_queues; i++) {
> +

[PATCH V2 net-next 5/5] ibmvnic: Allocate max queues stats buffers

2018-02-18 Thread Nathan Fontenot
To avoid losing any stats when the number of sub-crqs change, allocate
the max number of stats buffers so a stats buffer exists all possible
sub-crqs.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 0e2894a90885..14f2cffbbb55 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -361,14 +361,14 @@ static void release_stats_buffers(struct ibmvnic_adapter 
*adapter)
 static int init_stats_buffers(struct ibmvnic_adapter *adapter)
 {
adapter->tx_stats_buffers =
-   kcalloc(adapter->req_tx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_tx_queue_stats),
GFP_KERNEL);
if (!adapter->tx_stats_buffers)
return -ENOMEM;
 
adapter->rx_stats_buffers =
-   kcalloc(adapter->req_rx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_rx_queue_stats),
GFP_KERNEL);
if (!adapter->rx_stats_buffers)



[PATCH V2 net-next 4/5] ibmvnic: Make napi usage dynamic

2018-02-18 Thread Nathan Fontenot
In order to handle the number of rx sub crqs changing during a driver
reset, the ibmvnic driver also needs to update the number of napi.
To do this the code to init and free napi's is moved to their own
routines so they can be called during the reset process.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   67 
 1 file changed, 45 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 35a17234be30..0e2894a90885 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -730,6 +730,43 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
adapter->napi_enabled = false;
 }
 
+static int init_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   adapter->napi = kcalloc(adapter->req_rx_queues,
+   sizeof(struct napi_struct), GFP_KERNEL);
+   if (!adapter->napi)
+   return -ENOMEM;
+
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Adding napi[%d]\n", i);
+   netif_napi_add(adapter->netdev, >napi[i],
+  ibmvnic_poll, NAPI_POLL_WEIGHT);
+   }
+
+   return 0;
+}
+
+static void release_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   if (!adapter->napi)
+   return;
+
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
+   netif_napi_del(>napi[i]);
+   }
+   }
+
+   kfree(adapter->napi);
+   adapter->napi = NULL;
+}
+
 static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -783,8 +820,6 @@ static int ibmvnic_login(struct net_device *netdev)
 
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
-   int i;
-
release_vpd_data(adapter);
 
release_tx_pools(adapter);
@@ -793,16 +828,7 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
release_stats_token(adapter);
release_stats_buffers(adapter);
release_error_buffers(adapter);
-
-   if (adapter->napi) {
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i]) {
-   netdev_dbg(adapter->netdev,
-  "Releasing napi[%d]\n", i);
-   netif_napi_del(>napi[i]);
-   }
-   }
-   }
+   release_napi(adapter);
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
@@ -921,7 +947,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
 static int init_resources(struct ibmvnic_adapter *adapter)
 {
struct net_device *netdev = adapter->netdev;
-   int i, rc;
+   int rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -947,16 +973,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
}
 
adapter->map_id = 1;
-   adapter->napi = kcalloc(adapter->req_rx_queues,
-   sizeof(struct napi_struct), GFP_KERNEL);
-   if (!adapter->napi)
-   return -ENOMEM;
 
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   netdev_dbg(netdev, "Adding napi[%d]\n", i);
-   netif_napi_add(netdev, >napi[i], ibmvnic_poll,
-  NAPI_POLL_WEIGHT);
-   }
+   rc = init_napi(adapter);
+   if (rc)
+   return rc;
 
send_map_query(adapter);
 
@@ -1641,6 +1661,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
init_rx_pools(netdev);
init_tx_pools(netdev);
 
+   release_napi(adapter);
+   init_napi(adapter);
+
adapter->num_active_tx_scrqs = adapter->req_tx_queues;
adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {



[PATCH V2 net-next 3/5] ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change

2018-02-18 Thread Nathan Fontenot
When the driver resets it is possible that the number of tx/rx
sub-crqs can change. This patch handles this so that the driver does
not try to access non-existent sub-crqs.

The count for releasing sub crqs depends on the adapter state. The
active queue count is not set in probe, so if we are relasing in probe
state we use the request queue count.

Additionally, a parameter is added to release_sub_crqs() so that
we know if the h_call to free the sub-crq needs to be made. In
the reset path we have to do a reset of the main crq, which is
a free followed by a register of the main crq. The free of main
crq results in all of the sub crq's being free'ed. When updating
sub-crq count in the reset path we do not want to h_free the
sub-crqs, they are already free'ed.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

Updates for V2: Use the correct scrq count for releasing scrqs
when adapter is in probed state.

 drivers/net/ethernet/ibm/ibmvnic.c |   78 
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 9cfbb20b5ac1..35a17234be30 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
 
 static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
 static int ibmvnic_remove(struct vio_dev *);
-static void release_sub_crqs(struct ibmvnic_adapter *);
+static void release_sub_crqs(struct ibmvnic_adapter *, int);
 static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
 static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
 static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
@@ -740,7 +740,7 @@ static int ibmvnic_login(struct net_device *netdev)
do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
 
reinit_completion(>init_done);
send_cap_queries(adapter);
@@ -1602,7 +1602,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
adapter->wait_for_reset) {
release_resources(adapter);
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
release_crq_queue(adapter);
}
 
@@ -2241,24 +2241,27 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter 
*adapter)
 }
 
 static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
- struct ibmvnic_sub_crq_queue *scrq)
+ struct ibmvnic_sub_crq_queue *scrq,
+ int do_h_free)
 {
struct device *dev = >vdev->dev;
long rc;
 
netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
 
-   /* Close the sub-crqs */
-   do {
-   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
-   adapter->vdev->unit_address,
-   scrq->crq_num);
-   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+   if (do_h_free) {
+   /* Close the sub-crqs */
+   do {
+   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
+   adapter->vdev->unit_address,
+   scrq->crq_num);
+   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
 
-   if (rc) {
-   netdev_err(adapter->netdev,
-  "Failed to release sub-CRQ %16lx, rc = %ld\n",
-  scrq->crq_num, rc);
+   if (rc) {
+   netdev_err(adapter->netdev,
+  "Failed to release sub-CRQ %16lx, rc = 
%ld\n",
+  scrq->crq_num, rc);
+   }
}
 
dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
@@ -2326,12 +2329,21 @@ static struct ibmvnic_sub_crq_queue 
*init_sub_crq_queue(struct ibmvnic_adapter
return NULL;
 }
 
-static void release_sub_crqs(struct ibmvnic_adapter *adapter)
+static void release_sub_crqs(struct ibmvnic_adapter *adapter, int do_h_free)
 {
+   u64 num_tx_scrqs, num_rx_scrqs;
int i;
 
+   if (adapter->state == VNIC_PROBED) {
+   num_tx_scrqs = adapter->req_tx_queues;
+   num_rx_scrqs = adapter->req_rx_queues;
+   } else {
+   num_tx_scrqs = adapter->num_active_tx_scrqs;
+   num_rx_scrqs = adapter->num_active_rx_scrqs;
+   }
+
if (adapter->tx_scrq) {
-   for (i = 0; i < adapter->req_tx_queues; i++) {
+   for (i = 0; i < num_tx_scrqs;

[PATCH V2 net-next 2/5] ibmvnic: Move active sub-crq count settings

2018-02-18 Thread Nathan Fontenot
In preparation for using the active scrq count to track more active
resources, move the setting of the active count to after initialization
occurs in initial driver init and during driver reset.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index ca2e3fbfd848..9cfbb20b5ac1 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -484,7 +484,6 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,8 +508,6 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_scrqs = 0;
-
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
 
@@ -554,8 +551,6 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_scrqs = rxadd_subcrqs;
-
return 0;
 }
 
@@ -624,7 +619,6 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,8 +635,6 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_scrqs = 0;
-
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
 
@@ -690,8 +682,6 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_scrqs = tx_subcrqs;
-
return 0;
 }
 
@@ -975,6 +965,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 
rc = init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
+
return rc;
 }
 
@@ -1646,6 +1640,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
release_tx_pools(adapter);
init_rx_pools(netdev);
init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {
rc = reset_tx_pools(adapter);
if (rc)



[PATCH V2 net-next 1/5] ibmvnic: Rename active queue count variables

2018-02-18 Thread Nathan Fontenot
Rename the tx/rx active pool variables to be tx/rx active scrq
counts. The tx/rx pools are per sub-crq so this is a more appropriate
name. This also is a preparatory step for using thiese variables
for handling updates to sub-crqs and napi based on the active
count.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   16 
 drivers/net/ethernet/ibm/ibmvnic.h |4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 27447260215d..ca2e3fbfd848 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -461,7 +461,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->rx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_rx_pools; i++) {
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
@@ -484,7 +484,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,7 +509,7 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
@@ -554,7 +554,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_pools = rxadd_subcrqs;
+   adapter->num_active_rx_scrqs = rxadd_subcrqs;
 
return 0;
 }
@@ -613,7 +613,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->tx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_tx_pools; i++) {
+   for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
@@ -624,7 +624,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,7 +641,7 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
@@ -690,7 +690,7 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_pools = tx_subcrqs;
+   adapter->num_active_tx_scrqs = tx_subcrqs;
 
return 0;
 }
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index fe21a6e2ddae..c6d0b4afe899 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1091,8 +1091,8 @@ struct ibmvnic_adapter {
u64 opt_rxba_entries_per_subcrq;
__be64 tx_rx_desc_req;
u8 map_id;
-   u64 num_active_rx_pools;
-   u64 num_active_tx_pools;
+   u64 num_active_rx_scrqs;
+   u64 num_active_tx_scrqs;
 
struct tasklet_struct tasklet;
enum vnic_state state;



[PATCH V2 net-next 0/5] ibmvnic: Make driver resources dynamic

2018-02-18 Thread Nathan Fontenot
The ibmvnic driver needs to be able to handle the number of tx/rx
sub-crqs changing during a reset of the driver. To do this several
changes need to be made. First the num_active_[tx|rx]_pools
counters need to be re-named to num_active_[tc|rx]_scrqs, and
updated after resource initialization.

With this change we can now release and init the sub crqs and napi
(for rx sub crqs) when the number of sub crqs change.

Lastly, the stats buffer allocation is updated to always allocate
the maximum number of sub-crqs count of stats buffers.

-Nathan
---

Updates for V2: 
Patch 3/5 - Use correct queue count when driver is in probed state
for releasing sub crqs.

Nathan Fontenot (5):
  ibmvnic: Rename active queue count variables
  ibmvnic: Move active sub-crq count settings
  ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change
  ibmvnic: Make napi usage dynamic
  ibmvnic: Allocate max queues stats buffers


 drivers/net/ethernet/ibm/ibmvnic.c |  170 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |4 -
 2 files changed, 110 insertions(+), 64 deletions(-)



[PATCH net-next4/5] ibmvnic: Make napi usage dynamic

2018-02-17 Thread Nathan Fontenot
In order to handle the number of rx sub crqs changing during a driver
reset, the ibmvnic driver also needs to update the number of napi.
To do this the code to init and free napi's is moved to their own
routines so they can be called during the reset process.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   67 
 1 file changed, 45 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index a3079d5c072c..f4261f03a522 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -730,6 +730,43 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
adapter->napi_enabled = false;
 }
 
+static int init_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   adapter->napi = kcalloc(adapter->req_rx_queues,
+   sizeof(struct napi_struct), GFP_KERNEL);
+   if (!adapter->napi)
+   return -ENOMEM;
+
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Adding napi[%d]\n", i);
+   netif_napi_add(adapter->netdev, >napi[i],
+  ibmvnic_poll, NAPI_POLL_WEIGHT);
+   }
+
+   return 0;
+}
+
+static void release_napi(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   if (!adapter->napi)
+   return;
+
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
+   netif_napi_del(>napi[i]);
+   }
+   }
+
+   kfree(adapter->napi);
+   adapter->napi = NULL;
+}
+
 static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -783,8 +820,6 @@ static int ibmvnic_login(struct net_device *netdev)
 
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
-   int i;
-
release_vpd_data(adapter);
 
release_tx_pools(adapter);
@@ -793,16 +828,7 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
release_stats_token(adapter);
release_stats_buffers(adapter);
release_error_buffers(adapter);
-
-   if (adapter->napi) {
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i]) {
-   netdev_dbg(adapter->netdev,
-  "Releasing napi[%d]\n", i);
-   netif_napi_del(>napi[i]);
-   }
-   }
-   }
+   release_napi(adapter);
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
@@ -921,7 +947,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
 static int init_resources(struct ibmvnic_adapter *adapter)
 {
struct net_device *netdev = adapter->netdev;
-   int i, rc;
+   int rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -947,16 +973,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
}
 
adapter->map_id = 1;
-   adapter->napi = kcalloc(adapter->req_rx_queues,
-   sizeof(struct napi_struct), GFP_KERNEL);
-   if (!adapter->napi)
-   return -ENOMEM;
 
-   for (i = 0; i < adapter->req_rx_queues; i++) {
-   netdev_dbg(netdev, "Adding napi[%d]\n", i);
-   netif_napi_add(netdev, >napi[i], ibmvnic_poll,
-  NAPI_POLL_WEIGHT);
-   }
+   rc = init_napi(adapter);
+   if (rc)
+   return rc;
 
send_map_query(adapter);
 
@@ -1641,6 +1661,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
init_rx_pools(netdev);
init_tx_pools(netdev);
 
+   release_napi(adapter);
+   init_napi(adapter);
+
adapter->num_active_tx_scrqs = adapter->req_tx_queues;
adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {



[PATCH net-next3/5] ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change

2018-02-17 Thread Nathan Fontenot
When the driver resets it is possible that the number of tx/rx
sub-crqs can change. This patch handles this so that the driver does
not try to access non-existent sub-crqs.

Additionally, a parameter is added to release_sub_crqs() so that
we know if the h_call to free the sub-crq needs to be made. In
the reset path we have to do a reset of the main crq, which is
a free followed by a register of the main crq. The free of main
crq results in all of the sub crq's being free'ed. When updating
sub-crq count in the reset path we do not want to h_free the
sub-crqs, they are already free'ed.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   69 ++--
 1 file changed, 43 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 9cfbb20b5ac1..a3079d5c072c 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
 
 static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
 static int ibmvnic_remove(struct vio_dev *);
-static void release_sub_crqs(struct ibmvnic_adapter *);
+static void release_sub_crqs(struct ibmvnic_adapter *, int);
 static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
 static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
 static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
@@ -740,7 +740,7 @@ static int ibmvnic_login(struct net_device *netdev)
do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
 
reinit_completion(>init_done);
send_cap_queries(adapter);
@@ -1602,7 +1602,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
adapter->wait_for_reset) {
release_resources(adapter);
-   release_sub_crqs(adapter);
+   release_sub_crqs(adapter, 1);
release_crq_queue(adapter);
}
 
@@ -2241,24 +2241,27 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter 
*adapter)
 }
 
 static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
- struct ibmvnic_sub_crq_queue *scrq)
+ struct ibmvnic_sub_crq_queue *scrq,
+ int do_h_free)
 {
struct device *dev = >vdev->dev;
long rc;
 
netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
 
-   /* Close the sub-crqs */
-   do {
-   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
-   adapter->vdev->unit_address,
-   scrq->crq_num);
-   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+   if (do_h_free) {
+   /* Close the sub-crqs */
+   do {
+   rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
+   adapter->vdev->unit_address,
+   scrq->crq_num);
+   } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
 
-   if (rc) {
-   netdev_err(adapter->netdev,
-  "Failed to release sub-CRQ %16lx, rc = %ld\n",
-  scrq->crq_num, rc);
+   if (rc) {
+   netdev_err(adapter->netdev,
+  "Failed to release sub-CRQ %16lx, rc = 
%ld\n",
+  scrq->crq_num, rc);
+   }
}
 
dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
@@ -2326,12 +2329,12 @@ static struct ibmvnic_sub_crq_queue 
*init_sub_crq_queue(struct ibmvnic_adapter
return NULL;
 }
 
-static void release_sub_crqs(struct ibmvnic_adapter *adapter)
+static void release_sub_crqs(struct ibmvnic_adapter *adapter, int do_h_free)
 {
int i;
 
if (adapter->tx_scrq) {
-   for (i = 0; i < adapter->req_tx_queues; i++) {
+   for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
if (!adapter->tx_scrq[i])
continue;
 
@@ -2344,7 +2347,8 @@ static void release_sub_crqs(struct ibmvnic_adapter 
*adapter)
adapter->tx_scrq[i]->irq = 0;
}
 
-   release_sub_crq_queue(adapter, adapter->tx_scrq[i]);
+   release_sub_crq_queue(adapter, adapter->tx_scrq[i],
+ do_h_free);
}
 
kfree(adapter->tx_scrq);
@@ -2352,7 +2356,7 @@ static void release_

[PATCH net-next5/5] ibmvnic: Allocate max queues stats buffers

2018-02-17 Thread Nathan Fontenot
To avoid losing any stats when the number of sub-crqs change, allocate
the max number of stats buffers so a stats buffer exists all possible
sub-crqs.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index f4261f03a522..79a0b9bc5edb 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -361,14 +361,14 @@ static void release_stats_buffers(struct ibmvnic_adapter 
*adapter)
 static int init_stats_buffers(struct ibmvnic_adapter *adapter)
 {
adapter->tx_stats_buffers =
-   kcalloc(adapter->req_tx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_tx_queue_stats),
GFP_KERNEL);
if (!adapter->tx_stats_buffers)
return -ENOMEM;
 
adapter->rx_stats_buffers =
-   kcalloc(adapter->req_rx_queues,
+   kcalloc(IBMVNIC_MAX_QUEUES,
sizeof(struct ibmvnic_rx_queue_stats),
GFP_KERNEL);
if (!adapter->rx_stats_buffers)



[PATCH net-next2/5] ibmvnic: Move active sub-crq count settings

2018-02-17 Thread Nathan Fontenot
Inpreparation for using the active scrq count to track more active
resources, move the setting of the active count to after initialization
occurs in initial driver init and during driver reset.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index ca2e3fbfd848..9cfbb20b5ac1 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -484,7 +484,6 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,8 +508,6 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_scrqs = 0;
-
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
 
@@ -554,8 +551,6 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_scrqs = rxadd_subcrqs;
-
return 0;
 }
 
@@ -624,7 +619,6 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,8 +635,6 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_scrqs = 0;
-
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
 
@@ -690,8 +682,6 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_scrqs = tx_subcrqs;
-
return 0;
 }
 
@@ -975,6 +965,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 
rc = init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
+
return rc;
 }
 
@@ -1646,6 +1640,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
release_tx_pools(adapter);
init_rx_pools(netdev);
init_tx_pools(netdev);
+
+   adapter->num_active_tx_scrqs = adapter->req_tx_queues;
+   adapter->num_active_rx_scrqs = adapter->req_rx_queues;
} else {
rc = reset_tx_pools(adapter);
if (rc)



[PATCH net-next1/5] ibmvnic: Rename active queue count variables

2018-02-17 Thread Nathan Fontenot
Rename the tx/rx active pool variables to be tx/rx active scrq
counts. The tx/rx pools are per sub-crq so this is a more appropriate
name. This also is a preparatory step for using thiese variables
for handling updates to sub-crqs and napi based on the active
count.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   16 
 drivers/net/ethernet/ibm/ibmvnic.h |4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 27447260215d..ca2e3fbfd848 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -461,7 +461,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->rx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_rx_pools; i++) {
+   for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
@@ -484,7 +484,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->rx_pool);
adapter->rx_pool = NULL;
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 }
 
 static int init_rx_pools(struct net_device *netdev)
@@ -509,7 +509,7 @@ static int init_rx_pools(struct net_device *netdev)
return -1;
}
 
-   adapter->num_active_rx_pools = 0;
+   adapter->num_active_rx_scrqs = 0;
 
for (i = 0; i < rxadd_subcrqs; i++) {
rx_pool = >rx_pool[i];
@@ -554,7 +554,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool->next_free = 0;
}
 
-   adapter->num_active_rx_pools = rxadd_subcrqs;
+   adapter->num_active_rx_scrqs = rxadd_subcrqs;
 
return 0;
 }
@@ -613,7 +613,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
if (!adapter->tx_pool)
return;
 
-   for (i = 0; i < adapter->num_active_tx_pools; i++) {
+   for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
@@ -624,7 +624,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
kfree(adapter->tx_pool);
adapter->tx_pool = NULL;
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 }
 
 static int init_tx_pools(struct net_device *netdev)
@@ -641,7 +641,7 @@ static int init_tx_pools(struct net_device *netdev)
if (!adapter->tx_pool)
return -1;
 
-   adapter->num_active_tx_pools = 0;
+   adapter->num_active_tx_scrqs = 0;
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
@@ -690,7 +690,7 @@ static int init_tx_pools(struct net_device *netdev)
tx_pool->producer_index = 0;
}
 
-   adapter->num_active_tx_pools = tx_subcrqs;
+   adapter->num_active_tx_scrqs = tx_subcrqs;
 
return 0;
 }
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index fe21a6e2ddae..c6d0b4afe899 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1091,8 +1091,8 @@ struct ibmvnic_adapter {
u64 opt_rxba_entries_per_subcrq;
__be64 tx_rx_desc_req;
u8 map_id;
-   u64 num_active_rx_pools;
-   u64 num_active_tx_pools;
+   u64 num_active_rx_scrqs;
+   u64 num_active_tx_scrqs;
 
struct tasklet_struct tasklet;
enum vnic_state state;



[PATCH net-next 0/5] ibmvnic: Make driver resources dynamic

2018-02-17 Thread Nathan Fontenot
The ibmvnic driver needs to be able to handle the number of tx/rx
sub-crqs changing during a reset of the driver. To do this several
changes need to be made. First the num_active_[tx|rx]_pools
counters need to be re-named to num_active_[tc|rx]_scrqs, and
updated after resource initialization.

With this change we can now release and init the sub crqs and napi
(for rx sub crqs) when the number of sub crqs change.

Lastly, the stats buffer allocation is updated to always allocate
the maximum number of sub-crqs count of stats buffers.

-Nathan
---

Nathan Fontenot (5):
  ibmvnic: Rename active queue count variables
  ibmvnic: Move active sub-crq count settings
  ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change
  ibmvnic: Make napi usage dynamic
  ibmvnic: Allocate max queues stats buffers


 drivers/net/ethernet/ibm/ibmvnic.c |  161 ++--
 drivers/net/ethernet/ibm/ibmvnic.h |4 -
 2 files changed, 101 insertions(+), 64 deletions(-)



[PATCH net-next V2] ibmvnic: Remove skb->protocol checks in ibmvnic_xmit

2018-02-09 Thread Nathan Fontenot
From: John Allen <jal...@linux.vnet.ibm.com>

Having these checks in ibmvnic_xmit causes problems with VLAN
tagging and balance-alb/tlb bonding modes. The restriction they
imposed can be removed.

Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>
Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5caaa9033841..f276c6dcb4a9 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1414,10 +1414,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
hdrs += 2;
}
/* determine if l2/3/4 headers are sent to firmware */
-   if ((*hdrs >> 7) & 1 &&
-   (skb->protocol == htons(ETH_P_IP) ||
-skb->protocol == htons(ETH_P_IPV6) ||
-skb->protocol == htons(ETH_P_ARP))) {
+   if ((*hdrs >> 7) & 1) {
build_hdr_descs_arr(tx_buff, _entries, *hdrs);
tx_crq.v1.n_crq_elem = num_entries;
tx_buff->indir_arr[0] = tx_crq;



Re: [PATCH] ibmvnic: Remove skb->protocol checks in ibmvnic_xmit

2018-02-09 Thread Nathan Fontenot
On 02/09/2018 01:32 PM, Jakub Kicinski wrote:
> On Fri, 09 Feb 2018 13:09:34 -0600, Nathan Fontenot wrote:
>> From: John Allen (jal...@linux.vnet.ibm.com>
> 
> Nit: s/(/ 
>> Having these checks in ibmvnic_xmit causes problems with VLAN
>> tagging and balance-alb/tlb bonding modes. The restriction they
>> imposed can be removed.
>>
>> Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> 
> Patch does not have author's SoB line, the kernel bots will complain
> about this, so please add it if it's not a problem.
> 

Oops. Thanks for pointing this out, I'll re-send.

-Nathan



[PATCH] ibmvnic: Remove skb->protocol checks in ibmvnic_xmit

2018-02-09 Thread Nathan Fontenot
From: John Allen (jal...@linux.vnet.ibm.com>

Having these checks in ibmvnic_xmit causes problems with VLAN
tagging and balance-alb/tlb bonding modes. The restriction they
imposed can be removed.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5caaa9033841..f276c6dcb4a9 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1414,10 +1414,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
hdrs += 2;
}
/* determine if l2/3/4 headers are sent to firmware */
-   if ((*hdrs >> 7) & 1 &&
-   (skb->protocol == htons(ETH_P_IP) ||
-skb->protocol == htons(ETH_P_IPV6) ||
-skb->protocol == htons(ETH_P_ARP))) {
+   if ((*hdrs >> 7) & 1) {
build_hdr_descs_arr(tx_buff, _entries, *hdrs);
tx_crq.v1.n_crq_elem = num_entries;
tx_buff->indir_arr[0] = tx_crq;



[PATCH net-next] ibmvnic: queue reset when CRQ gets closed during reset

2018-02-07 Thread Nathan Fontenot
While handling a driver reset we get a H_CLOSED return trying
to send a CRQ event. When this occurs we need to queue up another
reset attempt. Without doing this we see instances where the driver
is left in a closed state because the reset failed and there is no
further attempts to reset the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5caaa9033841..0f7e1d016207 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2908,8 +2908,12 @@ static int ibmvnic_send_crq(struct ibmvnic_adapter 
*adapter,
cpu_to_be64(u64_crq[1]));
 
if (rc) {
-   if (rc == H_CLOSED)
+   if (rc == H_CLOSED) {
dev_warn(dev, "CRQ Queue closed\n");
+   if (adapter->resetting)
+   ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+   }
+
dev_warn(dev, "Send error (rc=%d)\n", rc);
}
 



Re: [PATCH net v2 3/3] ibmvnic: Allocate and request vpd in init_resources

2018-01-19 Thread Nathan Fontenot
On 01/18/2018 04:27 PM, John Allen wrote:
> In reset events in which our memory allocations need to be reallocated,
> VPD data is being freed, but never reallocated. This can cause issues if
> we later attempt to access that memory or reset and attempt to free the
> memory. This patch moves the allocation of the VPD data to init_resources
> so that it will be symmetrically freed during release resources.
> 
> Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index bb56460..f0dbb76 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -867,7 +867,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter 
> *adapter)
>   if (adapter->vpd->buff)
>   len = adapter->vpd->len;
> 
> - reinit_completion(>fw_done);
> + init_completion(>fw_done);
>   crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
>   crq.get_vpd_size.cmd = GET_VPD_SIZE;
>   ibmvnic_send_crq(adapter, );
> @@ -929,6 +929,13 @@ static int init_resources(struct ibmvnic_adapter 
> *adapter)
>   if (!adapter->vpd)
>   return -ENOMEM;
> 
> + /* Vital Product Data (VPD) */
> + rc = ibmvnic_get_vpd(adapter);
> + if (rc) {
> + netdev_err(netdev, "failed to initialize Vital Product Data 
> (VPD)\n");
> + return rc;
> + }
> +
>   adapter->map_id = 1;
>   adapter->napi = kcalloc(adapter->req_rx_queues,
>   sizeof(struct napi_struct), GFP_KERNEL);
> @@ -1002,7 +1009,7 @@ static int __ibmvnic_open(struct net_device *netdev)
>  static int ibmvnic_open(struct net_device *netdev)
>  {
>   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
> - int rc, vpd;
> + int rc;
> 
>   mutex_lock(>reset_lock);
> 
> @@ -1030,11 +1037,6 @@ static int ibmvnic_open(struct net_device *netdev)
>   rc = __ibmvnic_open(netdev);
>   netif_carrier_on(netdev);
> 
> - /* Vital Product Data (VPD) */
> - vpd = ibmvnic_get_vpd(adapter);
> - if (vpd)
> - netdev_err(netdev, "failed to initialize Vital Product Data 
> (VPD)\n");
> -
>   mutex_unlock(>reset_lock);
> 
>   return rc;
> 



Re: [PATCH net v2 2/3] ibmvnic: Revert to previous mtu when unsupported value requested

2018-01-19 Thread Nathan Fontenot


On 01/18/2018 04:27 PM, John Allen wrote:
> If we request an unsupported mtu value, the vnic server will suggest a
> different value. Currently we take the suggested value without question
> and login with that value. However, the behavior doesn't seem completely
> sane as attempting to change the mtu to some specific value will change
> the mtu to some completely different value most of the time. This patch
> fixes the issue by logging in with the previously used mtu value and
> printing an error message saying that the given mtu is unsupported.
> 
> Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index f8f1396..bb56460 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -3608,7 +3608,17 @@ static void handle_request_cap_rsp(union ibmvnic_crq 
> *crq,
>*req_value,
>(long int)be64_to_cpu(crq->request_capability_rsp.
>  number), name);
> - *req_value = be64_to_cpu(crq->request_capability_rsp.number);
> +
> + if (be16_to_cpu(crq->request_capability_rsp.capability) ==
> + REQ_MTU) {
> + pr_err("mtu of %llu is not supported. Reverting.\n",
> +*req_value);
> + *req_value = adapter->fallback.mtu;
> + } else {
> + *req_value =
> + be64_to_cpu(crq->request_capability_rsp.number);
> + }
> +
>   ibmvnic_send_req_caps(adapter, 1);
>   return;
>   default:
> 



Re: [PATCH net v2 1/3] ibmvnic: Modify buffer size and number of queues on failover

2018-01-19 Thread Nathan Fontenot
On 01/18/2018 04:26 PM, John Allen wrote:
> Using newer backing devices can cause the required padding at the end of
> buffer as well as the number of queues to change after a failover.
> Since we currently assume that these values never change, after a
> failover to a backing device with different capabilities, we can get
> errors from the vnic server, attempt to free long term buffers that are
> no longer there, or not free long term buffers that should be freed.
> 
> This patch resolves the issue by checking whether any of these values
> change, and if so perform the necessary re-allocations.
> 
> Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
> v2: Added the line to free the long term buff in reset rx pools which
> caused me to hit a couple of other problems. On a failover, the number
> of queues can also change which doesn't get updated in the current
> reset code. Added some extra logic in do reset to check for changed
> number of queues and added some logic to release pools to ensure that
> it is only releasing pools that were allocated in the init pools
> routines.
> ---
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 461014b7ccdd..12559c63c226 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -411,6 +411,10 @@ static int reset_rx_pools(struct ibmvnic_adapter 
> *adapter)
>   struct ibmvnic_rx_pool *rx_pool;
>   int rx_scrqs;
>   int i, j, rc;
> + u64 *size_array;
> +
> + size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
> + be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
> 
>   rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
>   for (i = 0; i < rx_scrqs; i++) {
> @@ -418,7 +422,17 @@ static int reset_rx_pools(struct ibmvnic_adapter 
> *adapter)
> 
>   netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
> 
> - rc = reset_long_term_buff(adapter, _pool->long_term_buff);
> + if (rx_pool->buff_size != be64_to_cpu(size_array[i])) {
> + free_long_term_buff(adapter, _pool->long_term_buff);
> + rx_pool->buff_size = be64_to_cpu(size_array[i]);
> + alloc_long_term_buff(adapter, _pool->long_term_buff,
> +  rx_pool->size *
> +  rx_pool->buff_size);
> + } else {
> + rc = reset_long_term_buff(adapter,
> +   _pool->long_term_buff);
> + }
> +
>   if (rc)
>   return rc;
> 
> @@ -440,14 +454,12 @@ static int reset_rx_pools(struct ibmvnic_adapter 
> *adapter)
>  static void release_rx_pools(struct ibmvnic_adapter *adapter)
>  {
>   struct ibmvnic_rx_pool *rx_pool;
> - int rx_scrqs;
>   int i, j;
> 
>   if (!adapter->rx_pool)
>   return;
> 
> - rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
> - for (i = 0; i < rx_scrqs; i++) {
> + for (i = 0; i < adapter->num_active_rx_pools; i++) {
>   rx_pool = >rx_pool[i];
> 
>   netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
> @@ -470,6 +482,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
> *adapter)
> 
>   kfree(adapter->rx_pool);
>   adapter->rx_pool = NULL;
> + adapter->num_active_rx_pools = 0;
>  }
> 
>  static int init_rx_pools(struct net_device *netdev)
> @@ -494,6 +507,8 @@ static int init_rx_pools(struct net_device *netdev)
>   return -1;
>   }
> 
> + adapter->num_active_rx_pools = 0;
> +
>   for (i = 0; i < rxadd_subcrqs; i++) {
>   rx_pool = >rx_pool[i];
> 
> @@ -537,6 +552,8 @@ static int init_rx_pools(struct net_device *netdev)
>   rx_pool->next_free = 0;
>   }
> 
> + adapter->num_active_rx_pools = rxadd_subcrqs;
> +
>   return 0;
>  }
> 
> @@ -587,13 +604,12 @@ static void release_vpd_data(struct ibmvnic_adapter 
> *adapter)
>  static void release_tx_pools(struct ibmvnic_adapter *adapter)
>  {
>   struct ibmvnic_tx_pool *tx_pool;
> - int i, tx_scrqs;
> + int i;
> 
>   if (!adapter->tx_pool)
>   return;
> 
> - tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
> - for (i = 0; i < tx_scrqs; i++) {
> + for (i = 0; i < 

[PATCH net-next v2] ibmvnic: Don't handle RX interrupts when not up.

2018-01-10 Thread Nathan Fontenot
Initiating a kdump via the command line can cause a pending interrupt
to be handled by the ibmvnic driver when initializing the sub-CRQ
irqs during driver initialization.

NIP [d0ca34f0] ibmvnic_interrupt_rx+0x40/0xd0 [ibmvnic]
LR [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
Call Trace:
[c00047fcfde0] [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
[c00047fcfea0] [c813317c] handle_irq_event_percpu+0x3c/0x90
[c00047fcfee0] [c813323c] handle_irq_event+0x6c/0xd0
[c00047fcff10] [c81385e0] handle_fasteoi_irq+0xf0/0x250
[c00047fcff40] [c81320a0] generic_handle_irq+0x50/0x80
[c00047fcff60] [c8014984] __do_irq+0x84/0x1d0
[c00047fcff90] [c8027564] call_do_irq+0x14/0x24
[c0003c92af00] [c8014b70] do_IRQ+0xa0/0x120
[c0003c92af50] [c8002594] hardware_interrupt_common+0x114/0x180
--- interrupt: 501 at arch_local_irq_restore+0x74/0x90
LR = arch_local_irq_restore+0x74/0x90
[c0003c92b240] [c8138a20] irq_startup+0xa0/0xe0 (unreliable)
[c0003c92b260] [c87fc440] _raw_spin_unlock_irqrestore+0x40/0x70
[c0003c92b280] [c81361f4] __setup_irq+0x584/0x7a0
[c0003c92b420] [c81366a0] request_threaded_irq+0x140/0x290
[c0003c92b480] [d0ca3754] init_sub_crq_irqs+0x1d4/0x370 [ibmvnic]
[c0003c92b520] [d0ca6b50] ibmvnic_init+0x140/0x760 [ibmvnic]
[c0003c92b5c0] [d0ca7308] ibmvnic_probe+0x198/0x330 [ibmvnic]
[c0003c92b650] [c8037270] vio_bus_probe+0x1c0/0x480
[c0003c92b6f0] [c859a140] driver_probe_device+0x1f0/0x540
[c0003c92b780] [c859a59c] __driver_attach+0x10c/0x110
[c0003c92b7c0] [c8596dac] bus_for_each_dev+0x8c/0xf0
[c0003c92b810] [c8599798] driver_attach+0x38/0x50
[c0003c92b830] [c8598f68] bus_add_driver+0x2b8/0x380
[c0003c92b8c0] [c859b660] driver_register+0xa0/0x180
[c0003c92b930] [c8035c5c] __vio_register_driver+0x7c/0xc0
[c0003c92b9b0] [d0caaf3c] ibmvnic_module_init+0x5c/0x70 [ibmvnic]
[c0003c92ba10] [c800b6cc] do_one_initcall+0x12c/0x280
[c0003c92bae0] [c8805614] do_init_module+0x98/0x24c
[c0003c92bb70] [c8181a80] load_module+0x1470/0x16c0
[c0003c92bd40] [c8181fb0] SyS_finit_module+0xd0/0x120
[c0003c92be30] [c8009204] system_call+0x38/0xb4

At this point the driver is not prepared to handle traffic and
should not try to handle the interrupt. This patch adds a check to
ensure the driver is up when handling RX interrupts.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

v2 updates:
 - Correct commit message typos
 - Add comment and unlikely() to adapter status check

---
 drivers/net/ethernet/ibm/ibmvnic.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 6911b7cc06c5..461014b7ccdd 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2453,6 +2453,12 @@ static irqreturn_t ibmvnic_interrupt_rx(int irq, void 
*instance)
struct ibmvnic_sub_crq_queue *scrq = instance;
struct ibmvnic_adapter *adapter = scrq->adapter;
 
+   /* When booting a kdump kernel we can hit pending interrupts
+* prior to completing driver initialization.
+*/
+   if (unlikely(adapter->state != VNIC_OPEN))
+   return IRQ_NONE;
+
adapter->rx_stats_buffers[scrq->scrq_num].interrupts++;
 
if (napi_schedule_prep(>napi[scrq->scrq_num])) {



Re: [PATCH net-next] ibmvnic: Don't handle RX interrupts when not up.

2018-01-10 Thread Nathan Fontenot
On 01/09/2018 02:33 PM, Thomas Falcon wrote:
> On 01/08/2018 10:09 AM, Nathan Fontenot wrote:
>> Initiating a kdump via the command line can cause a pending interrupt
>> to be handled by the ibmvnic driver when initializing the sub-CRQ
>> irqs during driver initialization.
>>
>> NIP [d0ca34f0] ibmvnic_interrupt_rx+0x40/0xd0 [ibmvnic]
>> LR [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
>> Call Trace:
>> [c00047fcfde0] [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
>> [c00047fcfea0] [c813317c] handle_irq_event_percpu+0x3c/0x90
>> [c00047fcfee0] [c813323c] handle_irq_event+0x6c/0xd0
>> [c00047fcff10] [c81385e0] handle_fasteoi_irq+0xf0/0x250
>> [c00047fcff40] [c81320a0] generic_handle_irq+0x50/0x80
>> [c00047fcff60] [c8014984] __do_irq+0x84/0x1d0
>> [c00047fcff90] [c8027564] call_do_irq+0x14/0x24
>> [c0003c92af00] [c8014b70] do_IRQ+0xa0/0x120
>> [c0003c92af50] [c8002594] hardware_interrupt_common+0x114/0x180
>> --- interrupt: 501 at arch_local_irq_restore+0x74/0x90
>> LR = arch_local_irq_restore+0x74/0x90
>> [c0003c92b240] [c8138a20] irq_startup+0xa0/0xe0 (unreliable)
>> [c0003c92b260] [c87fc440] _raw_spin_unlock_irqrestore+0x40/0x70
>> [c0003c92b280] [c81361f4] __setup_irq+0x584/0x7a0
>> [c0003c92b420] [c81366a0] request_threaded_irq+0x140/0x290
>> [c0003c92b480] [d0ca3754] init_sub_crq_irqs+0x1d4/0x370 [ibmvnic]
>> [c0003c92b520] [d0ca6b50] ibmvnic_init+0x140/0x760 [ibmvnic]
>> [c0003c92b5c0] [d0ca7308] ibmvnic_probe+0x198/0x330 [ibmvnic]
>> [c0003c92b650] [c8037270] vio_bus_probe+0x1c0/0x480
>> [c0003c92b6f0] [c859a140] driver_probe_device+0x1f0/0x540
>> [c0003c92b780] [c859a59c] __driver_attach+0x10c/0x110
>> [c0003c92b7c0] [c8596dac] bus_for_each_dev+0x8c/0xf0
>> [c0003c92b810] [c8599798] driver_attach+0x38/0x50
>> [c0003c92b830] [c8598f68] bus_add_driver+0x2b8/0x380
>> [c0003c92b8c0] [c859b660] driver_register+0xa0/0x180
>> [c0003c92b930] [c8035c5c] __vio_register_driver+0x7c/0xc0
>> [c0003c92b9b0] [d0caaf3c] ibmvnic_module_init+0x5c/0x70 [ibmvnic]
>> [c0003c92ba10] [c800b6cc] do_one_initcall+0x12c/0x280
>> [c0003c92bae0] [c8805614] do_init_module+0x98/0x24c
>> [c0003c92bb70] [c8181a80] load_module+0x1470/0x16c0
>> [c0003c92bd40] [c8181fb0] SyS_finit_module+0xd0/0x120
>> [c0003c92be30] [c8009204] system_call+0x38/0xb4
>>
>> At this poibnt the driver is not prepared to handle traffic and
>> should not try to handle the interrupt. This patch adds a check to
>> ensure the driver is up when handling RX interrupots.
>>
>> Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
>> ---
> 
> Minor comments:
> 
> There is a typo in the commit message.

Oops! Will fix in next version.

> 
>>  drivers/net/ethernet/ibm/ibmvnic.c |3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
>> b/drivers/net/ethernet/ibm/ibmvnic.c
>> index 6911b7cc06c5..46990b84cb2d 100644
>> --- a/drivers/net/ethernet/ibm/ibmvnic.c
>> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
>> @@ -2453,6 +2453,9 @@ static irqreturn_t ibmvnic_interrupt_rx(int irq, void 
>> *instance)
>>  struct ibmvnic_sub_crq_queue *scrq = instance;
>>  struct ibmvnic_adapter *adapter = scrq->adapter;
>>
>> +if (adapter->state != VNIC_OPEN)
>> +return IRQ_NONE;
>> +
> 
> Could you include a comment that this is a kdump specific check, since in any 
> other case interrupts should be disabled if the device is closed?  Maybe you 
> could use unlikely() here too.

Yes, I can add this update to the next version.

-Nathan

> 
> Thanks,
> Tom
> 
>>  adapter->rx_stats_buffers[scrq->scrq_num].interrupts++;
>>
>>  if (napi_schedule_prep(>napi[scrq->scrq_num])) {
>>
> 



[PATCH net-next] ibmvnic: Don't handle RX interrupts when not up.

2018-01-08 Thread Nathan Fontenot
Initiating a kdump via the command line can cause a pending interrupt
to be handled by the ibmvnic driver when initializing the sub-CRQ
irqs during driver initialization.

NIP [d0ca34f0] ibmvnic_interrupt_rx+0x40/0xd0 [ibmvnic]
LR [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
Call Trace:
[c00047fcfde0] [c8132ef0] __handle_irq_event_percpu+0xa0/0x2f0
[c00047fcfea0] [c813317c] handle_irq_event_percpu+0x3c/0x90
[c00047fcfee0] [c813323c] handle_irq_event+0x6c/0xd0
[c00047fcff10] [c81385e0] handle_fasteoi_irq+0xf0/0x250
[c00047fcff40] [c81320a0] generic_handle_irq+0x50/0x80
[c00047fcff60] [c8014984] __do_irq+0x84/0x1d0
[c00047fcff90] [c8027564] call_do_irq+0x14/0x24
[c0003c92af00] [c8014b70] do_IRQ+0xa0/0x120
[c0003c92af50] [c8002594] hardware_interrupt_common+0x114/0x180
--- interrupt: 501 at arch_local_irq_restore+0x74/0x90
LR = arch_local_irq_restore+0x74/0x90
[c0003c92b240] [c8138a20] irq_startup+0xa0/0xe0 (unreliable)
[c0003c92b260] [c87fc440] _raw_spin_unlock_irqrestore+0x40/0x70
[c0003c92b280] [c81361f4] __setup_irq+0x584/0x7a0
[c0003c92b420] [c81366a0] request_threaded_irq+0x140/0x290
[c0003c92b480] [d0ca3754] init_sub_crq_irqs+0x1d4/0x370 [ibmvnic]
[c0003c92b520] [d0ca6b50] ibmvnic_init+0x140/0x760 [ibmvnic]
[c0003c92b5c0] [d0ca7308] ibmvnic_probe+0x198/0x330 [ibmvnic]
[c0003c92b650] [c8037270] vio_bus_probe+0x1c0/0x480
[c0003c92b6f0] [c859a140] driver_probe_device+0x1f0/0x540
[c0003c92b780] [c859a59c] __driver_attach+0x10c/0x110
[c0003c92b7c0] [c8596dac] bus_for_each_dev+0x8c/0xf0
[c0003c92b810] [c8599798] driver_attach+0x38/0x50
[c0003c92b830] [c8598f68] bus_add_driver+0x2b8/0x380
[c0003c92b8c0] [c859b660] driver_register+0xa0/0x180
[c0003c92b930] [c8035c5c] __vio_register_driver+0x7c/0xc0
[c0003c92b9b0] [d0caaf3c] ibmvnic_module_init+0x5c/0x70 [ibmvnic]
[c0003c92ba10] [c800b6cc] do_one_initcall+0x12c/0x280
[c0003c92bae0] [c8805614] do_init_module+0x98/0x24c
[c0003c92bb70] [c8181a80] load_module+0x1470/0x16c0
[c0003c92bd40] [c8181fb0] SyS_finit_module+0xd0/0x120
[c0003c92be30] [c8009204] system_call+0x38/0xb4

At this poibnt the driver is not prepared to handle traffic and
should not try to handle the interrupt. This patch adds a check to
ensure the driver is up when handling RX interrupots.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 6911b7cc06c5..46990b84cb2d 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2453,6 +2453,9 @@ static irqreturn_t ibmvnic_interrupt_rx(int irq, void 
*instance)
struct ibmvnic_sub_crq_queue *scrq = instance;
struct ibmvnic_adapter *adapter = scrq->adapter;
 
+   if (adapter->state != VNIC_OPEN)
+   return IRQ_NONE;
+
adapter->rx_stats_buffers[scrq->scrq_num].interrupts++;
 
if (napi_schedule_prep(>napi[scrq->scrq_num])) {



Re: [PATCH] [net-next,v3] ibmvnic: Feature implementation of Vital Product Data (VPD) for the ibmvnic driver

2017-11-13 Thread Nathan Fontenot
On 11/10/2017 01:13 PM, Desnes Augusto Nunes do Rosário wrote:
> 
> 
> On 11/10/2017 12:54 PM, Nathan Fontenot wrote:
>> On 11/10/2017 08:41 AM, Desnes Augusto Nunes do Rosário wrote:
>>>
>>>
>>> On 11/09/2017 06:31 PM, Nathan Fontenot wrote:
>>>> On 11/09/2017 01:00 PM, Desnes Augusto Nunes do Rosario wrote:
>>>>> This patch implements and enables VDP support for the ibmvnic driver.
>>>>> Moreover, it includes the implementation of suitable structs, signal
>>>>>    transmission/handling and functions which allows the retrival of 
>>>>> firmware
>>>>>    information from the ibmvnic card through the ethtool command.
>>>>>
>>>>> Signed-off-by: Desnes A. Nunes do Rosario <desn...@linux.vnet.ibm.com>
>>>>> Signed-off-by: Thomas Falcon <tlfal...@linux.vnet.ibm.com>
>>>>> ---
>>>>>    drivers/net/ethernet/ibm/ibmvnic.c | 149 
>>>>> -
>>>>>    drivers/net/ethernet/ibm/ibmvnic.h |  27 ++-
>>>>>    2 files changed, 173 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
>>>>> b/drivers/net/ethernet/ibm/ibmvnic.c
>>>>> index d0cff28..693b502 100644
>>>>> --- a/drivers/net/ethernet/ibm/ibmvnic.c
>>>>> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
>>>>> @@ -573,6 +573,15 @@ static int reset_tx_pools(struct ibmvnic_adapter 
>>>>> *adapter)
>>>>>    return 0;
>>>>>    }
>>>>>
>>>>> +static void release_vpd_data(struct ibmvnic_adapter *adapter)
>>>>> +{
>>>>> +    if (!adapter->vpd)
>>>>> +    return;
>>>>> +
>>>>> +    kfree(adapter->vpd->buff);
>>>>> +    kfree(adapter->vpd);
>>>>> +}
>>>>> +
>>>>>    static void release_tx_pools(struct ibmvnic_adapter *adapter)
>>>>>    {
>>>>>    struct ibmvnic_tx_pool *tx_pool;
>>>>> @@ -753,6 +762,8 @@ static void release_resources(struct ibmvnic_adapter 
>>>>> *adapter)
>>>>>    {
>>>>>    int i;
>>>>>
>>>>> +    release_vpd_data(adapter);
>>>>> +
>>>>>    release_tx_pools(adapter);
>>>>>    release_rx_pools(adapter);
>>>>>
>>>>> @@ -833,6 +844,53 @@ static int set_real_num_queues(struct net_device 
>>>>> *netdev)
>>>>>    return rc;
>>>>>    }
>>>>>
>>>>> +static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
>>>>> +{
>>>>> +    struct device *dev = >vdev->dev;
>>>>> +    union ibmvnic_crq crq;
>>>>> +    dma_addr_t dma_addr;
>>>>> +    int len;
>>>>> +
>>>>> +    if (adapter->vpd->buff)
>>>>> +    len = adapter->vpd->len;
>>>>> +
>>>>> +    reinit_completion(>fw_done);
>>>>> +    crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
>>>>> +    crq.get_vpd_size.cmd = GET_VPD_SIZE;
>>>>> +    ibmvnic_send_crq(adapter, );
>>>>> +    wait_for_completion(>fw_done);
>>>>> +
>>>>
>>>> Shouldn't there be a check for the return code when getting the
>>>> vpd size?
>>>
>>> Hello Nathan,
>>>
>>> This check is already being performed on the handle_vpd_size_rsp() function 
>>> down below.
>>>
>>> In short, a GET_VPD_SIZE signal is sent here through a ibmvnic_crq union in 
>>> ibmvnic_send_crq(), whereas handle_query_ip_offload_rsp() receives from the 
>>> VNIC adapter a GET_VPD_SIZE_RSP containing a ibmvnic_crq union with the vpd 
>>> size information and the rc.code. If successful, a >fw_done is 
>>> sent and this part of the code continues; however if not, a dev_error() is 
>>> thrown. Same logic applies to GET_VPD/GET_VPD_RSP.
>>>
>>
>> Yes, I did see that code. You do a complet of the completion variable for 
>> both success and failure,
>> this then lets this routine continue irregardless of the results of the get 
>> vpd size request. The
>> call to dev_err will print the error message but does not prevent use from 
>> bailing if the
>> get vpd size fails. Perhaps setting vpd->len to -1 to indi

Re: [PATCH] [net-next,v3] ibmvnic: Feature implementation of Vital Product Data (VPD) for the ibmvnic driver

2017-11-10 Thread Nathan Fontenot
On 11/10/2017 08:41 AM, Desnes Augusto Nunes do Rosário wrote:
> 
> 
> On 11/09/2017 06:31 PM, Nathan Fontenot wrote:
>> On 11/09/2017 01:00 PM, Desnes Augusto Nunes do Rosario wrote:
>>> This patch implements and enables VDP support for the ibmvnic driver.
>>> Moreover, it includes the implementation of suitable structs, signal
>>>   transmission/handling and functions which allows the retrival of firmware
>>>   information from the ibmvnic card through the ethtool command.
>>>
>>> Signed-off-by: Desnes A. Nunes do Rosario <desn...@linux.vnet.ibm.com>
>>> Signed-off-by: Thomas Falcon <tlfal...@linux.vnet.ibm.com>
>>> ---
>>>   drivers/net/ethernet/ibm/ibmvnic.c | 149 
>>> -
>>>   drivers/net/ethernet/ibm/ibmvnic.h |  27 ++-
>>>   2 files changed, 173 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
>>> b/drivers/net/ethernet/ibm/ibmvnic.c
>>> index d0cff28..693b502 100644
>>> --- a/drivers/net/ethernet/ibm/ibmvnic.c
>>> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
>>> @@ -573,6 +573,15 @@ static int reset_tx_pools(struct ibmvnic_adapter 
>>> *adapter)
>>>   return 0;
>>>   }
>>>
>>> +static void release_vpd_data(struct ibmvnic_adapter *adapter)
>>> +{
>>> +    if (!adapter->vpd)
>>> +    return;
>>> +
>>> +    kfree(adapter->vpd->buff);
>>> +    kfree(adapter->vpd);
>>> +}
>>> +
>>>   static void release_tx_pools(struct ibmvnic_adapter *adapter)
>>>   {
>>>   struct ibmvnic_tx_pool *tx_pool;
>>> @@ -753,6 +762,8 @@ static void release_resources(struct ibmvnic_adapter 
>>> *adapter)
>>>   {
>>>   int i;
>>>
>>> +    release_vpd_data(adapter);
>>> +
>>>   release_tx_pools(adapter);
>>>   release_rx_pools(adapter);
>>>
>>> @@ -833,6 +844,53 @@ static int set_real_num_queues(struct net_device 
>>> *netdev)
>>>   return rc;
>>>   }
>>>
>>> +static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
>>> +{
>>> +    struct device *dev = >vdev->dev;
>>> +    union ibmvnic_crq crq;
>>> +    dma_addr_t dma_addr;
>>> +    int len;
>>> +
>>> +    if (adapter->vpd->buff)
>>> +    len = adapter->vpd->len;
>>> +
>>> +    reinit_completion(>fw_done);
>>> +    crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
>>> +    crq.get_vpd_size.cmd = GET_VPD_SIZE;
>>> +    ibmvnic_send_crq(adapter, );
>>> +    wait_for_completion(>fw_done);
>>> +
>>
>> Shouldn't there be a check for the return code when getting the
>> vpd size?
> 
> Hello Nathan,
> 
> This check is already being performed on the handle_vpd_size_rsp() function 
> down below.
> 
> In short, a GET_VPD_SIZE signal is sent here through a ibmvnic_crq union in 
> ibmvnic_send_crq(), whereas handle_query_ip_offload_rsp() receives from the 
> VNIC adapter a GET_VPD_SIZE_RSP containing a ibmvnic_crq union with the vpd 
> size information and the rc.code. If successful, a >fw_done is sent 
> and this part of the code continues; however if not, a dev_error() is thrown. 
> Same logic applies to GET_VPD/GET_VPD_RSP.
> 

Yes, I did see that code. You do a complet of the completion variable for both 
success and failure,
this then lets this routine continue irregardless of the results of the get vpd 
size request. The
call to dev_err will print the error message but does not prevent use from 
bailing if the
get vpd size fails. Perhaps setting vpd->len to -1 to indicate the get vpd call 
failed which could
then be checked by the requester.

-Nathan


> What I am adding on the next version of the patch is a check if 
> adapter->vpd->len is different than 0 before allocating adapter->vpd->buff, 
> since that in a case of a failure, adapter->vpd->len will be 0.
> 
> Best Regards,
> 
>>
>>
>>> +    if (!adapter->vpd->buff)
>>> +    adapter->vpd->buff = kzalloc(adapter->vpd->len, GFP_KERNEL);
>>> +    else if (adapter->vpd->len != len)
>>> +    adapter->vpd->buff =
>>> +    krealloc(adapter->vpd->buff,
>>> + adapter->vpd->len, GFP_KERNEL);
>>> +
>>> +    if (!adapter->vpd->buff) {
>>> +    dev_err(dev, "Could allocate VPD buffer\n");
>>> + 

Re: [PATCH] [net-next,v3] ibmvnic: Feature implementation of Vital Product Data (VPD) for the ibmvnic driver

2017-11-09 Thread Nathan Fontenot
On 11/09/2017 01:00 PM, Desnes Augusto Nunes do Rosario wrote:
> This patch implements and enables VDP support for the ibmvnic driver.
> Moreover, it includes the implementation of suitable structs, signal
>  transmission/handling and functions which allows the retrival of firmware
>  information from the ibmvnic card through the ethtool command.
> 
> Signed-off-by: Desnes A. Nunes do Rosario 
> Signed-off-by: Thomas Falcon 
> ---
>  drivers/net/ethernet/ibm/ibmvnic.c | 149 
> -
>  drivers/net/ethernet/ibm/ibmvnic.h |  27 ++-
>  2 files changed, 173 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index d0cff28..693b502 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -573,6 +573,15 @@ static int reset_tx_pools(struct ibmvnic_adapter 
> *adapter)
>   return 0;
>  }
> 
> +static void release_vpd_data(struct ibmvnic_adapter *adapter)
> +{
> + if (!adapter->vpd)
> + return;
> +
> + kfree(adapter->vpd->buff);
> + kfree(adapter->vpd);
> +}
> +
>  static void release_tx_pools(struct ibmvnic_adapter *adapter)
>  {
>   struct ibmvnic_tx_pool *tx_pool;
> @@ -753,6 +762,8 @@ static void release_resources(struct ibmvnic_adapter 
> *adapter)
>  {
>   int i;
> 
> + release_vpd_data(adapter);
> +
>   release_tx_pools(adapter);
>   release_rx_pools(adapter);
> 
> @@ -833,6 +844,53 @@ static int set_real_num_queues(struct net_device *netdev)
>   return rc;
>  }
> 
> +static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
> +{
> + struct device *dev = >vdev->dev;
> + union ibmvnic_crq crq;
> + dma_addr_t dma_addr;
> + int len;
> +
> + if (adapter->vpd->buff)
> + len = adapter->vpd->len;
> +
> + reinit_completion(>fw_done);
> + crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
> + crq.get_vpd_size.cmd = GET_VPD_SIZE;
> + ibmvnic_send_crq(adapter, );
> + wait_for_completion(>fw_done);
> +

Shouldn't there be a check for the return code when getting the
vpd size?


> + if (!adapter->vpd->buff)
> + adapter->vpd->buff = kzalloc(adapter->vpd->len, GFP_KERNEL);
> + else if (adapter->vpd->len != len)
> + adapter->vpd->buff =
> + krealloc(adapter->vpd->buff,
> +  adapter->vpd->len, GFP_KERNEL);
> +
> + if (!adapter->vpd->buff) {
> + dev_err(dev, "Could allocate VPD buffer\n");
> + return -ENOMEM;
> + }
> +
> + adapter->vpd->dma_addr =
> + dma_map_single(dev, adapter->vpd->buff, adapter->vpd->len,
> +DMA_FROM_DEVICE);
> + if (dma_mapping_error(dev, dma_addr)) {
> + dev_err(dev, "Could not map VPD buffer\n");
> + return -ENOMEM;
> + }
> +
> + reinit_completion(>fw_done);
> + crq.get_vpd.first = IBMVNIC_CRQ_CMD;
> + crq.get_vpd.cmd = GET_VPD;
> + crq.get_vpd.ioba = cpu_to_be32(adapter->vpd->dma_addr);
> + crq.get_vpd.len = cpu_to_be32((u32)adapter->vpd->len);
> + ibmvnic_send_crq(adapter, );
> + wait_for_completion(>fw_done);
> +
> + return 0;
> +}
> +
>  static int init_resources(struct ibmvnic_adapter *adapter)
>  {
>   struct net_device *netdev = adapter->netdev;
> @@ -850,6 +908,10 @@ static int init_resources(struct ibmvnic_adapter 
> *adapter)
>   if (rc)
>   return rc;
> 
> + adapter->vpd = kzalloc(sizeof(*adapter->vpd), GFP_KERNEL);
> + if (!adapter->vpd)
> + return -ENOMEM;
> +
>   adapter->map_id = 1;
>   adapter->napi = kcalloc(adapter->req_rx_queues,
>   sizeof(struct napi_struct), GFP_KERNEL);
> @@ -950,6 +1012,10 @@ static int ibmvnic_open(struct net_device *netdev)
> 
>   rc = __ibmvnic_open(netdev);
>   netif_carrier_on(netdev);
> +
> + /* Vital Product Data (VPD) */
> + ibmvnic_get_vpd(adapter);
> +
>   mutex_unlock(>reset_lock);
> 
>   return rc;
> @@ -1878,11 +1944,15 @@ static int ibmvnic_get_link_ksettings(struct 
> net_device *netdev,
>   return 0;
>  }
> 
> -static void ibmvnic_get_drvinfo(struct net_device *dev,
> +static void ibmvnic_get_drvinfo(struct net_device *netdev,
>   struct ethtool_drvinfo *info)
>  {
> + struct ibmvnic_adapter *adapter = netdev_priv(netdev);
> +
>   strlcpy(info->driver, ibmvnic_driver_name, sizeof(info->driver));
>   strlcpy(info->version, IBMVNIC_DRIVER_VERSION, sizeof(info->version));
> + strlcpy(info->fw_version, adapter->fw_version,
> + sizeof(info->fw_version));
>  }
> 
>  static u32 ibmvnic_get_msglevel(struct net_device *netdev)
> @@ -3076,6 +3146,77 @@ static void send_cap_queries(struct ibmvnic_adapter 
> *adapter)
>   ibmvnic_send_crq(adapter, );
>  }
> 
> +static void 

[PATCH net-next] ibmvnic: Add vnic client data to login buffer

2017-11-08 Thread Nathan Fontenot
Update the login buffer to include client data for the vnic driver,
this includes the OS name, LPAR name, and device name. This update
alolows thius information to be available in the VIOS.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   68 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |2 +
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index d0cff2807d0b..b918bc2f2e4f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -75,6 +75,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ibmvnic.h"
 
@@ -2813,6 +2814,55 @@ static int send_version_xchg(struct ibmvnic_adapter 
*adapter)
return ibmvnic_send_crq(adapter, );
 }
 
+struct vnic_login_client_data {
+   u8  type;
+   __be16  len;
+   charname;
+} __packed;
+
+static int vnic_client_data_len(struct ibmvnic_adapter *adapter)
+{
+   int len;
+
+   /* Calculate the amount of buffer space needed for the
+* vnic client data in the login buffer. There are four entries,
+* OS name, LPAR name, device name, and a null last entry.
+*/
+   len = 4 * sizeof(struct vnic_login_client_data);
+   len += 6; /* "Linux" plus NULL */
+   len += strlen(utsname()->nodename) + 1;
+   len += strlen(adapter->netdev->name) + 1;
+
+   return len;
+}
+
+static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
+struct vnic_login_client_data *vlcd)
+{
+   const char *os_name = "Linux";
+   int len;
+
+   /* Type 1 - LPAR OS */
+   vlcd->type = 1;
+   len = strlen(os_name) + 1;
+   vlcd->len = cpu_to_be16(len);
+   strncpy(>name, os_name, len);
+   vlcd = (struct vnic_login_client_data *)((char *)>name + len);
+
+   /* Type 2 - LPAR name */
+   vlcd->type = 2;
+   len = strlen(utsname()->nodename) + 1;
+   vlcd->len = cpu_to_be16(len);
+   strncpy(>name, utsname()->nodename, len);
+   vlcd = (struct vnic_login_client_data *)((char *)>name + len);
+
+   /* Type 3 - device name */
+   vlcd->type = 3;
+   len = strlen(adapter->netdev->name) + 1;
+   vlcd->len = cpu_to_be16(len);
+   strncpy(>name, adapter->netdev->name, len);
+}
+
 static void send_login(struct ibmvnic_adapter *adapter)
 {
struct ibmvnic_login_rsp_buffer *login_rsp_buffer;
@@ -2825,13 +2875,18 @@ static void send_login(struct ibmvnic_adapter *adapter)
size_t buffer_size;
__be64 *tx_list_p;
__be64 *rx_list_p;
+   int client_data_len;
+   struct vnic_login_client_data *vlcd;
int i;
 
+   client_data_len = vnic_client_data_len(adapter);
+
buffer_size =
sizeof(struct ibmvnic_login_buffer) +
-   sizeof(u64) * (adapter->req_tx_queues + adapter->req_rx_queues);
+   sizeof(u64) * (adapter->req_tx_queues + adapter->req_rx_queues) +
+   client_data_len;
 
-   login_buffer = kmalloc(buffer_size, GFP_ATOMIC);
+   login_buffer = kzalloc(buffer_size, GFP_ATOMIC);
if (!login_buffer)
goto buf_alloc_failed;
 
@@ -2898,6 +2953,15 @@ static void send_login(struct ibmvnic_adapter *adapter)
}
}
 
+   /* Insert vNIC login client data */
+   vlcd = (struct vnic_login_client_data *)
+   ((char *)rx_list_p + (sizeof(u64) * adapter->req_rx_queues));
+   login_buffer->client_data_offset =
+   cpu_to_be32((char *)vlcd - (char *)login_buffer);
+   login_buffer->client_data_len = cpu_to_be32(client_data_len);
+
+   vnic_add_client_data(adapter, vlcd);
+
netdev_dbg(adapter->netdev, "Login Buffer:\n");
for (i = 0; i < (adapter->login_buf_sz - 1) / 8 + 1; i++) {
netdev_dbg(adapter->netdev, "%016lx\n",
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index 4670af80d612..8ed829c5b026 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -57,6 +57,8 @@ struct ibmvnic_login_buffer {
__be32 off_rxcomp_subcrqs;
__be32 login_rsp_ioba;
__be32 login_rsp_len;
+   __be32 client_data_offset;
+   __be32 client_data_len;
 } __packed __aligned(8);
 
 struct ibmvnic_login_rsp_buffer {



Re: [PATCH v2 net-next 1/2] ibmvnic: Update reset infrastructure to support tunable parameters

2017-10-24 Thread Nathan Fontenot
On 10/23/2017 11:33 AM, John Allen wrote:
> Update ibmvnic reset infrastructure to include a new reset option that will
> allow changing of tunable parameters. There currently is no way to request
> different capabilities from the vnic server on the fly so this patch
> achieves this by resetting the driver and attempting to log in with the
> requested changes. If the reset operation fails, the old values of the
> tunable parameters are stored in the "fallback" struct and we attempt to
> login with the fallback values.
> 
> Signed-off-by: John Allen 
> ---
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 11eba82..c2c4a5b 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -115,6 +115,7 @@ static union sub_crq *ibmvnic_next_scrq(struct 
> ibmvnic_adapter *,
>  static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter);
>  static int ibmvnic_init(struct ibmvnic_adapter *);
>  static void release_crq_queue(struct ibmvnic_adapter *);
> +static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p);
> 
>  struct ibmvnic_stat {
>   char name[ETH_GSTRING_LEN];
> @@ -926,6 +927,11 @@ static int ibmvnic_open(struct net_device *netdev)
> 
>   mutex_lock(>reset_lock);
> 
> + if (adapter->desired->mac) {
> + __ibmvnic_set_mac(netdev, adapter->desired->mac);
> + adapter->desired->mac = NULL;

Not sure if I missed it, but setting this to NULL doesn't seem right.

This is allocated in ibmvnic_probe() but only gets any data in ibmvnic_set_mac()
if the adapter state is closed. I think the scenario of probe -> set mac addr ->
open -> close -> set mac addr,  would fail in the second set mac address because
the mac struct pointer is NULL.

> + }
> +
>   if (adapter->state != VNIC_CLOSED) {
>   rc = ibmvnic_login(netdev);
>   if (rc) {
> @@ -1426,7 +1432,7 @@ static void ibmvnic_set_multi(struct net_device *netdev)
>   }
>  }
> 
> -static int ibmvnic_set_mac(struct net_device *netdev, void *p)
> +static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p)
>  {
>   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
>   struct sockaddr *addr = p;
> @@ -1444,6 +1450,21 @@ static int ibmvnic_set_mac(struct net_device *netdev, 
> void *p)
>   return 0;
>  }
> 
> +static int ibmvnic_set_mac(struct net_device *netdev, void *p)
> +{
> + struct ibmvnic_adapter *adapter = netdev_priv(netdev);
> + struct sockaddr *addr = p;
> +
> + if (adapter->state != VNIC_OPEN) {
> + memcpy(adapter->desired->mac, addr, sizeof(struct sockaddr));
> + return 0;
> + }
> +
> + __ibmvnic_set_mac(netdev, addr);
> +
> + return 0;
> +}
> +
>  /**
>   * do_reset returns zero if we are able to keep processing reset events, or
>   * non-zero if we hit a fatal error and must halt.
> @@ -1470,6 +1491,13 @@ static int do_reset(struct ibmvnic_adapter *adapter,
>   if (rc)
>   return rc;
> 
> + if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
> + adapter->wait_for_reset) {
> + release_resources(adapter);
> + release_sub_crqs(adapter);
> + release_crq_queue(adapter);
> + }
> +
>   if (adapter->reset_reason != VNIC_RESET_NON_FATAL) {
>   /* remove the closed state so when we call open it appears
>* we are coming from the probed state.
> @@ -1492,16 +1520,23 @@ static int do_reset(struct ibmvnic_adapter *adapter,
>   return 0;
>   }
> 
> - rc = reset_tx_pools(adapter);
> - if (rc)
> - return rc;
> + if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
> + adapter->wait_for_reset) {
> + rc = init_resources(adapter);
> + if (rc)
> + return rc;
> + } else {
> + rc = reset_tx_pools(adapter);
> + if (rc)
> + return rc;
> 
> - rc = reset_rx_pools(adapter);
> - if (rc)
> - return rc;
> + rc = reset_rx_pools(adapter);
> + if (rc)
> + return rc;
> 
> - if (reset_state == VNIC_CLOSED)
> - return 0;
> + if (reset_state == VNIC_CLOSED)
> + return 0;
> + }
>   }
> 
>   rc = __ibmvnic_open(netdev);
> @@ -1580,6 +1615,12 @@ static void __ibmvnic_reset(struct work_struct *work)
>   rwi = get_next_rwi(adapter);
>   }
> 
> + if (adapter->wait_for_reset) {
> + adapter->wait_for_reset = false;
> + adapter->reset_done_rc = rc;
> + complete(>reset_done);
> + }
> +
>   if (rc) {
>   

Re: [PATCH net-next] ibmvnic: Add netdev_dbg output for debugging

2017-08-08 Thread Nathan Fontenot
On 08/08/2017 11:27 AM, Stephen Hemminger wrote:
> On Mon, 07 Aug 2017 15:02:58 -0400
> Nathan Fontenot <nf...@linux.vnet.ibm.com> wrote:
> 
>> To ease debugging of the ibmvnic driver add a series of netdev_dbg()
>> statements to track driver status, especially during initialization,
>> removal, and resetting of the driver.
>>
>> Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> 
> Maybe use netif_dbg() and the message type stuff.

Oh! I like this even more. This just begs to update all of the message
reporting in the driver though.

Let's scrap this patch. I'll work on a new patchset based on using
the netif_*() infrastructure.

-Nathan

 



[PATCH net-next] ibmvnic: Correct 'unused variable' warning in build.

2017-08-08 Thread Nathan Fontenot
Commit a248878d7a1d ("ibmvnic: Check for transport event on driver resume")
removed the loop to kick irqs on driver resume but didn't remove the now
unused loop variable 'i'.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index d267aa8..e3c422b 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3995,7 +3995,6 @@ static int ibmvnic_resume(struct device *dev)
 {
struct net_device *netdev = dev_get_drvdata(dev);
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-   int i;
 
if (adapter->state != VNIC_OPEN)
return 0;



[PATCH v3 net-next] ibmvnic: Add netdev_dbg output for debugging

2017-08-08 Thread Nathan Fontenot
To ease debugging of the ibmvnic driver add a series of netdev_dbg()
statements to track driver status, especially during initialization,
removal, and resetting of the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

v2: Removed several dbg statements where ftrace would already work
for tracking driver status, per Joe Perches comment.

v3: Correct misspelling in dbg message
---
 drivers/net/ethernet/ibm/ibmvnic.c |   62 
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5932160..d267aa8 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -398,6 +398,7 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
}
 
adapter->stats_token = stok;
+   netdev_dbg(adapter->netdev, "Stats token initialized (%llx)\n", stok);
return 0;
 }
 
@@ -411,6 +412,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
+
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
if (rc)
return rc;
@@ -443,6 +446,8 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
+
kfree(rx_pool->free_map);
free_long_term_buff(adapter, _pool->long_term_buff);
 
@@ -489,7 +494,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev,
-  "Initializing rx_pool %d, %lld buffs, %lld bytes 
each\n",
+  "Initializing rx_pool[%d], %lld buffs, %lld bytes 
each\n",
   i, adapter->req_rx_add_entries_per_subcrq,
   be64_to_cpu(size_array[i]));
 
@@ -539,6 +544,8 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i);
+
tx_pool = >tx_pool[i];
 
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
@@ -569,6 +576,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
free_long_term_buff(adapter, _pool->long_term_buff);
@@ -595,6 +603,11 @@ static int init_tx_pools(struct net_device *netdev)
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
+
+   netdev_dbg(adapter->netdev,
+  "Initializing tx_pool[%d], %lld buffs\n",
+  i, adapter->req_tx_entries_per_subcrq);
+
tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
   sizeof(struct ibmvnic_tx_buff),
   GFP_KERNEL);
@@ -665,8 +678,10 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
if (!adapter->napi_enabled)
return;
 
-   for (i = 0; i < adapter->req_rx_queues; i++)
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Disabling napi[%d]\n", i);
napi_disable(>napi[i]);
+   }
 
adapter->napi_enabled = false;
 }
@@ -716,8 +731,11 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
 
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i])
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
netif_napi_del(>napi[i]);
+   }
}
}
 }
@@ -730,7 +748,8 @@ static int set_link_state(struct ibmvnic_adapter *adapter, 
u8 link_state)
bool resend;
int rc;
 
-   netdev_err(netdev, "setting link state %d\n", link_state);
+   netdev_dbg(netdev, "setting link state %d\n", link_stat

[PATCH v2 net-next] ibmvnic: Add netdev_dbg output for debugging

2017-08-08 Thread Nathan Fontenot
To ease debugging of the ibmvnic driver add a series of netdev_dbg()
statements to track driver status, especially during initialization,
removal, and resetting of the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

v2: Removed several dbg statements where ftrace would already work
for tracking driver status, per Joe Perches comment.
---
 drivers/net/ethernet/ibm/ibmvnic.c |   62 
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5932160..08e1cb4 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -398,6 +398,7 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
}
 
adapter->stats_token = stok;
+   netdev_dbg(adapter->netdev, "Stats token intialized (%llx)\n", stok);
return 0;
 }
 
@@ -411,6 +412,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
+
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
if (rc)
return rc;
@@ -443,6 +446,8 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
+
kfree(rx_pool->free_map);
free_long_term_buff(adapter, _pool->long_term_buff);
 
@@ -489,7 +494,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev,
-  "Initializing rx_pool %d, %lld buffs, %lld bytes 
each\n",
+  "Initializing rx_pool[%d], %lld buffs, %lld bytes 
each\n",
   i, adapter->req_rx_add_entries_per_subcrq,
   be64_to_cpu(size_array[i]));
 
@@ -539,6 +544,8 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i);
+
tx_pool = >tx_pool[i];
 
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
@@ -569,6 +576,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
free_long_term_buff(adapter, _pool->long_term_buff);
@@ -595,6 +603,11 @@ static int init_tx_pools(struct net_device *netdev)
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
+
+   netdev_dbg(adapter->netdev,
+  "Initializing tx_pool[%d], %lld buffs\n",
+  i, adapter->req_tx_entries_per_subcrq);
+
tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
   sizeof(struct ibmvnic_tx_buff),
   GFP_KERNEL);
@@ -665,8 +678,10 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
if (!adapter->napi_enabled)
return;
 
-   for (i = 0; i < adapter->req_rx_queues; i++)
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Disabling napi[%d]\n", i);
napi_disable(>napi[i]);
+   }
 
adapter->napi_enabled = false;
 }
@@ -716,8 +731,11 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
 
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i])
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
netif_napi_del(>napi[i]);
+   }
}
}
 }
@@ -730,7 +748,8 @@ static int set_link_state(struct ibmvnic_adapter *adapter, 
u8 link_state)
bool resend;
int rc;
 
-   netdev_err(netdev, "setting link state %d\n", link_state);
+   netdev_dbg(netdev, "setting link state %d\n", link_state);
+
memset(, 0, sizeof(crq))

[PATCH net-next] ibmvnic: Clean up resources on probe failure

2017-08-08 Thread Nathan Fontenot
Ensure that any resources allocated during probe are released if the
probe of the driver fails.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5932160..24f536b 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3827,31 +3827,35 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
 
do {
rc = ibmvnic_init(adapter);
-   if (rc && rc != EAGAIN) {
-   free_netdev(netdev);
-   return rc;
-   }
+   if (rc && rc != EAGAIN)
+   goto ibmvnic_init_fail;
} while (rc == EAGAIN);
 
netdev->mtu = adapter->req_mtu - ETH_HLEN;
 
rc = device_create_file(>dev, _attr_failover);
-   if (rc) {
-   free_netdev(netdev);
-   return rc;
-   }
+   if (rc)
+   goto ibmvnic_init_fail;
 
rc = register_netdev(netdev);
if (rc) {
dev_err(>dev, "failed to register netdev rc=%d\n", rc);
-   device_remove_file(>dev, _attr_failover);
-   free_netdev(netdev);
-   return rc;
+   goto ibmvnic_register_fail;
}
dev_info(>dev, "ibmvnic registered\n");
 
adapter->state = VNIC_PROBED;
return 0;
+
+ibmvnic_register_fail:
+   device_remove_file(>dev, _attr_failover);
+   
+ibmvnic_init_fail:
+   release_sub_crqs(adapter);
+   release_crq_queue(adapter);
+   free_netdev(netdev);
+
+   return rc;
 }
 
 static int ibmvnic_remove(struct vio_dev *dev)



Re: [PATCH net-next] ibmvnic: Add netdev_dbg output for debugging

2017-08-08 Thread Nathan Fontenot
On 08/07/2017 10:29 AM, Joe Perches wrote:
> On Mon, 2017-08-07 at 15:02 -0400, Nathan Fontenot wrote:
>> To ease debugging of the ibmvnic driver add a series of netdev_dbg()
>> statements to track driver status, especially during initialization,
>> removal, and resetting of the driver.
> 
> For some of the function entry logging, it seems
> better to use ftrace instead.
> 
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
>> b/drivers/net/ethernet/ibm/ibmvnic.c
> []
>> @@ -389,6 +389,8 @@ static int init_stats_token(struct ibmvnic_adapter 
>> *adapter)
>>  struct device *dev = >vdev->dev;
>>  dma_addr_t stok;
>>  
>> +netdev_dbg(adapter->netdev, "Initializing stats token\n");
> 
> here and subsequent.

Thanks for the tip. I'm not very familiar with ftrace so I'll have to
investigate and send a revised patch.

-Nathan 



[PATCH net-next] ibmvnic: Add netdev_dbg output for debugging

2017-08-07 Thread Nathan Fontenot
To ease debugging of the ibmvnic driver add a series of netdev_dbg()
statements to track driver status, especially during initialization,
removal, and resetting of the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   78 +---
 1 file changed, 72 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5932160..4dd9415 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -389,6 +389,8 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
struct device *dev = >vdev->dev;
dma_addr_t stok;
 
+   netdev_dbg(adapter->netdev, "Initializing stats token\n");
+
stok = dma_map_single(dev, >stats,
  sizeof(struct ibmvnic_statistics),
  DMA_FROM_DEVICE);
@@ -411,6 +413,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
+
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
if (rc)
return rc;
@@ -443,6 +447,8 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = >rx_pool[i];
 
+   netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
+
kfree(rx_pool->free_map);
free_long_term_buff(adapter, _pool->long_term_buff);
 
@@ -489,7 +495,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool = >rx_pool[i];
 
netdev_dbg(adapter->netdev,
-  "Initializing rx_pool %d, %lld buffs, %lld bytes 
each\n",
+  "Initializing rx_pool[%d], %lld buffs, %lld bytes 
each\n",
   i, adapter->req_rx_add_entries_per_subcrq,
   be64_to_cpu(size_array[i]));
 
@@ -539,6 +545,8 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i);
+
tx_pool = >tx_pool[i];
 
rc = reset_long_term_buff(adapter, _pool->long_term_buff);
@@ -569,6 +577,7 @@ static void release_tx_pools(struct ibmvnic_adapter 
*adapter)
 
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+   netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = >tx_pool[i];
kfree(tx_pool->tx_buff);
free_long_term_buff(adapter, _pool->long_term_buff);
@@ -595,6 +604,11 @@ static int init_tx_pools(struct net_device *netdev)
 
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = >tx_pool[i];
+
+   netdev_dbg(adapter->netdev,
+  "Initializing tx_pool[%d], %lld buffs\n",
+  i, adapter->req_tx_entries_per_subcrq);
+
tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
   sizeof(struct ibmvnic_tx_buff),
   GFP_KERNEL);
@@ -665,8 +679,10 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter 
*adapter)
if (!adapter->napi_enabled)
return;
 
-   for (i = 0; i < adapter->req_rx_queues; i++)
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   netdev_dbg(adapter->netdev, "Disabling napi[%d]\n", i);
napi_disable(>napi[i]);
+   }
 
adapter->napi_enabled = false;
 }
@@ -677,6 +693,8 @@ static int ibmvnic_login(struct net_device *netdev)
unsigned long timeout = msecs_to_jiffies(3);
struct device *dev = >vdev->dev;
 
+   netdev_dbg(netdev, "Logging into server\n");
+
do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
@@ -716,8 +734,11 @@ static void release_resources(struct ibmvnic_adapter 
*adapter)
 
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++) {
-   if (>napi[i])
+   if (>napi[i]) {
+   netdev_dbg(adapter->netdev,
+  "Releasing napi[%d]\n", i);
netif_napi_del(>napi[i]);
+  

[PATCH net-next V2] ibmvnic: Correct return code checking for ibmvnic_init during probe

2017-06-21 Thread Nathan Fontenot
The update to ibmvnic_init to allow an EAGAIN return code broke
the calling of ibmvnic_init from ibmvnic_probe. The code now
will return from this point in the probe routine if anything
other than EAGAIN is returned. The check should be to see if rc
is non-zero and not equal to EAGAIN.

Without this fix, the vNIC driver can return 0 (success) from
its probe routine due to ibmvnic_init returning zero, but before
completing the probe process and registering with the netdev layer.

Fixes: 6a2fb0e99f9c (ibmvnic: driver initialization for kdump/kexec)
Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 0135095..05edf19 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3737,7 +3737,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
 
do {
rc = ibmvnic_init(adapter);
-   if (rc != EAGAIN) {
+   if (rc && rc != EAGAIN) {
free_netdev(netdev);
return rc;
}



Re: [PATCH net-next] ibmvnic: Correct return code checking for ibmvnic_init during probe

2017-06-21 Thread Nathan Fontenot
On 06/21/2017 02:39 PM, David Miller wrote:
> From: Nathan Fontenot <nf...@linux.vnet.ibm.com>
> Date: Tue, 20 Jun 2017 17:21:54 -0400
> 
>> Fixes: 6a2fb0e99f9c (ibmvnic: driver initialization for kdump/kexec)
> 
> I'm incredibly curious where you got the idea to put the Fixes: tag
> at the beginning of the commit message.

I have no excuse. As you mentioned I should have looked at what others
had done when using the Fixes.

Would you like me to re-send with the Fixes tag corrected?

-Nathan

> 
> Have you seen anyone else submitting patches on netdev do this?
> 
> It helps to operate by example, and look at how other people do
> things.
> 
> The correct location for the Fixes: tag is at the beginning of the
> singoffs and acks at the end of the commit message.
> 
> There shall be no empty lines between the Fixes: tag and those
> signoffs and acks.
> 
> Thank you.
> 



Re: [PATCH net-next] ibmvnic: Return from ibmvnic_resume if not in VNIC_OPEN state

2017-06-20 Thread Nathan Fontenot


On 06/19/2017 11:27 AM, John Allen wrote:
> If the ibmvnic driver is not in the VNIC_OPEN state, return from
> ibmvnic_resume callback. If we are not in the VNIC_OPEN state, interrupts
> may not be initialized and directly calling the interrupt handler will
> cause a crash.
> 
> Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 722daf5..0135095 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -3859,6 +3859,9 @@ static int ibmvnic_resume(struct device *dev)
>   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
>   int i;
> 
> + if (adapter->state != VNIC_OPEN)
> + return 0;
> +
>   /* kick the interrupt handlers just in case we lost an interrupt */
>   for (i = 0; i < adapter->req_rx_queues; i++)
>   ibmvnic_interrupt_rx(adapter->rx_scrq[i]->irq,
> 



[PATCH net-next] ibmvnic: Correct return code checking for ibmvnic_init during probe

2017-06-20 Thread Nathan Fontenot
Fixes: 6a2fb0e99f9c (ibmvnic: driver initialization for kdump/kexec)

The update to ibmvnic_init to allow an EAGAIN return code broke
the calling of ibmvnic_init from ibmvnic_probe. The code now
will return from this point in the probe routine if anything
other than EAGAIN is returned. The check should be to see if rc
is non-zero and not equal to EAGAIN.

Without this fix, the vNIC driver can return 0 (success) from
its probe routine due to ibmvnic_init returning zero, but before
completing the probe process and registering with the netdev layer.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 722daf5..4e17217 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3737,7 +3737,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
 
do {
rc = ibmvnic_init(adapter);
-   if (rc != EAGAIN) {
+   if (rc && rc != EAGAIN) {
free_netdev(netdev);
return rc;
}



[PATCH] ibmvnic: driver initialization for kdump/kexec

2017-06-15 Thread Nathan Fontenot
When booting into the kdump/kexec kernel, pHyp and vios
are not prepared for the initialization crq request and
a failover transport event is generated. This is not
handled correctly.

At this point in initialization the driver is still in
the 'probing' state and cannot handle a full reset of the
driver as is normally done for a failover transport event.

To correct this we catch driver resets while still in the
'probing' state and return EAGAIN. This results in the
driver tearing down the main crq and calling ibmvnic_init()
again.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 59ea7a5..50ac1dc 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1447,6 +1447,12 @@ static void ibmvnic_reset(struct ibmvnic_adapter 
*adapter,
return;
}
 
+   if (adapter->state == VNIC_PROBING) {
+   netdev_warn(netdev, "Adapter reset during probe\n");
+   adapter->init_done_rc = EAGAIN;
+   return;
+   }
+
mutex_lock(>rwi_lock);
 
list_for_each(entry, >rwi_list) {
@@ -3634,12 +3640,18 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
adapter->from_passive_init = false;
 
init_completion(>init_done);
+   adapter->init_done_rc = 0;
ibmvnic_send_crq_init(adapter);
if (!wait_for_completion_timeout(>init_done, timeout)) {
dev_err(dev, "Initialization sequence timed out\n");
return -1;
}
 
+   if (adapter->init_done_rc) {
+   release_crq_queue(adapter);
+   return adapter->init_done_rc;
+   }
+
if (adapter->from_passive_init) {
adapter->state = VNIC_OPEN;
adapter->from_passive_init = false;
@@ -3708,11 +3720,13 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
mutex_init(>rwi_lock);
adapter->resetting = false;
 
-   rc = ibmvnic_init(adapter);
-   if (rc) {
-   free_netdev(netdev);
-   return rc;
-   }
+   do {
+   rc = ibmvnic_init(adapter);
+   if (rc != EAGAIN) {
+   free_netdev(netdev);
+   return rc;
+   }
+   } while (rc == EAGAIN);
 
netdev->mtu = adapter->req_mtu - ETH_HLEN;
 



[PATCH net-next] ibmvnic: Remove netdev notify for failover resets

2017-06-12 Thread Nathan Fontenot
When handling a driver reset due to a failover of the backing
server on the vios, doing the netdev_notify_peers() can cause
network traffic to stall or halt. Remove the netdev notify call
for failover resets.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 7d84e20..1c647c0 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1364,7 +1364,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
for (i = 0; i < adapter->req_rx_queues; i++)
napi_schedule(>napi[i]);
 
-   netdev_notify_peers(netdev);
+   if (adapter->reset_reason != VNIC_RESET_FAILOVER)
+   netdev_notify_peers(netdev);
+
return 0;
 }
 



Re: [PATCH net-next] ibmvnic: Client-initiated failover

2017-06-12 Thread Nathan Fontenot
On 06/12/2017 12:35 PM, Thomas Falcon wrote:
> The IBM vNIC protocol provides support for the user to initiate
> a failover from the client LPAR in case the current backing infrastructure
> is deemed inadequate or in an error state.
> 
> Support for two H_VIOCTL sub-commands for vNIC devices are required
> to implement this function. These commands are H_GET_SESSION_TOKEN
> and H_SESSION_ERR_DETECTED.
> 
> "[H_GET_SESSION_TOKEN] is used to obtain a session token from a VNIC client
> adapter.  This token is opaque to the caller and is intended to be used in
> tandem with the SESSION_ERROR_DETECTED vioctl subfunction."
> 
> "[H_SESSION_ERR_DETECTED] is used to report that the currently active
> backing device for a VNIC client adapter is behaving poorly, and that
> the hypervisor should attempt to fail over to a different backing device,
> if one is available."
> 
> To provide tools access to this functionality the vNIC driver creates a
> sysfs file that, when written to, will send a request to pHyp to failover
> to a different backing device.
> 
> Signed-off-by: Thomas Falcon <tlfal...@linux.vnet.ibm.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
>  arch/powerpc/include/asm/hvcall.h  |  2 ++
>  drivers/net/ethernet/ibm/ibmvnic.c | 46 
> ++
>  2 files changed, 48 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/hvcall.h 
> b/arch/powerpc/include/asm/hvcall.h
> index d73755f..57d38b5 100644
> --- a/arch/powerpc/include/asm/hvcall.h
> +++ b/arch/powerpc/include/asm/hvcall.h
> @@ -295,6 +295,8 @@
>  #define H_DISABLE_ALL_VIO_INTS   0x0A
>  #define H_DISABLE_VIO_INTERRUPT  0x0B
>  #define H_ENABLE_VIO_INTERRUPT   0x0C
> +#define H_GET_SESSION_TOKEN  0x19
> +#define H_SESSION_ERR_DETECTED   0x1A
> 
> 
>  /* Platform specific hcalls, used by KVM */
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 7d84e20..fd3ef30 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -3656,6 +3656,8 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
>   return rc;
>  }
> 
> +static struct device_attribute dev_attr_failover;
> +
>  static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
>  {
>   struct ibmvnic_adapter *adapter;
> @@ -3712,9 +3714,16 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
> struct vio_device_id *id)
> 
>   netdev->mtu = adapter->req_mtu - ETH_HLEN;
> 
> + rc = device_create_file(>dev, _attr_failover);
> + if (rc) {
> + free_netdev(netdev);
> + return rc;
> + }
> +
>   rc = register_netdev(netdev);
>   if (rc) {
>   dev_err(>dev, "failed to register netdev rc=%d\n", rc);
> + device_remove_file(>dev, _attr_failover);
>   free_netdev(netdev);
>   return rc;
>   }
> @@ -3740,12 +3749,49 @@ static int ibmvnic_remove(struct vio_dev *dev)
>   adapter->state = VNIC_REMOVED;
> 
>   mutex_unlock(>reset_lock);
> + device_remove_file(>dev, _attr_failover);
>   free_netdev(netdev);
>   dev_set_drvdata(>dev, NULL);
> 
>   return 0;
>  }
> 
> +static ssize_t failover_store(struct device *dev, struct device_attribute 
> *attr,
> +   const char *buf, size_t count)
> +{
> + struct net_device *netdev = dev_get_drvdata(dev);
> + struct ibmvnic_adapter *adapter = netdev_priv(netdev);
> + unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
> + __be64 session_token;
> + long rc;
> +
> + if (!sysfs_streq(buf, "1"))
> + return -EINVAL;
> +
> + rc = plpar_hcall(H_VIOCTL, retbuf, adapter->vdev->unit_address,
> +  H_GET_SESSION_TOKEN, 0, 0, 0);
> + if (rc) {
> + netdev_err(netdev, "Couldn't retrieve session token, rc %ld\n",
> +rc);
> + return -EINVAL;
> + }
> +
> + session_token = (__be64)retbuf[0];
> + netdev_dbg(netdev, "Initiating client failover, session id %llx\n",
> +be64_to_cpu(session_token));
> + rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
> + H_SESSION_ERR_DETECTED, session_token, 0, 0);
> + if (rc) {
> + netdev_err(netdev, "Client initiated failover failed, rc %ld\n",
> +rc);
> + return -EINVAL;
> + }
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR(failover, 0200, NULL, failover_store);
> +
>  static unsigned long ibmvnic_get_desired_dma(struct vio_dev *vdev)
>  {
>   struct net_device *netdev = dev_get_drvdata(>dev);
> 



[PATCH net-next 08/11] ibmvnic: Check adapter state during ibmvnic_poll

2017-05-26 Thread Nathan Fontenot
We do not want to process any receive frames if the ibmvnic_poll
routine is invoked while a reset is in process. Also, before
replenishing the rx pools in the ibmvnic_poll, we want to
make sure the adapter is not in the process of closing.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 47421e4..760352f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1435,6 +1435,10 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
int scrq_num = (int)(napi - adapter->napi);
int frames_processed = 0;
+
+   if (adapter->resetting)
+   return 0;
+
 restart_poll:
while (frames_processed < budget) {
struct sk_buff *skb;
@@ -1493,7 +1497,9 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
netdev->stats.rx_bytes += length;
frames_processed++;
}
-   replenish_rx_pool(adapter, >rx_pool[scrq_num]);
+
+   if (adapter->state != VNIC_CLOSING)
+   replenish_rx_pool(adapter, >rx_pool[scrq_num]);
 
if (frames_processed < budget) {
enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);



[PATCH net-next 11/11] ibmvnic: Reset sub-crqs during driver reset

2017-05-26 Thread Nathan Fontenot
When the ibmvnic driver is resetting, we can just reset the sub crqs
instead of releasing all of their resources and re-allocting them.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   46 ++--
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5661a04..8dcf580 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1320,8 +1320,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
 */
adapter->state = VNIC_PROBED;
 
-   release_sub_crqs(adapter);
-
rc = ibmvnic_init(adapter);
if (rc)
return 0;
@@ -1728,6 +1726,45 @@ static void ibmvnic_get_ethtool_stats(struct net_device 
*dev,
 
 /* Routines for managing CRQs/sCRQs  */
 
+static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter,
+  struct ibmvnic_sub_crq_queue *scrq)
+{
+   int rc;
+
+   if (scrq->irq) {
+   free_irq(scrq->irq, scrq);
+   irq_dispose_mapping(scrq->irq);
+   scrq->irq = 0;
+   }
+
+   memset(scrq->msgs, 0, 2 * PAGE_SIZE);
+   scrq->cur = 0;
+
+   rc = h_reg_sub_crq(adapter->vdev->unit_address, scrq->msg_token,
+  4 * PAGE_SIZE, >crq_num, >hw_irq);
+   return rc;
+}
+
+static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter)
+{
+   int i, rc;
+
+   for (i = 0; i < adapter->req_tx_queues; i++) {
+   rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]);
+   if (rc)
+   return rc;
+   }
+
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   rc = reset_one_sub_crq_queue(adapter, adapter->rx_scrq[i]);
+   if (rc)
+   return rc;
+   }
+
+   rc = init_sub_crq_irqs(adapter);
+   return rc;
+}
+
 static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
  struct ibmvnic_sub_crq_queue *scrq)
 {
@@ -3607,7 +3644,10 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
return -1;
}
 
-   rc = init_sub_crqs(adapter);
+   if (adapter->resetting)
+   rc = reset_sub_crq_queues(adapter);
+   else
+   rc = init_sub_crqs(adapter);
if (rc) {
dev_err(dev, "Initialization of sub crqs failed\n");
release_crq_queue(adapter);



[PATCH net-next 09/11] ibmvnic: Reset the CRQ queue during driver reset

2017-05-26 Thread Nathan Fontenot
When a driver reset operation occurs there is not a need to release
the CRQ resources and re-allocate them. Instead a reset of the CRQ
will suffice.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 760352f..b9b0c69 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1260,7 +1260,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
 
release_resources(adapter);
release_sub_crqs(adapter);
-   release_crq_queue(adapter);
 
rc = ibmvnic_init(adapter);
if (rc)
@@ -3517,7 +3516,14 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
unsigned long timeout = msecs_to_jiffies(3);
int rc;
 
-   rc = init_crq_queue(adapter);
+   if (adapter->resetting) {
+   rc = ibmvnic_reset_crq(adapter);
+   if (!rc)
+   rc = vio_enable_interrupts(adapter->vdev);
+   } else {
+   rc = init_crq_queue(adapter);
+   }
+
if (rc) {
dev_err(dev, "Couldn't initialize crq. rc=%d\n", rc);
return rc;



[PATCH net-next 10/11] ibmvnic: Reset tx/rx pools on driver reset

2017-05-26 Thread Nathan Fontenot
When resetting the ibmvnic driver there is not a need to release
and re-allocate the resources for the tx and rx pools. These
resources can just be reset to avoid the re-allocations.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   71 ++--
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index b9b0c69..5661a04 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -163,6 +163,16 @@ static long h_reg_sub_crq(unsigned long unit_address, 
unsigned long token,
return rc;
 }
 
+static void reset_long_term_buff(struct ibmvnic_adapter *adapter,
+struct ibmvnic_long_term_buff *ltb)
+{
+   memset(ltb->buff, 0, ltb->size);
+
+   init_completion(>fw_done);
+   send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id);
+   wait_for_completion(>fw_done);
+}
+
 static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
struct ibmvnic_long_term_buff *ltb, int size)
 {
@@ -352,6 +362,32 @@ static int init_stats_token(struct ibmvnic_adapter 
*adapter)
return 0;
 }
 
+static int reset_rx_pools(struct ibmvnic_adapter *adapter)
+{
+   struct ibmvnic_rx_pool *rx_pool;
+   int rx_scrqs;
+   int i, j;
+
+   rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+   for (i = 0; i < rx_scrqs; i++) {
+   rx_pool = >rx_pool[i];
+
+   reset_long_term_buff(adapter, _pool->long_term_buff);
+
+   for (j = 0; j < rx_pool->size; j++)
+   rx_pool->free_map[j] = j;
+
+   memset(rx_pool->rx_buff, 0,
+  rx_pool->size * sizeof(struct ibmvnic_rx_buff));
+
+   atomic_set(_pool->available, 0);
+   rx_pool->next_alloc = 0;
+   rx_pool->next_free = 0;
+   }
+
+   return 0;
+}
+
 static void release_rx_pools(struct ibmvnic_adapter *adapter)
 {
struct ibmvnic_rx_pool *rx_pool;
@@ -453,6 +489,32 @@ static int init_rx_pools(struct net_device *netdev)
return 0;
 }
 
+static int reset_tx_pools(struct ibmvnic_adapter *adapter)
+{
+   struct ibmvnic_tx_pool *tx_pool;
+   int tx_scrqs;
+   int i, j;
+
+   tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+   for (i = 0; i < tx_scrqs; i++) {
+   tx_pool = >tx_pool[i];
+
+   reset_long_term_buff(adapter, _pool->long_term_buff);
+
+   memset(tx_pool->tx_buff, 0,
+  adapter->req_tx_entries_per_subcrq *
+  sizeof(struct ibmvnic_tx_buff));
+
+   for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++)
+   tx_pool->free_map[j] = j;
+
+   tx_pool->consumer_index = 0;
+   tx_pool->producer_index = 0;
+   }
+
+   return 0;
+}
+
 static void release_tx_pools(struct ibmvnic_adapter *adapter)
 {
struct ibmvnic_tx_pool *tx_pool;
@@ -1258,7 +1320,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
 */
adapter->state = VNIC_PROBED;
 
-   release_resources(adapter);
release_sub_crqs(adapter);
 
rc = ibmvnic_init(adapter);
@@ -1277,9 +1338,11 @@ static int do_reset(struct ibmvnic_adapter *adapter,
return 0;
}
 
-   rtnl_lock();
-   rc = init_resources(adapter);
-   rtnl_unlock();
+   rc = reset_tx_pools(adapter);
+   if (rc)
+   return rc;
+
+   rc = reset_rx_pools(adapter);
if (rc)
return rc;
 



[PATCH net-next 07/11] ibmvnic: Deactivate RX pool buffer replenishment on H_CLOSED

2017-05-26 Thread Nathan Fontenot
From: Thomas Falcon 

If H_CLOSED is returned, halt RX buffer replenishment activity
until firmware sends a notification that the driver can reset.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c |   21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 1c3f1ed..47421e4 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -200,6 +200,15 @@ static void free_long_term_buff(struct ibmvnic_adapter 
*adapter,
dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
 }
 
+static void deactivate_rx_pools(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+i++)
+   adapter->rx_pool[i].active = 0;
+}
+
 static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
  struct ibmvnic_rx_pool *pool)
 {
@@ -217,6 +226,9 @@ static void replenish_rx_pool(struct ibmvnic_adapter 
*adapter,
int index;
int i;
 
+   if (!pool->active)
+   return;
+
handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
  be32_to_cpu(adapter->login_rsp_buf->
  off_rxadd_subcrqs));
@@ -287,6 +299,15 @@ static void replenish_rx_pool(struct ibmvnic_adapter 
*adapter,
dev_kfree_skb_any(skb);
adapter->replenish_add_buff_failure++;
atomic_add(buffers_added, >available);
+
+   if (lpar_rc == H_CLOSED) {
+   /* Disable buffer pool replenishment and report carrier off if
+* queue is closed. Firmware guarantees that a signal will
+* be sent to the driver, triggering a reset.
+*/
+   deactivate_rx_pools(adapter);
+   netif_carrier_off(adapter->netdev);
+   }
 }
 
 static void replenish_pools(struct ibmvnic_adapter *adapter)



[PATCH net-next 06/11] ibmvnic: Halt TX and report carrier off on H_CLOSED return code

2017-05-26 Thread Nathan Fontenot
From: Thomas Falcon 

This patch disables transmissions and reports carrier off if xmit
function returns that the hardware TX queue is closed. The driver can
then await a signal from firmware to determine the correct reset method.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index def867a..1c3f1ed 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -,8 +,14 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
dev_kfree_skb_any(skb);
tx_buff->skb = NULL;
 
-   if (lpar_rc == H_CLOSED)
-   netif_stop_subqueue(netdev, queue_num);
+   if (lpar_rc == H_CLOSED) {
+   /* Disable TX and report carrier off if queue is closed.
+* Firmware guarantees that a signal will be sent to the
+* driver, triggering a reset or some other action.
+*/
+   netif_tx_stop_all_queues(netdev);
+   netif_carrier_off(netdev);
+   }
 
tx_send_failed++;
tx_dropped++;



[PATCH net-next 05/11] ibmvnic: Non-fatal error handling

2017-05-26 Thread Nathan Fontenot
From: John Allen 

Handle non-fatal error conditions. The process to do this when
resetting the driver is to just do __ibmvnic_close followed by
__ibmvnic_open.

Signed-off-by: John Allen 
---
 drivers/net/ethernet/ibm/ibmvnic.c |   56 
 drivers/net/ethernet/ibm/ibmvnic.h |1 +
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 0f705e6..def867a 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1225,37 +1225,41 @@ static int do_reset(struct ibmvnic_adapter *adapter,
if (rc)
return rc;
 
-   /* remove the closed state so when we call open it appears
-* we are coming from the probed state.
-*/
-   adapter->state = VNIC_PROBED;
+   if (adapter->reset_reason != VNIC_RESET_NON_FATAL) {
+   /* remove the closed state so when we call open it appears
+* we are coming from the probed state.
+*/
+   adapter->state = VNIC_PROBED;
 
-   release_resources(adapter);
-   release_sub_crqs(adapter);
-   release_crq_queue(adapter);
+   release_resources(adapter);
+   release_sub_crqs(adapter);
+   release_crq_queue(adapter);
 
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return 0;
+   rc = ibmvnic_init(adapter);
+   if (rc)
+   return 0;
 
-   /* If the adapter was in PROBE state prior to the reset, exit here. */
-   if (reset_state == VNIC_PROBED)
-   return 0;
+   /* If the adapter was in PROBE state prior to the reset,
+* exit here.
+*/
+   if (reset_state == VNIC_PROBED)
+   return 0;
 
-   rc = ibmvnic_login(netdev);
-   if (rc) {
-   adapter->state = VNIC_PROBED;
-   return 0;
-   }
+   rc = ibmvnic_login(netdev);
+   if (rc) {
+   adapter->state = VNIC_PROBED;
+   return 0;
+   }
 
-   rtnl_lock();
-   rc = init_resources(adapter);
-   rtnl_unlock();
-   if (rc)
-   return rc;
+   rtnl_lock();
+   rc = init_resources(adapter);
+   rtnl_unlock();
+   if (rc)
+   return rc;
 
-   if (reset_state == VNIC_CLOSED)
-   return 0;
+   if (reset_state == VNIC_CLOSED)
+   return 0;
+   }
 
rc = __ibmvnic_open(netdev);
if (rc) {
@@ -2763,6 +2767,8 @@ static void handle_error_indication(union ibmvnic_crq 
*crq,
 
if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+   else
+   ibmvnic_reset(adapter, VNIC_RESET_NON_FATAL);
 }
 
 static void handle_change_mac_rsp(union ibmvnic_crq *crq,
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index fa6ac4e..7e2300e 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -925,6 +925,7 @@ enum vnic_state {VNIC_PROBING = 1,
 enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1,
   VNIC_RESET_MOBILITY,
   VNIC_RESET_FATAL,
+  VNIC_RESET_NON_FATAL,
   VNIC_RESET_TIMEOUT};
 
 struct ibmvnic_rwi {



[PATCH net-next 04/11] ibmvnic: Fix cleanup of SKB's on driver close

2017-05-26 Thread Nathan Fontenot
From: Thomas Falcon 

A race condition occurs when closing the driver. Free'ing of skb's
can race between the close routine and ibmvnic_tx_interrupt. To fix
this we move the claenup of tx pools during close to after the
sub-CRQ interrupts are disabled.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 465a8fa..0f705e6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -804,7 +804,6 @@ static int __ibmvnic_close(struct net_device *netdev)
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
ibmvnic_napi_disable(adapter);
-   clean_tx_pools(adapter);
 
if (adapter->tx_scrq) {
for (i = 0; i < adapter->req_tx_queues; i++)
@@ -833,6 +832,7 @@ static int __ibmvnic_close(struct net_device *netdev)
}
}
 
+   clean_tx_pools(adapter);
adapter->state = VNIC_CLOSED;
return rc;
 }



[PATCH net-next 03/11] ibmvnic: Send gratuitous arp on reset

2017-05-26 Thread Nathan Fontenot
From: John Allen 

Send gratuitous arp after any reset.

Signed-off-by: John Allen 
---
 drivers/net/ethernet/ibm/ibmvnic.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 1f7cf6f..465a8fa 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1273,6 +1273,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
for (i = 0; i < adapter->req_rx_queues; i++)
napi_schedule(>napi[i]);
 
+   netdev_notify_peers(netdev);
return 0;
 }
 



[PATCH net-next 02/11] ibmvnic: Handle failover after failed init crq

2017-05-26 Thread Nathan Fontenot
From: John Allen 

Handle case where phyp sends a failover after failing to send the
init crq.

Signed-off-by: John Allen 
---
 drivers/net/ethernet/ibm/ibmvnic.c |   11 ++-
 drivers/net/ethernet/ibm/ibmvnic.h |2 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4997de4..1f7cf6f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3167,6 +3167,8 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
switch (gen_crq->cmd) {
case IBMVNIC_CRQ_INIT:
dev_info(dev, "Partner initialized\n");
+   adapter->from_passive_init = true;
+   complete(>init_done);
break;
case IBMVNIC_CRQ_INIT_COMPLETE:
dev_info(dev, "Partner initialization complete\n");
@@ -3481,11 +3483,18 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
return rc;
}
 
+   adapter->from_passive_init = false;
+
init_completion(>init_done);
ibmvnic_send_crq_init(adapter);
if (!wait_for_completion_timeout(>init_done, timeout)) {
dev_err(dev, "Initialization sequence timed out\n");
-   release_crq_queue(adapter);
+   return -1;
+   }
+
+   if (adapter->from_passive_init) {
+   adapter->state = VNIC_OPEN;
+   adapter->from_passive_init = false;
return -1;
}
 
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index 4816e04..fa6ac4e 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1031,5 +1031,5 @@ struct ibmvnic_adapter {
struct list_head rwi_list;
struct work_struct ibmvnic_reset;
bool resetting;
-   bool napi_enabled;
+   bool napi_enabled, from_passive_init;
 };



[PATCH net-next 01/11] ibmvnic: Track state of adapter napis

2017-05-26 Thread Nathan Fontenot
From: John Allen <jal...@linux.vnet.ibm.com>

Track the state of ibmvnic napis. The driver can get into states where it
can be reset when napis are already disabled and attempting to disable them
again will cause the driver to hang.

Signed-off-by: John Allen <jal...@linux.vnet.ibm.com>
Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   37 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |1 +
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 27f7933..4997de4 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -518,6 +518,32 @@ static void release_error_buffers(struct ibmvnic_adapter 
*adapter)
spin_unlock_irqrestore(>error_list_lock, flags);
 }
 
+static void ibmvnic_napi_enable(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   if (adapter->napi_enabled)
+   return;
+
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_enable(>napi[i]);
+
+   adapter->napi_enabled = true;
+}
+
+static void ibmvnic_napi_disable(struct ibmvnic_adapter *adapter)
+{
+   int i;
+
+   if (!adapter->napi_enabled)
+   return;
+
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_disable(>napi[i]);
+
+   adapter->napi_enabled = false;
+}
+
 static int ibmvnic_login(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -674,9 +700,7 @@ static int __ibmvnic_open(struct net_device *netdev)
 
adapter->state = VNIC_OPENING;
replenish_pools(adapter);
-
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   napi_enable(>napi[i]);
+   ibmvnic_napi_enable(adapter);
 
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
@@ -779,12 +803,7 @@ static int __ibmvnic_close(struct net_device *netdev)
 
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
-
-   if (adapter->napi) {
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   napi_disable(>napi[i]);
-   }
-
+   ibmvnic_napi_disable(adapter);
clean_tx_pools(adapter);
 
if (adapter->tx_scrq) {
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index 4702b48..4816e04 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1031,4 +1031,5 @@ struct ibmvnic_adapter {
struct list_head rwi_list;
struct work_struct ibmvnic_reset;
bool resetting;
+   bool napi_enabled;
 };



[PATCH net-next 00/11] ibmvnic: Driver updates

2017-05-26 Thread Nathan Fontenot
This set of patches implements several updates to the ibmvnic driver
to fix issues that have been found in testing. Most of the updates
invovle updating queue handling during driver close and reset
operations.

-Nathan
---

John Allen (4):
  ibmvnic: Track state of adapter napis
  ibmvnic: Handle failover after failed init crq
  ibmvnic: Send gratuitous arp on reset
  ibmvnic: Non-fatal error handling

Nathan Fontenot (4):
  ibmvnic: Check adapter state during ibmvnic_poll
  ibmvnic: Reset the CRQ queue during driver reset
  ibmvnic: Reset tx/rx pools on driver reset
  ibmvnic: Reset sub-crqs during driver reset

Thomas Falcon (3):
  ibmvnic: Fix cleanup of SKB's on driver close
  ibmvnic: Halt TX and report carrier off on H_CLOSED return code
  ibmvnic: Deactivate RX pool buffer replenishment on H_CLOSED


 drivers/net/ethernet/ibm/ibmvnic.c |  259 ++--
 drivers/net/ethernet/ibm/ibmvnic.h |2 
 2 files changed, 220 insertions(+), 41 deletions(-)



Re: [PATCH net-next] ibmvnic: fix missing unlock on error in __ibmvnic_reset()

2017-05-18 Thread Nathan Fontenot
On 05/18/2017 10:24 AM, Wei Yongjun wrote:
> From: Wei Yongjun <weiyongj...@huawei.com>
> 
> Add the missing unlock before return from function __ibmvnic_reset()
> in the error handling case.
> 
> Fixes: ed651a10875f ("ibmvnic: Updated reset handling")
> Signed-off-by: Wei Yongjun <weiyongj...@huawei.com>

Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>

> ---
>  drivers/net/ethernet/ibm/ibmvnic.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
> b/drivers/net/ethernet/ibm/ibmvnic.c
> index 4f2d329..27f7933 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -1313,6 +1313,7 @@ static void __ibmvnic_reset(struct work_struct *work)
> 
>   if (rc) {
>   free_all_rwi(adapter);
> + mutex_unlock(>reset_lock);
>   return;
>   }
> 



[PATCH v4 net-next 11/11] ibmvnic: Move queue restarting in ibmvnic_tx_complete

2017-05-03 Thread Nathan Fontenot
Restart of the subqueue should occur outside of the loop processing
any tx buffers instead of doing this in the middle of the loop.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

v2: Use __netif_subqueue_stopped() instead of netif_subqueue_stopped()
to avoid possible using un-initialized skb variable.
---
 drivers/net/ethernet/ibm/ibmvnic.c |   22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 1b6268c..4f2d329 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1809,19 +1809,8 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter 
*adapter,
}
 
if (txbuff->last_frag) {
-   if (atomic_sub_return(next->tx_comp.num_comps,
- >used) <=
-   (adapter->req_tx_entries_per_subcrq / 2) &&
-   netif_subqueue_stopped(adapter->netdev,
-  txbuff->skb)) {
-   netif_wake_subqueue(adapter->netdev,
-   scrq->pool_index);
-   netdev_dbg(adapter->netdev,
-  "Started queue %d\n",
-  scrq->pool_index);
-   }
-
dev_kfree_skb_any(txbuff->skb);
+   txbuff->skb = NULL;
}
 
adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
@@ -1832,6 +1821,15 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter 
*adapter,
}
/* remove tx_comp scrq*/
next->tx_comp.first = 0;
+
+   if (atomic_sub_return(next->tx_comp.num_comps, >used) <=
+   (adapter->req_tx_entries_per_subcrq / 2) &&
+   __netif_subqueue_stopped(adapter->netdev,
+scrq->pool_index)) {
+   netif_wake_subqueue(adapter->netdev, scrq->pool_index);
+   netdev_info(adapter->netdev, "Started queue %d\n",
+   scrq->pool_index);
+   }
}
 
enable_scrq_irq(adapter, scrq);



[PATCH v4 net-next 07/11] ibmvnic: Wait for any pending scrqs entries at driver close

2017-05-03 Thread Nathan Fontenot
When closing the ibmvnic driver we need to wait for any pending
sub crq entries to ensure they are handled.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   47 +---
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 2297cf2..a312bc1 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -743,23 +743,6 @@ static int ibmvnic_open(struct net_device *netdev)
return rc;
 }
 
-static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
-{
-   int i;
-
-   if (adapter->tx_scrq) {
-   for (i = 0; i < adapter->req_tx_queues; i++)
-   if (adapter->tx_scrq[i])
-   disable_irq(adapter->tx_scrq[i]->irq);
-   }
-
-   if (adapter->rx_scrq) {
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   if (adapter->rx_scrq[i])
-   disable_irq(adapter->rx_scrq[i]->irq);
-   }
-}
-
 static void clean_tx_pools(struct ibmvnic_adapter *adapter)
 {
struct ibmvnic_tx_pool *tx_pool;
@@ -797,15 +780,39 @@ static int __ibmvnic_close(struct net_device *netdev)
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
 
-   clean_tx_pools(adapter);
-   disable_sub_crqs(adapter);
-
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(>napi[i]);
}
 
+   clean_tx_pools(adapter);
+
+   if (adapter->tx_scrq) {
+   for (i = 0; i < adapter->req_tx_queues; i++)
+   if (adapter->tx_scrq[i]->irq)
+   disable_irq(adapter->tx_scrq[i]->irq);
+   }
+
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
+   if (rc)
+   return rc;
+
+   if (adapter->rx_scrq) {
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   int retries = 10;
+
+   while (pending_scrq(adapter, adapter->rx_scrq[i])) {
+   retries--;
+   mdelay(100);
+
+   if (retries == 0)
+   break;
+   }
+
+   if (adapter->rx_scrq[i]->irq)
+   disable_irq(adapter->rx_scrq[i]->irq);
+   }
+   }
 
adapter->state = VNIC_CLOSED;
return rc;



[PATCH v4 net-next 10/11] ibmvnic: Record SKB RX queue during poll

2017-05-03 Thread Nathan Fontenot
From: Thomas Falcon 

Map each RX SKB to the RX queue associated with the driver's RX SCRQ.
This should improve the RX CPU load balancing issues seen by the
performance team.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 00c9d5a..1b6268c 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1428,6 +1428,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
 
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, netdev);
+   skb_record_rx_queue(skb, scrq_num);
 
if (flags & IBMVNIC_IP_CHKSUM_GOOD &&
flags & IBMVNIC_TCP_UDP_CHKSUM_GOOD) {



[PATCH v4 net-next 06/11] ibmvnic: Clean up tx pools when closing

2017-05-03 Thread Nathan Fontenot
When closing the ibmvnic driver, most notably during the reset
path, the tx pools need to be cleaned to ensure there are no
hanging skbs that need to be free'ed.

The need for this was found during debugging a loss of network
traffic after handling a driver reset. The underlying cause was
some skbs in the tx pool that were never free'ed. As a
result the upper network layers never tried a re-send since it
believed the driver still had the skb.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index bbbd57e..2297cf2 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -760,6 +760,34 @@ static void disable_sub_crqs(struct ibmvnic_adapter 
*adapter)
}
 }
 
+static void clean_tx_pools(struct ibmvnic_adapter *adapter)
+{
+   struct ibmvnic_tx_pool *tx_pool;
+   u64 tx_entries;
+   int tx_scrqs;
+   int i, j;
+
+   if (!adapter->tx_pool)
+   return;
+
+   tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+   tx_entries = adapter->req_tx_entries_per_subcrq;
+
+   /* Free any remaining skbs in the tx buffer pools */
+   for (i = 0; i < tx_scrqs; i++) {
+   tx_pool = >tx_pool[i];
+   if (!tx_pool)
+   continue;
+
+   for (j = 0; j < tx_entries; j++) {
+   if (tx_pool->tx_buff[j].skb) {
+   dev_kfree_skb_any(tx_pool->tx_buff[j].skb);
+   tx_pool->tx_buff[j].skb = NULL;
+   }
+   }
+   }
+}
+
 static int __ibmvnic_close(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -768,6 +796,8 @@ static int __ibmvnic_close(struct net_device *netdev)
 
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
+
+   clean_tx_pools(adapter);
disable_sub_crqs(adapter);
 
if (adapter->napi) {



[PATCH v4 net-next 09/11] ibmvnic: Continue skb processing after skb completion error

2017-05-03 Thread Nathan Fontenot
There is not a need to stop processing skbs if we encounter a
skb that has a receive completion error.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index f1ee377..00c9d5a 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1404,7 +1404,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
/* free the entry */
next->rx_comp.first = 0;
remove_buff_from_pool(adapter, rx_buff);
-   break;
+   continue;
}
 
length = be32_to_cpu(next->rx_comp.len);



[PATCH v4 net-next 03/11] ibmvnic: Updated reset handling

2017-05-03 Thread Nathan Fontenot
The ibmvnic driver has multiple handlers for resetting the driver
depending on the reason the reset is needed (failover, lpm,
fatal erors,...). All of the reset handlers do essentially the same
thing, this patch moves this work to a common reset handler.

By doing this we also allow the driver to better handle situations
where we can get a reset while handling a reset.

The updated reset handling works by adding a reset work item to the
list of resets and then scheduling work to perform the reset. This
step is necessary because we can receive a reset in interrupt context
and we want to handle the reset out of interrupt context.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |  413 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |   19 +-
 2 files changed, 275 insertions(+), 157 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 40a8ba0..a7c7a94 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -194,7 +194,8 @@ static void free_long_term_buff(struct ibmvnic_adapter 
*adapter,
if (!ltb->buff)
return;
 
-   if (!adapter->failover)
+   if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+   adapter->reset_reason != VNIC_RESET_MOBILITY)
send_request_unmap(adapter, ltb->map_id);
dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
 }
@@ -292,9 +293,6 @@ static void replenish_pools(struct ibmvnic_adapter *adapter)
 {
int i;
 
-   if (adapter->migrated)
-   return;
-
adapter->replenish_task_cycles++;
for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
 i++) {
@@ -569,11 +567,6 @@ static int set_link_state(struct ibmvnic_adapter *adapter, 
u8 link_state)
bool resend;
int rc;
 
-   if (adapter->logical_link_state == link_state) {
-   netdev_dbg(netdev, "Link state already %d\n", link_state);
-   return 0;
-   }
-
netdev_err(netdev, "setting link state %d\n", link_state);
memset(, 0, sizeof(crq));
crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
@@ -664,27 +657,13 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 }
 
-static int ibmvnic_open(struct net_device *netdev)
+static int __ibmvnic_open(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+   enum vnic_state prev_state = adapter->state;
int i, rc;
 
adapter->state = VNIC_OPENING;
-
-   if (adapter->state == VNIC_CLOSED) {
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return rc;
-   }
-
-   rc = ibmvnic_login(netdev);
-   if (rc)
-   return rc;
-
-   rc = init_resources(adapter);
-   if (rc)
-   return rc;
-
replenish_pools(adapter);
 
for (i = 0; i < adapter->req_rx_queues; i++)
@@ -693,22 +672,65 @@ static int ibmvnic_open(struct net_device *netdev)
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
 */
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   if (prev_state == VNIC_CLOSED)
+   enable_irq(adapter->rx_scrq[i]->irq);
+   else
+   enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+   }
 
-   for (i = 0; i < adapter->req_tx_queues; i++)
-   enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+   for (i = 0; i < adapter->req_tx_queues; i++) {
+   if (prev_state == VNIC_CLOSED)
+   enable_irq(adapter->tx_scrq[i]->irq);
+   else
+   enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+   }
 
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
if (rc) {
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(>napi[i]);
release_resources(adapter);
-   } else {
-   netif_tx_start_all_queues(netdev);
-   adapter->state = VNIC_OPEN;
+   return rc;
}
 
+   netif_tx_start_all_queues(netdev);
+
+   if (prev_state == VNIC_CLOSED) {
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_schedule(>napi[i]);
+   }
+
+   adapter->state = VNIC_OPEN;
+   return rc;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+

[PATCH v4 net-next 01/11] ibmvnic: Move resource initialization to its own routine

2017-05-03 Thread Nathan Fontenot
Move all of the calls to initialize resources for the driver to
a separate routine.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   71 
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4fcd2f0..c67f1d6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -624,22 +624,10 @@ static int set_real_num_queues(struct net_device *netdev)
return rc;
 }
 
-static int ibmvnic_open(struct net_device *netdev)
+static int init_resources(struct ibmvnic_adapter *adapter)
 {
-   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-   struct device *dev = >vdev->dev;
-   int rc = 0;
-   int i;
-
-   if (adapter->is_closed) {
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return rc;
-   }
-
-   rc = ibmvnic_login(netdev);
-   if (rc)
-   return rc;
+   struct net_device *netdev = adapter->netdev;
+   int i, rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -647,7 +635,7 @@ static int ibmvnic_open(struct net_device *netdev)
 
rc = init_sub_crq_irqs(adapter);
if (rc) {
-   dev_err(dev, "failed to initialize sub crq irqs\n");
+   netdev_err(netdev, "failed to initialize sub crq irqs\n");
return -1;
}
 
@@ -659,25 +647,47 @@ static int ibmvnic_open(struct net_device *netdev)
adapter->napi = kcalloc(adapter->req_rx_queues,
sizeof(struct napi_struct), GFP_KERNEL);
if (!adapter->napi)
-   goto ibmvnic_open_fail;
+   return -ENOMEM;
+
for (i = 0; i < adapter->req_rx_queues; i++) {
netif_napi_add(netdev, >napi[i], ibmvnic_poll,
   NAPI_POLL_WEIGHT);
-   napi_enable(>napi[i]);
}
 
send_map_query(adapter);
 
rc = init_rx_pools(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
 
rc = init_tx_pools(netdev);
+   return rc;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+   int i, rc;
+
+   if (adapter->is_closed) {
+   rc = ibmvnic_init(adapter);
+   if (rc)
+   return rc;
+   }
+
+   rc = ibmvnic_login(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
+
+   rc = init_resources(adapter);
+   if (rc)
+   return rc;
 
replenish_pools(adapter);
 
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_enable(>napi[i]);
+
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
 */
@@ -688,19 +698,16 @@ static int ibmvnic_open(struct net_device *netdev)
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
 
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
-   if (rc)
-   goto ibmvnic_open_fail;
-
-   netif_tx_start_all_queues(netdev);
-   adapter->is_closed = false;
-
-   return 0;
+   if (rc) {
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_disable(>napi[i]);
+   release_resources(adapter);
+   } else {
+   netif_tx_start_all_queues(netdev);
+   adapter->is_closed = false;
+   }
 
-ibmvnic_open_fail:
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   napi_disable(>napi[i]);
-   release_resources(adapter);
-   return -ENOMEM;
+   return rc;
 }
 
 static void disable_sub_crqs(struct ibmvnic_adapter *adapter)



[PATCH v4 net-next 00/11] ibmvnic: Updated reset handler and code fixes

2017-05-03 Thread Nathan Fontenot
This set of patches multiple code fixes and a new rest handler
for the ibmvnic driver. In order to implement the new reset handler
for the ibmvnic driver resource initialization needed to be moved to
its own routine, a state variable is introduced to replace the
various is_* flags in the driver, and a new routine to handle the
assorted reasons the driver can be reset.

v4 updates:

Patch 3/11: Corrected trailing whitespace
Patch 7/11: Corrected trailing whitespace

v3 updates:

Patch 10/11: Correct patch subject line to be a description of the patch.

v2 updates:

Patch 11/11: Use __netif_subqueue_stopped() instead of
netif_subqueue_stopped() to avoid possible use of an un-initialized
skb variable.

---

Nathan Fontenot (10):
  ibmvnic: Move resource initialization to its own routine
  ibmvnic: Replace is_closed with state field
  ibmvnic: Updated reset handling
  ibmvnic: Delete napi's when releasing driver resources
  ibmvnic: Whitespace correction in release_rx_pools
  ibmvnic: Clean up tx pools when closing
  ibmvnic: Wait for any pending scrqs entries at driver close
  ibmvnic: Check for driver reset first in ibmvnic_xmit
  ibmvnic: Continue skb processing after skb completion error
  ibmvnic: Move queue restarting in ibmvnic_tx_complete

Thomas Falcon (1):
  ibmvnic: Record SKB RX queue during poll


 drivers/net/ethernet/ibm/ibmvnic.c |  561 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |   31 ++
 2 files changed, 388 insertions(+), 204 deletions(-)

--
Nathan Fontenot



[PATCH v4 net-next 02/11] ibmvnic: Replace is_closed with state field

2017-05-03 Thread Nathan Fontenot
Replace the is_closed flag in the ibmvnic adapter strcut with a
more comprehensive state field that tracks the current state of
the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   20 +---
 drivers/net/ethernet/ibm/ibmvnic.h |   12 ++--
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index c67f1d6..40a8ba0 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -669,7 +669,9 @@ static int ibmvnic_open(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
int i, rc;
 
-   if (adapter->is_closed) {
+   adapter->state = VNIC_OPENING;
+
+   if (adapter->state == VNIC_CLOSED) {
rc = ibmvnic_init(adapter);
if (rc)
return rc;
@@ -704,7 +706,7 @@ static int ibmvnic_open(struct net_device *netdev)
release_resources(adapter);
} else {
netif_tx_start_all_queues(netdev);
-   adapter->is_closed = false;
+   adapter->state = VNIC_OPEN;
}
 
return rc;
@@ -733,7 +735,7 @@ static int ibmvnic_close(struct net_device *netdev)
int rc = 0;
int i;
 
-   adapter->closing = true;
+   adapter->state = VNIC_CLOSING;
disable_sub_crqs(adapter);
 
if (adapter->napi) {
@@ -748,8 +750,7 @@ static int ibmvnic_close(struct net_device *netdev)
 
release_resources(adapter);
 
-   adapter->is_closed = true;
-   adapter->closing = false;
+   adapter->state = VNIC_CLOSED;
return rc;
 }
 
@@ -1860,7 +1861,8 @@ static int pending_scrq(struct ibmvnic_adapter *adapter,
 {
union sub_crq *entry = >msgs[scrq->cur];
 
-   if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP || adapter->closing)
+   if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP ||
+   adapter->state == VNIC_CLOSING)
return 1;
else
return 0;
@@ -3353,6 +3355,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
return -ENOMEM;
 
adapter = netdev_priv(netdev);
+   adapter->state = VNIC_PROBING;
dev_set_drvdata(>dev, netdev);
adapter->vdev = dev;
adapter->netdev = netdev;
@@ -3380,7 +3383,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
}
 
netdev->mtu = adapter->req_mtu - ETH_HLEN;
-   adapter->is_closed = false;
 
rc = register_netdev(netdev);
if (rc) {
@@ -3390,6 +3392,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
}
dev_info(>dev, "ibmvnic registered\n");
 
+   adapter->state = VNIC_PROBED;
return 0;
 }
 
@@ -3398,12 +3401,15 @@ static int ibmvnic_remove(struct vio_dev *dev)
struct net_device *netdev = dev_get_drvdata(>dev);
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
 
+   adapter->state = VNIC_REMOVING;
unregister_netdev(netdev);
 
release_resources(adapter);
release_sub_crqs(adapter);
release_crq_queue(adapter);
 
+   adapter->state = VNIC_REMOVED;
+
free_netdev(netdev);
dev_set_drvdata(>dev, NULL);
 
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index a69979f..03a866f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -913,6 +913,15 @@ struct ibmvnic_error_buff {
__be32 error_id;
 };
 
+enum vnic_state {VNIC_PROBING = 1,
+VNIC_PROBED,
+VNIC_OPENING,
+VNIC_OPEN,
+VNIC_CLOSING,
+VNIC_CLOSED,
+VNIC_REMOVING,
+VNIC_REMOVED};
+
 struct ibmvnic_adapter {
struct vio_dev *vdev;
struct net_device *netdev;
@@ -962,7 +971,6 @@ struct ibmvnic_adapter {
u64 promisc;
 
struct ibmvnic_tx_pool *tx_pool;
-   bool closing;
struct completion init_done;
int init_done_rc;
 
@@ -1011,5 +1019,5 @@ struct ibmvnic_adapter {
struct work_struct ibmvnic_xport;
struct tasklet_struct tasklet;
bool failover;
-   bool is_closed;
+   enum vnic_state state;
 };



[PATCH v4 net-next 05/11] ibmvnic: Whitespace correction in release_rx_pools

2017-05-03 Thread Nathan Fontenot
Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index d52d98c..bbbd57e 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -348,7 +348,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
free_long_term_buff(adapter, _pool->long_term_buff);
 
if (!rx_pool->rx_buff)
-   continue;
+   continue;
 
for (j = 0; j < rx_pool->size; j++) {
if (rx_pool->rx_buff[j].skb) {



[PATCH v4 net-next 08/11] ibmvnic: Check for driver reset first in ibmvnic_xmit

2017-05-03 Thread Nathan Fontenot
Move the check for the driver resetting to the first thing
in ibmvnic_xmit().

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index a312bc1..f1ee377 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -985,12 +985,6 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
int index = 0;
int ret = 0;
 
-   tx_pool = >tx_pool[queue_num];
-   tx_scrq = adapter->tx_scrq[queue_num];
-   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
-   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
-  be32_to_cpu(adapter->login_rsp_buf->
-  off_txsubm_subcrqs));
if (adapter->resetting) {
if (!netif_subqueue_stopped(netdev, skb))
netif_stop_subqueue(netdev, queue_num);
@@ -1002,6 +996,12 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
goto out;
}
 
+   tx_pool = >tx_pool[queue_num];
+   tx_scrq = adapter->tx_scrq[queue_num];
+   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
+   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+   be32_to_cpu(adapter->login_rsp_buf->off_txsubm_subcrqs));
+
index = tx_pool->free_map[tx_pool->consumer_index];
offset = index * adapter->req_mtu;
dst = tx_pool->long_term_buff.buff + offset;



[PATCH v4 net-next 04/11] ibmvnic: Delete napi's when releasing driver resources

2017-05-03 Thread Nathan Fontenot
The napi structs allocated at drivier initializatio need to be
free'ed when releasing the drivers resources.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index a7c7a94..d52d98c 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -552,11 +552,20 @@ static int ibmvnic_login(struct net_device *netdev)
 
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
+   int i;
+
release_tx_pools(adapter);
release_rx_pools(adapter);
 
release_stats_token(adapter);
release_error_buffers(adapter);
+
+   if (adapter->napi) {
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   if (>napi[i])
+   netif_napi_del(>napi[i]);
+   }
+   }
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)



[PATCH v3 net-next 09/11] ibmvnic: Continue skb processing after skb completion error

2017-05-02 Thread Nathan Fontenot
There is not a need to stop processing skbs if we encounter a
skb that has a receive completion error.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 2cf1b64..4b2e128 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1404,7 +1404,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
/* free the entry */
next->rx_comp.first = 0;
remove_buff_from_pool(adapter, rx_buff);
-   break;
+   continue;
}
 
length = be32_to_cpu(next->rx_comp.len);



[PATCH v3 net-next 11/11] ibmvnic: Move queue restarting in ibmvnic_tx_complete

2017-05-02 Thread Nathan Fontenot
Restart of the subqueue should occur outside of the loop processing
any tx buffers instead of doing this in the middle of the loop.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---

v2: Use __netif_subqueue_stopped() instead of netif_subqueue_stopped()
to avoid possible using un-initialized skb variable.
---
 drivers/net/ethernet/ibm/ibmvnic.c |   22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4a2b99f..4c5de60 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1809,19 +1809,8 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter 
*adapter,
}
 
if (txbuff->last_frag) {
-   if (atomic_sub_return(next->tx_comp.num_comps,
- >used) <=
-   (adapter->req_tx_entries_per_subcrq / 2) &&
-   netif_subqueue_stopped(adapter->netdev,
-  txbuff->skb)) {
-   netif_wake_subqueue(adapter->netdev,
-   scrq->pool_index);
-   netdev_dbg(adapter->netdev,
-  "Started queue %d\n",
-  scrq->pool_index);
-   }
-
dev_kfree_skb_any(txbuff->skb);
+   txbuff->skb = NULL;
}
 
adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
@@ -1832,6 +1821,15 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter 
*adapter,
}
/* remove tx_comp scrq*/
next->tx_comp.first = 0;
+
+   if (atomic_sub_return(next->tx_comp.num_comps, >used) <=
+   (adapter->req_tx_entries_per_subcrq / 2) &&
+   __netif_subqueue_stopped(adapter->netdev,
+scrq->pool_index)) {
+   netif_wake_subqueue(adapter->netdev, scrq->pool_index);
+   netdev_info(adapter->netdev, "Started queue %d\n",
+   scrq->pool_index);
+   }
}
 
enable_scrq_irq(adapter, scrq);



[PATCH v3 net-next 05/11] ibmvnic: Whitespace correction in release_rx_pools

2017-05-02 Thread Nathan Fontenot
Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 9f2686d..d20d884 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -348,7 +348,7 @@ static void release_rx_pools(struct ibmvnic_adapter 
*adapter)
free_long_term_buff(adapter, _pool->long_term_buff);
 
if (!rx_pool->rx_buff)
-   continue;
+   continue;
 
for (j = 0; j < rx_pool->size; j++) {
if (rx_pool->rx_buff[j].skb) {



[PATCH v3 net-next 10/11] ibmvnic: Record SKB RX queue during poll

2017-05-02 Thread Nathan Fontenot
From: Thomas Falcon 

Map each RX SKB to the RX queue associated with the driver's RX SCRQ.
This should improve the RX CPU load balancing issues seen by the
performance team.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4b2e128..4a2b99f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1428,6 +1428,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
 
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, netdev);
+   skb_record_rx_queue(skb, scrq_num);
 
if (flags & IBMVNIC_IP_CHKSUM_GOOD &&
flags & IBMVNIC_TCP_UDP_CHKSUM_GOOD) {



[PATCH v3 net-next 06/11] ibmvnic: Clean up tx pools when closing

2017-05-02 Thread Nathan Fontenot
When closing the ibmvnic driver, most notably during the reset
path, the tx pools need to be cleaned to ensure there are no
hanging skbs that need to be free'ed.

The need for this was found during debugging a loss of network
traffic after handling a driver reset. The underlying cause was
some skbs in the tx pool that were never free'ed. As a
result the upper network layers never tried a re-send since it
believed the driver still had the skb.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index d20d884..0400ae7 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -760,6 +760,34 @@ static void disable_sub_crqs(struct ibmvnic_adapter 
*adapter)
}
 }
 
+static void clean_tx_pools(struct ibmvnic_adapter *adapter)
+{
+   struct ibmvnic_tx_pool *tx_pool;
+   u64 tx_entries;
+   int tx_scrqs;
+   int i, j;
+
+   if (!adapter->tx_pool)
+   return;
+
+   tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+   tx_entries = adapter->req_tx_entries_per_subcrq;
+
+   /* Free any remaining skbs in the tx buffer pools */
+   for (i = 0; i < tx_scrqs; i++) {
+   tx_pool = >tx_pool[i];
+   if (!tx_pool)
+   continue;
+
+   for (j = 0; j < tx_entries; j++) {
+   if (tx_pool->tx_buff[j].skb) {
+   dev_kfree_skb_any(tx_pool->tx_buff[j].skb);
+   tx_pool->tx_buff[j].skb = NULL;
+   }
+   }
+   }
+}
+
 static int __ibmvnic_close(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -768,6 +796,8 @@ static int __ibmvnic_close(struct net_device *netdev)
 
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
+
+   clean_tx_pools(adapter);
disable_sub_crqs(adapter);
 
if (adapter->napi) {



[PATCH v3 net-next 08/11] ibmvnic: Check for driver reset first in ibmvnic_xmit

2017-05-02 Thread Nathan Fontenot
Move the check for the driver resetting to the first thing
in ibmvnic_xmit().

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4da7080..2cf1b64 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -985,12 +985,6 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
int index = 0;
int ret = 0;
 
-   tx_pool = >tx_pool[queue_num];
-   tx_scrq = adapter->tx_scrq[queue_num];
-   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
-   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
-  be32_to_cpu(adapter->login_rsp_buf->
-  off_txsubm_subcrqs));
if (adapter->resetting) {
if (!netif_subqueue_stopped(netdev, skb))
netif_stop_subqueue(netdev, queue_num);
@@ -1002,6 +996,12 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
goto out;
}
 
+   tx_pool = >tx_pool[queue_num];
+   tx_scrq = adapter->tx_scrq[queue_num];
+   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
+   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+   be32_to_cpu(adapter->login_rsp_buf->off_txsubm_subcrqs));
+
index = tx_pool->free_map[tx_pool->consumer_index];
offset = index * adapter->req_mtu;
dst = tx_pool->long_term_buff.buff + offset;



[PATCH v3 net-next 07/11] ibmvnic: Wait for any pending scrqs entries at driver close

2017-05-02 Thread Nathan Fontenot
When closing the ibmvnic driver we need to wait for any pending
sub crq entries to ensure they are handled.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   47 +---
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 0400ae7..4da7080 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -743,23 +743,6 @@ static int ibmvnic_open(struct net_device *netdev)
return rc;
 }
 
-static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
-{
-   int i;
-
-   if (adapter->tx_scrq) {
-   for (i = 0; i < adapter->req_tx_queues; i++)
-   if (adapter->tx_scrq[i])
-   disable_irq(adapter->tx_scrq[i]->irq);
-   }
-
-   if (adapter->rx_scrq) {
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   if (adapter->rx_scrq[i])
-   disable_irq(adapter->rx_scrq[i]->irq);
-   }
-}
-
 static void clean_tx_pools(struct ibmvnic_adapter *adapter)
 {
struct ibmvnic_tx_pool *tx_pool;
@@ -797,15 +780,39 @@ static int __ibmvnic_close(struct net_device *netdev)
adapter->state = VNIC_CLOSING;
netif_tx_stop_all_queues(netdev);
 
-   clean_tx_pools(adapter);
-   disable_sub_crqs(adapter);
-
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(>napi[i]);
}
 
+   clean_tx_pools(adapter);
+
+   if (adapter->tx_scrq) {
+   for (i = 0; i < adapter->req_tx_queues; i++)
+   if (adapter->tx_scrq[i]->irq)
+   disable_irq(adapter->tx_scrq[i]->irq);
+   }
+
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
+   if (rc)
+   return rc;
+
+   if (adapter->rx_scrq) {
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   int retries = 10;
+
+   while (pending_scrq(adapter, adapter->rx_scrq[i])) {
+   retries--;
+   mdelay(100);
+
+   if (retries == 0)
+   break;
+   }
+   
+   if (adapter->rx_scrq[i]->irq)
+   disable_irq(adapter->rx_scrq[i]->irq);
+   }
+   }
 
adapter->state = VNIC_CLOSED;
return rc;



[PATCH v3 net-next 01/11] ibmvnic: Move resource initialization to its own routine

2017-05-02 Thread Nathan Fontenot
Move all of the calls to initialize resources for the driver to
a separate routine.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   71 
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4fcd2f0..c67f1d6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -624,22 +624,10 @@ static int set_real_num_queues(struct net_device *netdev)
return rc;
 }
 
-static int ibmvnic_open(struct net_device *netdev)
+static int init_resources(struct ibmvnic_adapter *adapter)
 {
-   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-   struct device *dev = >vdev->dev;
-   int rc = 0;
-   int i;
-
-   if (adapter->is_closed) {
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return rc;
-   }
-
-   rc = ibmvnic_login(netdev);
-   if (rc)
-   return rc;
+   struct net_device *netdev = adapter->netdev;
+   int i, rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -647,7 +635,7 @@ static int ibmvnic_open(struct net_device *netdev)
 
rc = init_sub_crq_irqs(adapter);
if (rc) {
-   dev_err(dev, "failed to initialize sub crq irqs\n");
+   netdev_err(netdev, "failed to initialize sub crq irqs\n");
return -1;
}
 
@@ -659,25 +647,47 @@ static int ibmvnic_open(struct net_device *netdev)
adapter->napi = kcalloc(adapter->req_rx_queues,
sizeof(struct napi_struct), GFP_KERNEL);
if (!adapter->napi)
-   goto ibmvnic_open_fail;
+   return -ENOMEM;
+
for (i = 0; i < adapter->req_rx_queues; i++) {
netif_napi_add(netdev, >napi[i], ibmvnic_poll,
   NAPI_POLL_WEIGHT);
-   napi_enable(>napi[i]);
}
 
send_map_query(adapter);
 
rc = init_rx_pools(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
 
rc = init_tx_pools(netdev);
+   return rc;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+   int i, rc;
+
+   if (adapter->is_closed) {
+   rc = ibmvnic_init(adapter);
+   if (rc)
+   return rc;
+   }
+
+   rc = ibmvnic_login(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
+
+   rc = init_resources(adapter);
+   if (rc)
+   return rc;
 
replenish_pools(adapter);
 
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_enable(>napi[i]);
+
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
 */
@@ -688,19 +698,16 @@ static int ibmvnic_open(struct net_device *netdev)
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
 
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
-   if (rc)
-   goto ibmvnic_open_fail;
-
-   netif_tx_start_all_queues(netdev);
-   adapter->is_closed = false;
-
-   return 0;
+   if (rc) {
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_disable(>napi[i]);
+   release_resources(adapter);
+   } else {
+   netif_tx_start_all_queues(netdev);
+   adapter->is_closed = false;
+   }
 
-ibmvnic_open_fail:
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   napi_disable(>napi[i]);
-   release_resources(adapter);
-   return -ENOMEM;
+   return rc;
 }
 
 static void disable_sub_crqs(struct ibmvnic_adapter *adapter)



[PATCH v3 net-next 03/11] ibmvnic: Updated reset handling

2017-05-02 Thread Nathan Fontenot
The ibmvnic driver has multiple handlers for resetting the driver
depending on the reason the reset is needed (failover, lpm,
fatal erors,...). All of the reset handlers do essentially the same
thing, this patch moves this work to a common reset handler.

By doing this we also allow the driver to better handle situations
where we can get a reset while handling a reset.

The updated reset handling works by adding a reset work item to the
list of resets and then scheduling work to perform the reset. This
step is necessary because we can receive a reset in interrupt context
and we want to handle the reset out of interrupt context.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |  413 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |   19 +-
 2 files changed, 275 insertions(+), 157 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 40a8ba0..b3d9b28 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -194,7 +194,8 @@ static void free_long_term_buff(struct ibmvnic_adapter 
*adapter,
if (!ltb->buff)
return;
 
-   if (!adapter->failover)
+   if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+   adapter->reset_reason != VNIC_RESET_MOBILITY)
send_request_unmap(adapter, ltb->map_id);
dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
 }
@@ -292,9 +293,6 @@ static void replenish_pools(struct ibmvnic_adapter *adapter)
 {
int i;
 
-   if (adapter->migrated)
-   return;
-
adapter->replenish_task_cycles++;
for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
 i++) {
@@ -569,11 +567,6 @@ static int set_link_state(struct ibmvnic_adapter *adapter, 
u8 link_state)
bool resend;
int rc;
 
-   if (adapter->logical_link_state == link_state) {
-   netdev_dbg(netdev, "Link state already %d\n", link_state);
-   return 0;
-   }
-
netdev_err(netdev, "setting link state %d\n", link_state);
memset(, 0, sizeof(crq));
crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
@@ -664,27 +657,13 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return rc;
 }
 
-static int ibmvnic_open(struct net_device *netdev)
+static int __ibmvnic_open(struct net_device *netdev)
 {
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+   enum vnic_state prev_state = adapter->state;
int i, rc;
 
adapter->state = VNIC_OPENING;
-
-   if (adapter->state == VNIC_CLOSED) {
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return rc;
-   }
-
-   rc = ibmvnic_login(netdev);
-   if (rc)
-   return rc;
-
-   rc = init_resources(adapter);
-   if (rc)
-   return rc;
-
replenish_pools(adapter);
 
for (i = 0; i < adapter->req_rx_queues; i++)
@@ -693,22 +672,65 @@ static int ibmvnic_open(struct net_device *netdev)
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
 */
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   if (prev_state == VNIC_CLOSED)
+   enable_irq(adapter->rx_scrq[i]->irq);
+   else
+   enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+   }
 
-   for (i = 0; i < adapter->req_tx_queues; i++)
-   enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+   for (i = 0; i < adapter->req_tx_queues; i++) {
+   if (prev_state == VNIC_CLOSED)
+   enable_irq(adapter->tx_scrq[i]->irq);
+   else
+   enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+   }
 
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
if (rc) {
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(>napi[i]);
release_resources(adapter);
-   } else {
-   netif_tx_start_all_queues(netdev);
-   adapter->state = VNIC_OPEN;
+   return rc;
+   }
+   
+   netif_tx_start_all_queues(netdev);
+
+   if (prev_state == VNIC_CLOSED) {
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_schedule(>napi[i]);
}
 
+   adapter->state = VNIC_OPEN;
+   return rc;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+

[PATCH v3 net-next 04/11] ibmvnic: Delete napi's when releasing driver resources

2017-05-02 Thread Nathan Fontenot
The napi structs allocated at drivier initializatio need to be
free'ed when releasing the drivers resources.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index b3d9b28..9f2686d 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -552,11 +552,20 @@ static int ibmvnic_login(struct net_device *netdev)
 
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
+   int i;
+
release_tx_pools(adapter);
release_rx_pools(adapter);
 
release_stats_token(adapter);
release_error_buffers(adapter);
+
+   if (adapter->napi) {
+   for (i = 0; i < adapter->req_rx_queues; i++) {
+   if (>napi[i])
+   netif_napi_del(>napi[i]);
+   }
+   }
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)



[PATCH v3 net-next 02/11] ibmvnic: Replace is_closed with state field

2017-05-02 Thread Nathan Fontenot
Replace the is_closed flag in the ibmvnic adapter strcut with a
more comprehensive state field that tracks the current state of
the driver.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   20 +---
 drivers/net/ethernet/ibm/ibmvnic.h |   12 ++--
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index c67f1d6..40a8ba0 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -669,7 +669,9 @@ static int ibmvnic_open(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
int i, rc;
 
-   if (adapter->is_closed) {
+   adapter->state = VNIC_OPENING;
+
+   if (adapter->state == VNIC_CLOSED) {
rc = ibmvnic_init(adapter);
if (rc)
return rc;
@@ -704,7 +706,7 @@ static int ibmvnic_open(struct net_device *netdev)
release_resources(adapter);
} else {
netif_tx_start_all_queues(netdev);
-   adapter->is_closed = false;
+   adapter->state = VNIC_OPEN;
}
 
return rc;
@@ -733,7 +735,7 @@ static int ibmvnic_close(struct net_device *netdev)
int rc = 0;
int i;
 
-   adapter->closing = true;
+   adapter->state = VNIC_CLOSING;
disable_sub_crqs(adapter);
 
if (adapter->napi) {
@@ -748,8 +750,7 @@ static int ibmvnic_close(struct net_device *netdev)
 
release_resources(adapter);
 
-   adapter->is_closed = true;
-   adapter->closing = false;
+   adapter->state = VNIC_CLOSED;
return rc;
 }
 
@@ -1860,7 +1861,8 @@ static int pending_scrq(struct ibmvnic_adapter *adapter,
 {
union sub_crq *entry = >msgs[scrq->cur];
 
-   if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP || adapter->closing)
+   if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP ||
+   adapter->state == VNIC_CLOSING)
return 1;
else
return 0;
@@ -3353,6 +3355,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
return -ENOMEM;
 
adapter = netdev_priv(netdev);
+   adapter->state = VNIC_PROBING;
dev_set_drvdata(>dev, netdev);
adapter->vdev = dev;
adapter->netdev = netdev;
@@ -3380,7 +3383,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
}
 
netdev->mtu = adapter->req_mtu - ETH_HLEN;
-   adapter->is_closed = false;
 
rc = register_netdev(netdev);
if (rc) {
@@ -3390,6 +3392,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
}
dev_info(>dev, "ibmvnic registered\n");
 
+   adapter->state = VNIC_PROBED;
return 0;
 }
 
@@ -3398,12 +3401,15 @@ static int ibmvnic_remove(struct vio_dev *dev)
struct net_device *netdev = dev_get_drvdata(>dev);
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
 
+   adapter->state = VNIC_REMOVING;
unregister_netdev(netdev);
 
release_resources(adapter);
release_sub_crqs(adapter);
release_crq_queue(adapter);
 
+   adapter->state = VNIC_REMOVED;
+
free_netdev(netdev);
dev_set_drvdata(>dev, NULL);
 
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index a69979f..03a866f 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -913,6 +913,15 @@ struct ibmvnic_error_buff {
__be32 error_id;
 };
 
+enum vnic_state {VNIC_PROBING = 1,
+VNIC_PROBED,
+VNIC_OPENING,
+VNIC_OPEN,
+VNIC_CLOSING,
+VNIC_CLOSED,
+VNIC_REMOVING,
+VNIC_REMOVED};
+
 struct ibmvnic_adapter {
struct vio_dev *vdev;
struct net_device *netdev;
@@ -962,7 +971,6 @@ struct ibmvnic_adapter {
u64 promisc;
 
struct ibmvnic_tx_pool *tx_pool;
-   bool closing;
struct completion init_done;
int init_done_rc;
 
@@ -1011,5 +1019,5 @@ struct ibmvnic_adapter {
struct work_struct ibmvnic_xport;
struct tasklet_struct tasklet;
bool failover;
-   bool is_closed;
+   enum vnic_state state;
 };



[PATCH v3 net-next 00/11] ibmvnic: Updated reset handler and code fixes

2017-05-02 Thread Nathan Fontenot
This set of patches multiple code fixes and a new rest handler
for the ibmvnic driver. In order to implement the new reset handler
for the ibmvnic driver resource initialization needed to be moved to
its own routine, a state variable is introduced to replace the
various is_* flags in the driver, and a new routine to handle the
assorted reasons the driver can be reset.

v3 updates:

Patch 10/11: Correct patch subject line to be a description of the patch.

v2 updates:

Patch 11/11: Use __netif_subqueue_stopped() instead of
netif_subqueue_stopped() to avoid possible use of an un-initialized
skb variable.

---

Nathan Fontenot (10):
  ibmvnic: Move resource initialization to its own routine
  ibmvnic: Replace is_closed with state field
  ibmvnic: Updated reset handling
  ibmvnic: Delete napi's when releasing driver resources
  ibmvnic: Whitespace correction in release_rx_pools
  ibmvnic: Clean up tx pools when closing
  ibmvnic: Wait for any pending scrqs entries at driver close
  ibmvnic: Check for driver reset first in ibmvnic_xmit
  ibmvnic: Continue skb processing after skb completion error
  ibmvnic: Move queue restarting in ibmvnic_tx_complete

Thomas Falcon (1):
  ibmvnic: Record SKB RX queue during poll


 drivers/net/ethernet/ibm/ibmvnic.c |  563 +++-
 drivers/net/ethernet/ibm/ibmvnic.h |   31 ++
 2 files changed, 389 insertions(+), 205 deletions(-)

--
Nathan Fontenot



[PATCH v2 net-next 01/11] ibmvnic: Move resource initialization to its own routine

2017-05-01 Thread Nathan Fontenot
Move all of the calls to initialize resources for the driver to
a separate routine.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   71 
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4fcd2f0..c67f1d6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -624,22 +624,10 @@ static int set_real_num_queues(struct net_device *netdev)
return rc;
 }
 
-static int ibmvnic_open(struct net_device *netdev)
+static int init_resources(struct ibmvnic_adapter *adapter)
 {
-   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-   struct device *dev = >vdev->dev;
-   int rc = 0;
-   int i;
-
-   if (adapter->is_closed) {
-   rc = ibmvnic_init(adapter);
-   if (rc)
-   return rc;
-   }
-
-   rc = ibmvnic_login(netdev);
-   if (rc)
-   return rc;
+   struct net_device *netdev = adapter->netdev;
+   int i, rc;
 
rc = set_real_num_queues(netdev);
if (rc)
@@ -647,7 +635,7 @@ static int ibmvnic_open(struct net_device *netdev)
 
rc = init_sub_crq_irqs(adapter);
if (rc) {
-   dev_err(dev, "failed to initialize sub crq irqs\n");
+   netdev_err(netdev, "failed to initialize sub crq irqs\n");
return -1;
}
 
@@ -659,25 +647,47 @@ static int ibmvnic_open(struct net_device *netdev)
adapter->napi = kcalloc(adapter->req_rx_queues,
sizeof(struct napi_struct), GFP_KERNEL);
if (!adapter->napi)
-   goto ibmvnic_open_fail;
+   return -ENOMEM;
+
for (i = 0; i < adapter->req_rx_queues; i++) {
netif_napi_add(netdev, >napi[i], ibmvnic_poll,
   NAPI_POLL_WEIGHT);
-   napi_enable(>napi[i]);
}
 
send_map_query(adapter);
 
rc = init_rx_pools(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
 
rc = init_tx_pools(netdev);
+   return rc;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+   struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+   int i, rc;
+
+   if (adapter->is_closed) {
+   rc = ibmvnic_init(adapter);
+   if (rc)
+   return rc;
+   }
+
+   rc = ibmvnic_login(netdev);
if (rc)
-   goto ibmvnic_open_fail;
+   return rc;
+
+   rc = init_resources(adapter);
+   if (rc)
+   return rc;
 
replenish_pools(adapter);
 
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_enable(>napi[i]);
+
/* We're ready to receive frames, enable the sub-crq interrupts and
 * set the logical link state to up
 */
@@ -688,19 +698,16 @@ static int ibmvnic_open(struct net_device *netdev)
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
 
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
-   if (rc)
-   goto ibmvnic_open_fail;
-
-   netif_tx_start_all_queues(netdev);
-   adapter->is_closed = false;
-
-   return 0;
+   if (rc) {
+   for (i = 0; i < adapter->req_rx_queues; i++)
+   napi_disable(>napi[i]);
+   release_resources(adapter);
+   } else {
+   netif_tx_start_all_queues(netdev);
+   adapter->is_closed = false;
+   }
 
-ibmvnic_open_fail:
-   for (i = 0; i < adapter->req_rx_queues; i++)
-   napi_disable(>napi[i]);
-   release_resources(adapter);
-   return -ENOMEM;
+   return rc;
 }
 
 static void disable_sub_crqs(struct ibmvnic_adapter *adapter)



[PATCH v2 net-next 08/11] ibmvnic: Check for driver reset first in ibmvnic_xmit

2017-05-01 Thread Nathan Fontenot
Move the check for the driver resetting to the first thing
in ibmvnic_xmit().

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 4da7080..2cf1b64 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -985,12 +985,6 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
int index = 0;
int ret = 0;
 
-   tx_pool = >tx_pool[queue_num];
-   tx_scrq = adapter->tx_scrq[queue_num];
-   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
-   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
-  be32_to_cpu(adapter->login_rsp_buf->
-  off_txsubm_subcrqs));
if (adapter->resetting) {
if (!netif_subqueue_stopped(netdev, skb))
netif_stop_subqueue(netdev, queue_num);
@@ -1002,6 +996,12 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct 
net_device *netdev)
goto out;
}
 
+   tx_pool = >tx_pool[queue_num];
+   tx_scrq = adapter->tx_scrq[queue_num];
+   txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
+   handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+   be32_to_cpu(adapter->login_rsp_buf->off_txsubm_subcrqs));
+
index = tx_pool->free_map[tx_pool->consumer_index];
offset = index * adapter->req_mtu;
dst = tx_pool->long_term_buff.buff + offset;



[PATCH v2 net-next 09/11] ibmvnic: Continue skb processing after skb completion error

2017-05-01 Thread Nathan Fontenot
There is not a need to stop processing skbs if we encounter a
skb that has a receive completion error.

Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 2cf1b64..4b2e128 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1404,7 +1404,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int 
budget)
/* free the entry */
next->rx_comp.first = 0;
remove_buff_from_pool(adapter, rx_buff);
-   break;
+   continue;
}
 
length = be32_to_cpu(next->rx_comp.len);



  1   2   >