summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Hodgson <shodgson@solarflare.com>2011-05-23 12:18:45 +0100
committerBen Hutchings <bhutchings@solarflare.com>2012-02-16 00:25:07 +0000
commita606f4325dca6950996abbae452d33f2af095f39 (patch)
tree5d39056ca66b6be3190ff9df902eb404acc17eda
parent90893000e21e2d52a0a9d5aa0c4234c90bcd9470 (diff)
sfc: Disable flow control during flushes
The TX DMA engine issues upstream read requests when there is room in the TX FIFO for the completion. However, the fetches for the rest of the packet might be delayed by any back pressure. Since a flush must wait for an EOP, the entire flush may be delayed by back pressure. Mitigate this by disabling flow control before the flushes are started. Since PF and VF flushes run in parallel introduce fc_disable, a reference count of the number of flushes outstanding. The same principle could be applied to Falcon, but that would bring with it its own testing. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/mcdi_mac.c2
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h4
-rw-r--r--drivers/net/ethernet/sfc/nic.c3
3 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c
index f67cf921bd1..98afe1c1165 100644
--- a/drivers/net/ethernet/sfc/mcdi_mac.c
+++ b/drivers/net/ethernet/sfc/mcdi_mac.c
@@ -44,6 +44,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
}
if (efx->wanted_fc & EFX_FC_AUTO)
fcntl = MC_CMD_FCNTL_AUTO;
+ if (efx->fc_disable)
+ fcntl = MC_CMD_FCNTL_OFF;
MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 18c4b3c245e..f5268774150 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -670,6 +670,9 @@ struct efx_filter_state;
* @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
* @multicast_hash: Multicast hash table
* @wanted_fc: Wanted flow control flags
+ * @fc_disable: When non-zero flow control is disabled. Typically used to
+ * ensure that network back pressure doesn't delay dma queue flushes.
+ * Serialised by the rtnl lock.
* @mac_work: Work item for changing MAC promiscuity and multicast hash
* @loopback_mode: Loopback status
* @loopback_modes: Supported loopback mode bitmask
@@ -769,6 +772,7 @@ struct efx_nic {
bool promiscuous;
union efx_multicast_hash multicast_hash;
u8 wanted_fc;
+ unsigned fc_disable;
atomic_t rx_reset;
enum efx_loopback_mode loopback_mode;
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 539b57441e8..1bb41fff3ed 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -677,6 +677,7 @@ int efx_nic_flush_queues(struct efx_nic *efx)
struct efx_tx_queue *tx_queue;
int rc = 0;
+ efx->fc_disable++;
efx->type->prepare_flush(efx);
efx_for_each_channel(channel, efx) {
@@ -727,6 +728,8 @@ int efx_nic_flush_queues(struct efx_nic *efx)
atomic_set(&efx->rxq_flush_outstanding, 0);
}
+ efx->fc_disable--;
+
return rc;
}