Commit c936835c authored by Peter Dunning's avatar Peter Dunning Committed by David S. Miller

sfc: Report TX completions to BQL after all TX events in interrupt

The limit for BQL is updated each time we call
netdev_tx_completed_queue.
Without this patch the BQL limit was updated for every TX event we
see.
The issue was that this only updated the limit to handle the data
we complete in two events as the first event wouldn't show that
enough traffic had been processed between them.

This was OK when interrupt moderation was off but not when it was
on as more data had to be completed in a single interrupt.

The patch changes this so that we do report the completion to BQL
only when all the TX events in the interrupt have been processed.
Signed-off-by: default avatarShradha Shah <sshah@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d065c3c1
...@@ -245,11 +245,17 @@ static int efx_check_disabled(struct efx_nic *efx) ...@@ -245,11 +245,17 @@ static int efx_check_disabled(struct efx_nic *efx)
*/ */
static int efx_process_channel(struct efx_channel *channel, int budget) static int efx_process_channel(struct efx_channel *channel, int budget)
{ {
struct efx_tx_queue *tx_queue;
int spent; int spent;
if (unlikely(!channel->enabled)) if (unlikely(!channel->enabled))
return 0; return 0;
efx_for_each_channel_tx_queue(tx_queue, channel) {
tx_queue->pkts_compl = 0;
tx_queue->bytes_compl = 0;
}
spent = efx_nic_process_eventq(channel, budget); spent = efx_nic_process_eventq(channel, budget);
if (spent && efx_channel_has_rx_queue(channel)) { if (spent && efx_channel_has_rx_queue(channel)) {
struct efx_rx_queue *rx_queue = struct efx_rx_queue *rx_queue =
...@@ -259,6 +265,14 @@ static int efx_process_channel(struct efx_channel *channel, int budget) ...@@ -259,6 +265,14 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
efx_fast_push_rx_descriptors(rx_queue, true); efx_fast_push_rx_descriptors(rx_queue, true);
} }
/* Update BQL */
efx_for_each_channel_tx_queue(tx_queue, channel) {
if (tx_queue->bytes_compl) {
netdev_tx_completed_queue(tx_queue->core_txq,
tx_queue->pkts_compl, tx_queue->bytes_compl);
}
}
return spent; return spent;
} }
......
...@@ -241,6 +241,8 @@ struct efx_tx_queue { ...@@ -241,6 +241,8 @@ struct efx_tx_queue {
unsigned int read_count ____cacheline_aligned_in_smp; unsigned int read_count ____cacheline_aligned_in_smp;
unsigned int old_write_count; unsigned int old_write_count;
unsigned int merge_events; unsigned int merge_events;
unsigned int bytes_compl;
unsigned int pkts_compl;
/* Members used only on the xmit path */ /* Members used only on the xmit path */
unsigned int insert_count ____cacheline_aligned_in_smp; unsigned int insert_count ____cacheline_aligned_in_smp;
......
...@@ -617,7 +617,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) ...@@ -617,7 +617,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask);
efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl); efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl);
netdev_tx_completed_queue(tx_queue->core_txq, pkts_compl, bytes_compl); tx_queue->pkts_compl += pkts_compl;
tx_queue->bytes_compl += bytes_compl;
if (pkts_compl > 1) if (pkts_compl > 1)
++tx_queue->merge_events; ++tx_queue->merge_events;
......
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