Commit a606f432 authored by Steve Hodgson's avatar Steve Hodgson Committed by Ben Hutchings

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: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 90893000
...@@ -44,6 +44,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx) ...@@ -44,6 +44,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
} }
if (efx->wanted_fc & EFX_FC_AUTO) if (efx->wanted_fc & EFX_FC_AUTO)
fcntl = MC_CMD_FCNTL_AUTO; fcntl = MC_CMD_FCNTL_AUTO;
if (efx->fc_disable)
fcntl = MC_CMD_FCNTL_OFF;
MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl); MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
......
...@@ -670,6 +670,9 @@ struct efx_filter_state; ...@@ -670,6 +670,9 @@ struct efx_filter_state;
* @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
* @multicast_hash: Multicast hash table * @multicast_hash: Multicast hash table
* @wanted_fc: Wanted flow control flags * @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 * @mac_work: Work item for changing MAC promiscuity and multicast hash
* @loopback_mode: Loopback status * @loopback_mode: Loopback status
* @loopback_modes: Supported loopback mode bitmask * @loopback_modes: Supported loopback mode bitmask
...@@ -769,6 +772,7 @@ struct efx_nic { ...@@ -769,6 +772,7 @@ struct efx_nic {
bool promiscuous; bool promiscuous;
union efx_multicast_hash multicast_hash; union efx_multicast_hash multicast_hash;
u8 wanted_fc; u8 wanted_fc;
unsigned fc_disable;
atomic_t rx_reset; atomic_t rx_reset;
enum efx_loopback_mode loopback_mode; enum efx_loopback_mode loopback_mode;
......
...@@ -677,6 +677,7 @@ int efx_nic_flush_queues(struct efx_nic *efx) ...@@ -677,6 +677,7 @@ int efx_nic_flush_queues(struct efx_nic *efx)
struct efx_tx_queue *tx_queue; struct efx_tx_queue *tx_queue;
int rc = 0; int rc = 0;
efx->fc_disable++;
efx->type->prepare_flush(efx); efx->type->prepare_flush(efx);
efx_for_each_channel(channel, efx) { efx_for_each_channel(channel, efx) {
...@@ -727,6 +728,8 @@ int efx_nic_flush_queues(struct efx_nic *efx) ...@@ -727,6 +728,8 @@ int efx_nic_flush_queues(struct efx_nic *efx)
atomic_set(&efx->rxq_flush_outstanding, 0); atomic_set(&efx->rxq_flush_outstanding, 0);
} }
efx->fc_disable--;
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment