sfc: Stop RX refill before flushing RX queues

rx_queue::enabled guards refill, so rename it to reflect that.  Clear
it at the start of the queue teardown process rather than waiting for
the RX queue to be flushed.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
Ben Hutchings 2013-05-27 16:52:54 +01:00
parent 1840667a85
commit d8aec745dd
4 changed files with 13 additions and 9 deletions

View File

@ -248,8 +248,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
efx_channel_get_rx_queue(channel); efx_channel_get_rx_queue(channel);
efx_rx_flush_packet(channel); efx_rx_flush_packet(channel);
if (rx_queue->enabled) efx_fast_push_rx_descriptors(rx_queue);
efx_fast_push_rx_descriptors(rx_queue);
} }
return spent; return spent;
@ -647,6 +646,12 @@ static void efx_stop_datapath(struct efx_nic *efx)
EFX_ASSERT_RESET_SERIALISED(efx); EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled); BUG_ON(efx->port_enabled);
/* Stop RX refill */
efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel)
rx_queue->refill_enabled = false;
}
/* Only perform flush if dma is enabled */ /* Only perform flush if dma is enabled */
if (dev->is_busmaster && efx->state != STATE_RECOVERY) { if (dev->is_busmaster && efx->state != STATE_RECOVERY) {
rc = efx_nic_flush_queues(efx); rc = efx_nic_flush_queues(efx);

View File

@ -286,7 +286,7 @@ struct efx_rx_page_state {
* @buffer: The software buffer ring * @buffer: The software buffer ring
* @rxd: The hardware descriptor ring * @rxd: The hardware descriptor ring
* @ptr_mask: The size of the ring minus 1. * @ptr_mask: The size of the ring minus 1.
* @enabled: Receive queue enabled indicator. * @refill_enabled: Enable refill whenever fill level is low
* @flush_pending: Set when a RX flush is pending. Has the same lifetime as * @flush_pending: Set when a RX flush is pending. Has the same lifetime as
* @rxq_flush_pending. * @rxq_flush_pending.
* @added_count: Number of buffers added to the receive queue. * @added_count: Number of buffers added to the receive queue.
@ -317,7 +317,7 @@ struct efx_rx_queue {
struct efx_rx_buffer *buffer; struct efx_rx_buffer *buffer;
struct efx_special_buffer rxd; struct efx_special_buffer rxd;
unsigned int ptr_mask; unsigned int ptr_mask;
bool enabled; bool refill_enabled;
bool flush_pending; bool flush_pending;
unsigned int added_count; unsigned int added_count;

View File

@ -1204,7 +1204,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
* queue. Refill it here */ * queue. Refill it here */
efx_fast_push_rx_descriptors(rx_queue); efx_fast_push_rx_descriptors(rx_queue);
} else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) { } else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) {
rx_queue->enabled = false;
efx_handle_drain_event(channel); efx_handle_drain_event(channel);
} else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) { } else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) {
efx_handle_drain_event(channel); efx_handle_drain_event(channel);

View File

@ -326,6 +326,9 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
unsigned int fill_level, batch_size; unsigned int fill_level, batch_size;
int space, rc = 0; int space, rc = 0;
if (!rx_queue->refill_enabled)
return;
/* Calculate current fill level, and exit if we don't need to fill */ /* Calculate current fill level, and exit if we don't need to fill */
fill_level = (rx_queue->added_count - rx_queue->removed_count); fill_level = (rx_queue->added_count - rx_queue->removed_count);
EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries);
@ -738,9 +741,9 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
rx_queue->max_fill = max_fill; rx_queue->max_fill = max_fill;
rx_queue->fast_fill_trigger = trigger; rx_queue->fast_fill_trigger = trigger;
rx_queue->refill_enabled = true;
/* Set up RX descriptor ring */ /* Set up RX descriptor ring */
rx_queue->enabled = true;
efx_nic_init_rx(rx_queue); efx_nic_init_rx(rx_queue);
} }
@ -753,9 +756,6 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
/* A flush failure might have left rx_queue->enabled */
rx_queue->enabled = false;
del_timer_sync(&rx_queue->slow_fill); del_timer_sync(&rx_queue->slow_fill);
efx_nic_fini_rx(rx_queue); efx_nic_fini_rx(rx_queue);