aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Falcon <tlfalcon@linux.vnet.ibm.com>2018-04-06 19:37:05 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-08 12:39:47 -0400
commit5a18e1e0c193b2f6a8d4651f38aaabee58080647 (patch)
tree292e792573c11be8cc6a4fef9b2b5dddb11695da
parentaf894d239840908dfebb2215e13a713e63d2ffb0 (diff)
ibmvnic: Fix failover case for non-redundant configuration
There is a failover case for a non-redundant pseries VNIC configuration that was not being handled properly. The current implementation assumes that the driver will always have a redandant device to communicate with following a failover notification. There are cases, however, when a non-redundant configuration can receive a failover request. If that happens, the driver should wait until it receives a signal that the device is ready for operation. The driver is agnostic of its backing hardware configuration, so this fix necessarily affects all device failover management. The driver needs to wait until it receives a signal that the device is ready for resetting. A flag is introduced to track this intermediary state where the driver is waiting for an active device. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c37
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.h1
2 files changed, 30 insertions, 8 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index bbcd07a02694..151542e79884 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -325,10 +325,11 @@ failure:
325 adapter->replenish_add_buff_failure++; 325 adapter->replenish_add_buff_failure++;
326 atomic_add(buffers_added, &pool->available); 326 atomic_add(buffers_added, &pool->available);
327 327
328 if (lpar_rc == H_CLOSED) { 328 if (lpar_rc == H_CLOSED || adapter->failover_pending) {
329 /* Disable buffer pool replenishment and report carrier off if 329 /* Disable buffer pool replenishment and report carrier off if
330 * queue is closed. Firmware guarantees that a signal will 330 * queue is closed or pending failover.
331 * be sent to the driver, triggering a reset. 331 * Firmware guarantees that a signal will be sent to the
332 * driver, triggering a reset.
332 */ 333 */
333 deactivate_rx_pools(adapter); 334 deactivate_rx_pools(adapter);
334 netif_carrier_off(adapter->netdev); 335 netif_carrier_off(adapter->netdev);
@@ -1068,6 +1069,14 @@ static int ibmvnic_open(struct net_device *netdev)
1068 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 1069 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
1069 int rc; 1070 int rc;
1070 1071
1072 /* If device failover is pending, just set device state and return.
1073 * Device operation will be handled by reset routine.
1074 */
1075 if (adapter->failover_pending) {
1076 adapter->state = VNIC_OPEN;
1077 return 0;
1078 }
1079
1071 mutex_lock(&adapter->reset_lock); 1080 mutex_lock(&adapter->reset_lock);
1072 1081
1073 if (adapter->state != VNIC_CLOSED) { 1082 if (adapter->state != VNIC_CLOSED) {
@@ -1225,6 +1234,14 @@ static int ibmvnic_close(struct net_device *netdev)
1225 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 1234 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
1226 int rc; 1235 int rc;
1227 1236
1237 /* If device failover is pending, just set device state and return.
1238 * Device operation will be handled by reset routine.
1239 */
1240 if (adapter->failover_pending) {
1241 adapter->state = VNIC_CLOSED;
1242 return 0;
1243 }
1244
1228 mutex_lock(&adapter->reset_lock); 1245 mutex_lock(&adapter->reset_lock);
1229 rc = __ibmvnic_close(netdev); 1246 rc = __ibmvnic_close(netdev);
1230 mutex_unlock(&adapter->reset_lock); 1247 mutex_unlock(&adapter->reset_lock);
@@ -1559,8 +1576,9 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1559 dev_kfree_skb_any(skb); 1576 dev_kfree_skb_any(skb);
1560 tx_buff->skb = NULL; 1577 tx_buff->skb = NULL;
1561 1578
1562 if (lpar_rc == H_CLOSED) { 1579 if (lpar_rc == H_CLOSED || adapter->failover_pending) {
1563 /* Disable TX and report carrier off if queue is closed. 1580 /* Disable TX and report carrier off if queue is closed
1581 * or pending failover.
1564 * Firmware guarantees that a signal will be sent to the 1582 * Firmware guarantees that a signal will be sent to the
1565 * driver, triggering a reset or some other action. 1583 * driver, triggering a reset or some other action.
1566 */ 1584 */
@@ -1884,9 +1902,10 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
1884 int ret; 1902 int ret;
1885 1903
1886 if (adapter->state == VNIC_REMOVING || 1904 if (adapter->state == VNIC_REMOVING ||
1887 adapter->state == VNIC_REMOVED) { 1905 adapter->state == VNIC_REMOVED ||
1906 adapter->failover_pending) {
1888 ret = EBUSY; 1907 ret = EBUSY;
1889 netdev_dbg(netdev, "Adapter removing, skipping reset\n"); 1908 netdev_dbg(netdev, "Adapter removing or pending failover, skipping reset\n");
1890 goto err; 1909 goto err;
1891 } 1910 }
1892 1911
@@ -4162,7 +4181,9 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
4162 case IBMVNIC_CRQ_INIT: 4181 case IBMVNIC_CRQ_INIT:
4163 dev_info(dev, "Partner initialized\n"); 4182 dev_info(dev, "Partner initialized\n");
4164 adapter->from_passive_init = true; 4183 adapter->from_passive_init = true;
4184 adapter->failover_pending = false;
4165 complete(&adapter->init_done); 4185 complete(&adapter->init_done);
4186 ibmvnic_reset(adapter, VNIC_RESET_FAILOVER);
4166 break; 4187 break;
4167 case IBMVNIC_CRQ_INIT_COMPLETE: 4188 case IBMVNIC_CRQ_INIT_COMPLETE:
4168 dev_info(dev, "Partner initialization complete\n"); 4189 dev_info(dev, "Partner initialization complete\n");
@@ -4179,7 +4200,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
4179 ibmvnic_reset(adapter, VNIC_RESET_MOBILITY); 4200 ibmvnic_reset(adapter, VNIC_RESET_MOBILITY);
4180 } else if (gen_crq->cmd == IBMVNIC_DEVICE_FAILOVER) { 4201 } else if (gen_crq->cmd == IBMVNIC_DEVICE_FAILOVER) {
4181 dev_info(dev, "Backing device failover detected\n"); 4202 dev_info(dev, "Backing device failover detected\n");
4182 ibmvnic_reset(adapter, VNIC_RESET_FAILOVER); 4203 adapter->failover_pending = true;
4183 } else { 4204 } else {
4184 /* The adapter lost the connection */ 4205 /* The adapter lost the connection */
4185 dev_err(dev, "Virtual Adapter failed (rc=%d)\n", 4206 dev_err(dev, "Virtual Adapter failed (rc=%d)\n",
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index 89efe700eafe..99c0b58c2c39 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1108,6 +1108,7 @@ struct ibmvnic_adapter {
1108 bool napi_enabled, from_passive_init; 1108 bool napi_enabled, from_passive_init;
1109 1109
1110 bool mac_change_pending; 1110 bool mac_change_pending;
1111 bool failover_pending;
1111 1112
1112 struct ibmvnic_tunables desired; 1113 struct ibmvnic_tunables desired;
1113 struct ibmvnic_tunables fallback; 1114 struct ibmvnic_tunables fallback;