aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Dunning <pdunning@solarflare.com>2015-07-08 05:05:10 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-09 03:00:40 -0400
commitc936835c1ec6f871f32c9b87a7708700320075b3 (patch)
tree999f02b4bd00500bee3d131f55b30f3b1118e86d
parentd065c3c17dae95832badf6329512dd057c905890 (diff)
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: Shradha Shah <sshah@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/sfc/efx.c14
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
-rw-r--r--drivers/net/ethernet/sfc/tx.c3
3 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 804b9ad553d3..03bc03b67f08 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -245,11 +245,17 @@ static int efx_check_disabled(struct efx_nic *efx)
245 */ 245 */
246static int efx_process_channel(struct efx_channel *channel, int budget) 246static int efx_process_channel(struct efx_channel *channel, int budget)
247{ 247{
248 struct efx_tx_queue *tx_queue;
248 int spent; 249 int spent;
249 250
250 if (unlikely(!channel->enabled)) 251 if (unlikely(!channel->enabled))
251 return 0; 252 return 0;
252 253
254 efx_for_each_channel_tx_queue(tx_queue, channel) {
255 tx_queue->pkts_compl = 0;
256 tx_queue->bytes_compl = 0;
257 }
258
253 spent = efx_nic_process_eventq(channel, budget); 259 spent = efx_nic_process_eventq(channel, budget);
254 if (spent && efx_channel_has_rx_queue(channel)) { 260 if (spent && efx_channel_has_rx_queue(channel)) {
255 struct efx_rx_queue *rx_queue = 261 struct efx_rx_queue *rx_queue =
@@ -259,6 +265,14 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
259 efx_fast_push_rx_descriptors(rx_queue, true); 265 efx_fast_push_rx_descriptors(rx_queue, true);
260 } 266 }
261 267
268 /* Update BQL */
269 efx_for_each_channel_tx_queue(tx_queue, channel) {
270 if (tx_queue->bytes_compl) {
271 netdev_tx_completed_queue(tx_queue->core_txq,
272 tx_queue->pkts_compl, tx_queue->bytes_compl);
273 }
274 }
275
262 return spent; 276 return spent;
263} 277}
264 278
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index d72f522bf9c3..47d1e3a96522 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -241,6 +241,8 @@ struct efx_tx_queue {
241 unsigned int read_count ____cacheline_aligned_in_smp; 241 unsigned int read_count ____cacheline_aligned_in_smp;
242 unsigned int old_write_count; 242 unsigned int old_write_count;
243 unsigned int merge_events; 243 unsigned int merge_events;
244 unsigned int bytes_compl;
245 unsigned int pkts_compl;
244 246
245 /* Members used only on the xmit path */ 247 /* Members used only on the xmit path */
246 unsigned int insert_count ____cacheline_aligned_in_smp; 248 unsigned int insert_count ____cacheline_aligned_in_smp;
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index aaf2987512b5..1833a0146571 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -617,7 +617,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
617 EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); 617 EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask);
618 618
619 efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl); 619 efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl);
620 netdev_tx_completed_queue(tx_queue->core_txq, pkts_compl, bytes_compl); 620 tx_queue->pkts_compl += pkts_compl;
621 tx_queue->bytes_compl += bytes_compl;
621 622
622 if (pkts_compl > 1) 623 if (pkts_compl > 1)
623 ++tx_queue->merge_events; 624 ++tx_queue->merge_events;