aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-03-20 09:30:37 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-21 22:06:58 -0400
commit6fb70fd1b57707a5c7b9fb167b7790b2cba13f04 (patch)
tree311192bd4de07e1da571f1a6ac6a3ad123ab3f50 /drivers/net/sfc/efx.c
parent85451a951b9511605475fadcc0a8d3aeccefded8 (diff)
sfc: Implement adaptive IRQ moderation
Calculate a score for each 1000 IRQs: - TX completions are worth 1 point - RX completions are worth 4 if merged using LRO or 2 otherwise Reduce moderation if the score is less than 10000, down to a minimum of 5 us. Increase moderation if the score is more than 20000, up to the specified maximum. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 8fa68d82c022..6eff9ca6c6c8 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -133,6 +133,16 @@ static int phy_flash_cfg;
133module_param(phy_flash_cfg, int, 0644); 133module_param(phy_flash_cfg, int, 0644);
134MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially"); 134MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially");
135 135
136static unsigned irq_adapt_low_thresh = 10000;
137module_param(irq_adapt_low_thresh, uint, 0644);
138MODULE_PARM_DESC(irq_adapt_low_thresh,
139 "Threshold score for reducing IRQ moderation");
140
141static unsigned irq_adapt_high_thresh = 20000;
142module_param(irq_adapt_high_thresh, uint, 0644);
143MODULE_PARM_DESC(irq_adapt_high_thresh,
144 "Threshold score for increasing IRQ moderation");
145
136/************************************************************************** 146/**************************************************************************
137 * 147 *
138 * Utility functions and prototypes 148 * Utility functions and prototypes
@@ -223,6 +233,35 @@ static int efx_poll(struct napi_struct *napi, int budget)
223 rx_packets = efx_process_channel(channel, budget); 233 rx_packets = efx_process_channel(channel, budget);
224 234
225 if (rx_packets < budget) { 235 if (rx_packets < budget) {
236 struct efx_nic *efx = channel->efx;
237
238 if (channel->used_flags & EFX_USED_BY_RX &&
239 efx->irq_rx_adaptive &&
240 unlikely(++channel->irq_count == 1000)) {
241 unsigned old_irq_moderation = channel->irq_moderation;
242
243 if (unlikely(channel->irq_mod_score <
244 irq_adapt_low_thresh)) {
245 channel->irq_moderation =
246 max_t(int,
247 channel->irq_moderation -
248 FALCON_IRQ_MOD_RESOLUTION,
249 FALCON_IRQ_MOD_RESOLUTION);
250 } else if (unlikely(channel->irq_mod_score >
251 irq_adapt_high_thresh)) {
252 channel->irq_moderation =
253 min(channel->irq_moderation +
254 FALCON_IRQ_MOD_RESOLUTION,
255 efx->irq_rx_moderation);
256 }
257
258 if (channel->irq_moderation != old_irq_moderation)
259 falcon_set_int_moderation(channel);
260
261 channel->irq_count = 0;
262 channel->irq_mod_score = 0;
263 }
264
226 /* There is no race here; although napi_disable() will 265 /* There is no race here; although napi_disable() will
227 * only wait for napi_complete(), this isn't a problem 266 * only wait for napi_complete(), this isn't a problem
228 * since efx_channel_processed() will have no effect if 267 * since efx_channel_processed() will have no effect if
@@ -991,7 +1030,7 @@ static int efx_probe_nic(struct efx_nic *efx)
991 efx_set_channels(efx); 1030 efx_set_channels(efx);
992 1031
993 /* Initialise the interrupt moderation settings */ 1032 /* Initialise the interrupt moderation settings */
994 efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec); 1033 efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
995 1034
996 return 0; 1035 return 0;
997} 1036}
@@ -1188,7 +1227,8 @@ void efx_flush_queues(struct efx_nic *efx)
1188 **************************************************************************/ 1227 **************************************************************************/
1189 1228
1190/* Set interrupt moderation parameters */ 1229/* Set interrupt moderation parameters */
1191void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs) 1230void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
1231 bool rx_adaptive)
1192{ 1232{
1193 struct efx_tx_queue *tx_queue; 1233 struct efx_tx_queue *tx_queue;
1194 struct efx_rx_queue *rx_queue; 1234 struct efx_rx_queue *rx_queue;
@@ -1198,6 +1238,8 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
1198 efx_for_each_tx_queue(tx_queue, efx) 1238 efx_for_each_tx_queue(tx_queue, efx)
1199 tx_queue->channel->irq_moderation = tx_usecs; 1239 tx_queue->channel->irq_moderation = tx_usecs;
1200 1240
1241 efx->irq_rx_adaptive = rx_adaptive;
1242 efx->irq_rx_moderation = rx_usecs;
1201 efx_for_each_rx_queue(rx_queue, efx) 1243 efx_for_each_rx_queue(rx_queue, efx)
1202 rx_queue->channel->irq_moderation = rx_usecs; 1244 rx_queue->channel->irq_moderation = rx_usecs;
1203} 1245}