Commit d8aec745 authored by Ben Hutchings's avatar Ben Hutchings
Browse files

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: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 1840667a
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -248,7 +248,6 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
			efx_channel_get_rx_queue(channel);

		efx_rx_flush_packet(channel);
		if (rx_queue->enabled)
		efx_fast_push_rx_descriptors(rx_queue);
	}

@@ -647,6 +646,12 @@ static void efx_stop_datapath(struct efx_nic *efx)
	EFX_ASSERT_RESET_SERIALISED(efx);
	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 */
	if (dev->is_busmaster && efx->state != STATE_RECOVERY) {
		rc = efx_nic_flush_queues(efx);
+2 −2
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ struct efx_rx_page_state {
 * @buffer: The software buffer ring
 * @rxd: The hardware descriptor ring
 * @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
 *	@rxq_flush_pending.
 * @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_special_buffer rxd;
	unsigned int ptr_mask;
	bool enabled;
	bool refill_enabled;
	bool flush_pending;

	unsigned int added_count;
+0 −1
Original line number Diff line number Diff line
@@ -1204,7 +1204,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
		 * queue. Refill it here */
		efx_fast_push_rx_descriptors(rx_queue);
	} else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) {
		rx_queue->enabled = false;
		efx_handle_drain_event(channel);
	} else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) {
		efx_handle_drain_event(channel);
+4 −4
Original line number Diff line number Diff line
@@ -326,6 +326,9 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
	unsigned int fill_level, batch_size;
	int space, rc = 0;

	if (!rx_queue->refill_enabled)
		return;

	/* Calculate current fill level, and exit if we don't need to fill */
	fill_level = (rx_queue->added_count - rx_queue->removed_count);
	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->fast_fill_trigger = trigger;
	rx_queue->refill_enabled = true;

	/* Set up RX descriptor ring */
	rx_queue->enabled = true;
	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,
		  "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);
	efx_nic_fini_rx(rx_queue);