aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cavium/liquidio/lio_main.c
diff options
context:
space:
mode:
authorRaghu Vatsavayi <raghu.vatsavayi@cavium.com>2018-03-29 11:13:22 -0700
committerDavid S. Miller <davem@davemloft.net>2018-03-30 14:16:19 -0400
commitccdd0b4c35f2adb7434ed69a89bc68bb6e9089ea (patch)
treedc0a8e01b3a7cedf17724aff50ad049a220ee3af /drivers/net/ethernet/cavium/liquidio/lio_main.c
parentMerge branch 'ieee802154-for-davem-2018-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next (diff)
downloadlinux-dev-ccdd0b4c35f2adb7434ed69a89bc68bb6e9089ea.tar.xz
linux-dev-ccdd0b4c35f2adb7434ed69a89bc68bb6e9089ea.zip
liquidio: prevent rx queues from getting stalled
This commit has fix for RX traffic issues when we stress test the driver with continuous ifconfig up/down under very high traffic conditions. Reason for the issue is that, in existing liquidio_stop function NAPI is disabled even before actual FW/HW interface is brought down via send_rx_ctrl_cmd(lio, 0). Between time frame of NAPI disable and actual interface down in firmware, firmware continuously enqueues rx traffic to host. When interrupt happens for new packets, host irq handler fails in scheduling NAPI as the NAPI is already disabled. After "ifconfig <iface> up", Host re-enables NAPI but cannot schedule it until it receives another Rx interrupt. Host never receives Rx interrupt as it never cleared the Rx interrupt it received during interface down operation. NIC Rx interrupt gets cleared only when Host processes queue and clears the queue counts. Above anomaly leads to other issues like packet overflow in FW/HW queues, backpressure. Fix: This commit fixes this issue by disabling NAPI only after informing firmware to stop queueing packets to host via send_rx_ctrl_cmd(lio, 0). send_rx_ctrl_cmd is not visible in the patch as it is already there in the code. The DOWN command also waits for any pending packets to be processed by NAPI so that the deadlock will not occur. Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@cavium.com> Acked-by: Derek Chickles <derek.chickles@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/lio_main.c')
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 43c5ba0af12b..603a144d3d9c 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2084,16 +2084,6 @@ static int liquidio_stop(struct net_device *netdev)
struct octeon_device *oct = lio->oct_dev;
struct napi_struct *napi, *n;
- if (oct->props[lio->ifidx].napi_enabled) {
- list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
- napi_disable(napi);
-
- oct->props[lio->ifidx].napi_enabled = 0;
-
- if (OCTEON_CN23XX_PF(oct))
- oct->droq[0]->ops.poll_mode = 0;
- }
-
ifstate_reset(lio, LIO_IFSTATE_RUNNING);
netif_tx_disable(netdev);
@@ -2119,6 +2109,21 @@ static int liquidio_stop(struct net_device *netdev)
lio->ptp_clock = NULL;
}
+ /* Wait for any pending Rx descriptors */
+ if (lio_wait_for_clean_oq(oct))
+ netif_info(lio, rx_err, lio->netdev,
+ "Proceeding with stop interface after partial RX desc processing\n");
+
+ if (oct->props[lio->ifidx].napi_enabled == 1) {
+ list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
+ napi_disable(napi);
+
+ oct->props[lio->ifidx].napi_enabled = 0;
+
+ if (OCTEON_CN23XX_PF(oct))
+ oct->droq[0]->ops.poll_mode = 0;
+ }
+
dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
return 0;