sfc: Maintain interrupt moderation values in ticks, not microseconds

This simplifies the implementation a lot.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ben Hutchings 2009-10-23 08:32:13 +00:00 committed by David S. Miller
parent 0484e0db7c
commit 0d86ebd815
4 changed files with 28 additions and 34 deletions

View File

@ -228,26 +228,20 @@ static int efx_poll(struct napi_struct *napi, int budget)
if (channel->used_flags & EFX_USED_BY_RX &&
efx->irq_rx_adaptive &&
unlikely(++channel->irq_count == 1000)) {
unsigned old_irq_moderation = channel->irq_moderation;
if (unlikely(channel->irq_mod_score <
irq_adapt_low_thresh)) {
channel->irq_moderation =
max_t(int,
channel->irq_moderation -
FALCON_IRQ_MOD_RESOLUTION,
FALCON_IRQ_MOD_RESOLUTION);
if (channel->irq_moderation > 1) {
channel->irq_moderation -= 1;
falcon_set_int_moderation(channel);
}
} else if (unlikely(channel->irq_mod_score >
irq_adapt_high_thresh)) {
channel->irq_moderation =
min(channel->irq_moderation +
FALCON_IRQ_MOD_RESOLUTION,
efx->irq_rx_moderation);
if (channel->irq_moderation <
efx->irq_rx_moderation) {
channel->irq_moderation += 1;
falcon_set_int_moderation(channel);
}
}
if (channel->irq_moderation != old_irq_moderation)
falcon_set_int_moderation(channel);
channel->irq_count = 0;
channel->irq_mod_score = 0;
}
@ -1220,22 +1214,33 @@ void efx_flush_queues(struct efx_nic *efx)
*
**************************************************************************/
static unsigned irq_mod_ticks(int usecs, int resolution)
{
if (usecs <= 0)
return 0; /* cannot receive interrupts ahead of time :-) */
if (usecs < resolution)
return 1; /* never round down to 0 */
return usecs / resolution;
}
/* Set interrupt moderation parameters */
void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
bool rx_adaptive)
{
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
unsigned tx_ticks = irq_mod_ticks(tx_usecs, FALCON_IRQ_MOD_RESOLUTION);
unsigned rx_ticks = irq_mod_ticks(rx_usecs, FALCON_IRQ_MOD_RESOLUTION);
EFX_ASSERT_RESET_SERIALISED(efx);
efx_for_each_tx_queue(tx_queue, efx)
tx_queue->channel->irq_moderation = tx_usecs;
tx_queue->channel->irq_moderation = tx_ticks;
efx->irq_rx_adaptive = rx_adaptive;
efx->irq_rx_moderation = rx_usecs;
efx->irq_rx_moderation = rx_ticks;
efx_for_each_rx_queue(rx_queue, efx)
rx_queue->channel->irq_moderation = rx_usecs;
rx_queue->channel->irq_moderation = rx_ticks;
}
/**************************************************************************

View File

@ -618,6 +618,9 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
coalesce->tx_coalesce_usecs_irq *= FALCON_IRQ_MOD_RESOLUTION;
coalesce->rx_coalesce_usecs_irq *= FALCON_IRQ_MOD_RESOLUTION;
return 0;
}
@ -656,11 +659,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
}
efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive);
/* Reset channel to pick up new moderation value. Note that
* this may change the value of the irq_moderation field
* (e.g. to allow for hardware timer granularity).
*/
efx_for_each_channel(channel, efx)
falcon_set_int_moderation(channel);

View File

@ -1063,20 +1063,11 @@ void falcon_set_int_moderation(struct efx_channel *channel)
/* Set timer register */
if (channel->irq_moderation) {
/* Round to resolution supported by hardware. The value we
* program is based at 0. So actual interrupt moderation
* achieved is ((x + 1) * res).
*/
channel->irq_moderation -= (channel->irq_moderation %
FALCON_IRQ_MOD_RESOLUTION);
if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION)
channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION;
EFX_POPULATE_DWORD_2(timer_cmd,
FRF_AB_TC_TIMER_MODE,
FFE_BB_TIMER_MODE_INT_HLDOFF,
FRF_AB_TC_TIMER_VAL,
channel->irq_moderation /
FALCON_IRQ_MOD_RESOLUTION - 1);
channel->irq_moderation - 1);
} else {
EFX_POPULATE_DWORD_2(timer_cmd,
FRF_AB_TC_TIMER_MODE,

View File

@ -327,7 +327,7 @@ enum efx_rx_alloc_method {
* @used_flags: Channel is used by net driver
* @enabled: Channel enabled indicator
* @irq: IRQ number (MSI and MSI-X only)
* @irq_moderation: IRQ moderation value (in us)
* @irq_moderation: IRQ moderation value (in hardware ticks)
* @napi_dev: Net device used with NAPI
* @napi_str: NAPI control structure
* @reset_work: Scheduled reset work thread