提交 3881d8ab 编写于 作者: A Alexandre Rames 提交者: Ben Hutchings

sfc: Use a global count of active queues instead of pending drains

On EF10, the firmware will initiate a queue flush in certain
error cases.  We need to accept that flush events might appear
at any time after a queue has been initialised, not just when
we try to flush them.

We can handle Falcon-architecture in just the same way.
Signed-off-by: NBen Hutchings <bhutchings@solarflare.com>
上级 e8c68c0a
...@@ -631,11 +631,14 @@ static void efx_start_datapath(struct efx_nic *efx) ...@@ -631,11 +631,14 @@ static void efx_start_datapath(struct efx_nic *efx)
/* Initialise the channels */ /* Initialise the channels */
efx_for_each_channel(channel, efx) { efx_for_each_channel(channel, efx) {
efx_for_each_channel_tx_queue(tx_queue, channel) efx_for_each_channel_tx_queue(tx_queue, channel) {
efx_init_tx_queue(tx_queue); efx_init_tx_queue(tx_queue);
atomic_inc(&efx->active_queues);
}
efx_for_each_channel_rx_queue(rx_queue, channel) { efx_for_each_channel_rx_queue(rx_queue, channel) {
efx_init_rx_queue(rx_queue); efx_init_rx_queue(rx_queue);
atomic_inc(&efx->active_queues);
efx_nic_generate_fill_event(rx_queue); efx_nic_generate_fill_event(rx_queue);
} }
......
...@@ -594,7 +594,7 @@ static bool efx_farch_flush_wake(struct efx_nic *efx) ...@@ -594,7 +594,7 @@ static bool efx_farch_flush_wake(struct efx_nic *efx)
/* Ensure that all updates are visible to efx_farch_flush_queues() */ /* Ensure that all updates are visible to efx_farch_flush_queues() */
smp_mb(); smp_mb();
return (atomic_read(&efx->drain_pending) == 0 || return (atomic_read(&efx->active_queues) == 0 ||
(atomic_read(&efx->rxq_flush_outstanding) < EFX_RX_FLUSH_COUNT (atomic_read(&efx->rxq_flush_outstanding) < EFX_RX_FLUSH_COUNT
&& atomic_read(&efx->rxq_flush_pending) > 0)); && atomic_read(&efx->rxq_flush_pending) > 0));
} }
...@@ -626,7 +626,7 @@ static bool efx_check_tx_flush_complete(struct efx_nic *efx) ...@@ -626,7 +626,7 @@ static bool efx_check_tx_flush_complete(struct efx_nic *efx)
netif_dbg(efx, hw, efx->net_dev, netif_dbg(efx, hw, efx->net_dev,
"flush complete on TXQ %d, so drain " "flush complete on TXQ %d, so drain "
"the queue\n", tx_queue->queue); "the queue\n", tx_queue->queue);
/* Don't need to increment drain_pending as it /* Don't need to increment active_queues as it
* has already been incremented for the queues * has already been incremented for the queues
* which did not drain * which did not drain
*/ */
...@@ -653,17 +653,15 @@ static int efx_farch_do_flush(struct efx_nic *efx) ...@@ -653,17 +653,15 @@ static int efx_farch_do_flush(struct efx_nic *efx)
efx_for_each_channel(channel, efx) { efx_for_each_channel(channel, efx) {
efx_for_each_channel_tx_queue(tx_queue, channel) { efx_for_each_channel_tx_queue(tx_queue, channel) {
atomic_inc(&efx->drain_pending);
efx_farch_flush_tx_queue(tx_queue); efx_farch_flush_tx_queue(tx_queue);
} }
efx_for_each_channel_rx_queue(rx_queue, channel) { efx_for_each_channel_rx_queue(rx_queue, channel) {
atomic_inc(&efx->drain_pending);
rx_queue->flush_pending = true; rx_queue->flush_pending = true;
atomic_inc(&efx->rxq_flush_pending); atomic_inc(&efx->rxq_flush_pending);
} }
} }
while (timeout && atomic_read(&efx->drain_pending) > 0) { while (timeout && atomic_read(&efx->active_queues) > 0) {
/* If SRIOV is enabled, then offload receive queue flushing to /* If SRIOV is enabled, then offload receive queue flushing to
* the firmware (though we will still have to poll for * the firmware (though we will still have to poll for
* completion). If that fails, fall back to the old scheme. * completion). If that fails, fall back to the old scheme.
...@@ -699,15 +697,15 @@ static int efx_farch_do_flush(struct efx_nic *efx) ...@@ -699,15 +697,15 @@ static int efx_farch_do_flush(struct efx_nic *efx)
timeout); timeout);
} }
if (atomic_read(&efx->drain_pending) && if (atomic_read(&efx->active_queues) &&
!efx_check_tx_flush_complete(efx)) { !efx_check_tx_flush_complete(efx)) {
netif_err(efx, hw, efx->net_dev, "failed to flush %d queues " netif_err(efx, hw, efx->net_dev, "failed to flush %d queues "
"(rx %d+%d)\n", atomic_read(&efx->drain_pending), "(rx %d+%d)\n", atomic_read(&efx->active_queues),
atomic_read(&efx->rxq_flush_outstanding), atomic_read(&efx->rxq_flush_outstanding),
atomic_read(&efx->rxq_flush_pending)); atomic_read(&efx->rxq_flush_pending));
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
atomic_set(&efx->drain_pending, 0); atomic_set(&efx->active_queues, 0);
atomic_set(&efx->rxq_flush_pending, 0); atomic_set(&efx->rxq_flush_pending, 0);
atomic_set(&efx->rxq_flush_outstanding, 0); atomic_set(&efx->rxq_flush_outstanding, 0);
} }
...@@ -1123,8 +1121,8 @@ efx_farch_handle_drain_event(struct efx_channel *channel) ...@@ -1123,8 +1121,8 @@ efx_farch_handle_drain_event(struct efx_channel *channel)
{ {
struct efx_nic *efx = channel->efx; struct efx_nic *efx = channel->efx;
WARN_ON(atomic_read(&efx->drain_pending) == 0); WARN_ON(atomic_read(&efx->active_queues) == 0);
atomic_dec(&efx->drain_pending); atomic_dec(&efx->active_queues);
if (efx_farch_flush_wake(efx)) if (efx_farch_flush_wake(efx))
wake_up(&efx->flush_wq); wake_up(&efx->flush_wq);
} }
......
...@@ -723,7 +723,7 @@ struct vfdi_status; ...@@ -723,7 +723,7 @@ struct vfdi_status;
* @rps_flow_id: Flow IDs of filters allocated for accelerated RFS, * @rps_flow_id: Flow IDs of filters allocated for accelerated RFS,
* indexed by filter ID * indexed by filter ID
* @rps_expire_index: Next index to check for expiry in @rps_flow_id * @rps_expire_index: Next index to check for expiry in @rps_flow_id
* @drain_pending: Count of RX and TX queues that haven't been flushed and drained. * @active_queues: Count of RX and TX queues that haven't been flushed and drained.
* @rxq_flush_pending: Count of number of receive queues that need to be flushed. * @rxq_flush_pending: Count of number of receive queues that need to be flushed.
* Decremented when the efx_flush_rx_queue() is called. * Decremented when the efx_flush_rx_queue() is called.
* @rxq_flush_outstanding: Count of number of RX flushes started but not yet * @rxq_flush_outstanding: Count of number of RX flushes started but not yet
...@@ -864,7 +864,7 @@ struct efx_nic { ...@@ -864,7 +864,7 @@ struct efx_nic {
unsigned int rps_expire_index; unsigned int rps_expire_index;
#endif #endif
atomic_t drain_pending; atomic_t active_queues;
atomic_t rxq_flush_pending; atomic_t rxq_flush_pending;
atomic_t rxq_flush_outstanding; atomic_t rxq_flush_outstanding;
wait_queue_head_t flush_wq; wait_queue_head_t flush_wq;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册