diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-05-23 12:18:45 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-28 12:06:00 -0700 |
commit | 442933f2b6a4c0e1d4a3b216c55c720a01c032be (patch) | |
tree | 16b635eac56c1bfead31ab1df1d61d4f4e5ae8cb /drivers/net/sfc/net_driver.h | |
parent | 886033e132d6d83d6e7738e3edcd1598a7b66cf0 (diff) |
sfc: Fix two causes of flush failure
[ Upstream commits a606f4325dca6950996abbae452d33f2af095f39,
d5e8cc6c946e0857826dcfbb3585068858445bfe,
525d9e824018cd7cc8d8d44832ddcd363abfe6e1 ]
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.
We sometimes hit a "failed to flush" timeout on some TX queues, but the
flushes have completed and the flush completion events seem to go missing.
In this case, we can check the TX_DESC_PTR_TBL register and drain the
queues if the flushes had finished.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
[bwh: Backported to 3.0:
- Call efx_nic_type::finish_flush() on both success and failure paths
- Check the TX_DESC_PTR_TBL registers in the polling loop
- Declare efx_mcdi_set_mac() extern]
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/sfc/net_driver.h')
-rw-r--r-- | drivers/net/sfc/net_driver.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e8d5f03a89f..47aff8ec720 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -690,6 +690,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 @@ -783,6 +786,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; @@ -834,6 +838,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @remove_port: Free resources allocated by probe_port() * @handle_global_event: Handle a "global" event (may be %NULL) * @prepare_flush: Prepare the hardware for flushing the DMA queues + * @finish_flush: Clean up after flushing the DMA queues * @update_stats: Update statistics not provided by event handling * @start_stats: Start the regular fetching of statistics * @stop_stats: Stop the regular fetching of statistics @@ -879,6 +884,7 @@ struct efx_nic_type { void (*remove_port)(struct efx_nic *efx); bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *); void (*prepare_flush)(struct efx_nic *efx); + void (*finish_flush)(struct efx_nic *efx); void (*update_stats)(struct efx_nic *efx); void (*start_stats)(struct efx_nic *efx); void (*stop_stats)(struct efx_nic *efx); |