| From fdf4f75f02430df3b77fad6d886ecc02cfeb76b2 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 29 Oct 2021 15:03:14 -0700 |
| Subject: ibmvnic: don't stop queue in xmit |
| |
| From: Sukadev Bhattiprolu <sukadev@linux.ibm.com> |
| |
| [ Upstream commit 8878e46fcfd46b19964bd90e13b25dd94cbfc9be ] |
| |
| If adapter's resetting bit is on, discard the packet but don't stop the |
| transmit queue - instead leave that to the reset code. With this change, |
| it is possible that we may get several calls to ibmvnic_xmit() that simply |
| discard packets and return. |
| |
| But if we stop the queue here, we might end up doing so just after |
| __ibmvnic_open() started the queues (during a hard/soft reset) and before |
| the ->resetting bit was cleared. If that happens, there will be no one to |
| restart queue and transmissions will be blocked indefinitely. |
| |
| This can cause a TIMEOUT reset and with auto priority failover enabled, |
| an unnecessary FAILOVER reset to less favored backing device and then a |
| FAILOVER back to the most favored backing device. If we hit the window |
| repeatedly, we can get stuck in a loop of TIMEOUT, FAILOVER, FAILOVER |
| resets leaving the adapter unusable for extended periods of time. |
| |
| Fixes: 7f5b030830fe ("ibmvnic: Free skb's in cases of failure in transmit") |
| Reported-by: Abdul Haleem <abdhalee@in.ibm.com> |
| Reported-by: Vaishnavi Bhat <vaish123@in.ibm.com> |
| Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com> |
| Reviewed-by: Dany Madden <drt@linux.ibm.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/ibm/ibmvnic.c | 2 -- |
| 1 file changed, 2 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c |
| index cfe7229593ead..059eaa13e2c6d 100644 |
| --- a/drivers/net/ethernet/ibm/ibmvnic.c |
| +++ b/drivers/net/ethernet/ibm/ibmvnic.c |
| @@ -1462,8 +1462,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) |
| netdev_tx_t ret = NETDEV_TX_OK; |
| |
| if (test_bit(0, &adapter->resetting)) { |
| - if (!netif_subqueue_stopped(netdev, skb)) |
| - netif_stop_subqueue(netdev, queue_num); |
| dev_kfree_skb_any(skb); |
| |
| tx_send_failed++; |
| -- |
| 2.33.0 |
| |