Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d86ebd8 authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller
Browse files

sfc: Maintain interrupt moderation values in ticks, not microseconds



This simplifies the implementation a lot.

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0484e0db
Loading
Loading
Loading
Loading
+23 −18
Original line number Original line Diff line number Diff line
@@ -228,26 +228,20 @@ static int efx_poll(struct napi_struct *napi, int budget)
		if (channel->used_flags & EFX_USED_BY_RX &&
		if (channel->used_flags & EFX_USED_BY_RX &&
		    efx->irq_rx_adaptive &&
		    efx->irq_rx_adaptive &&
		    unlikely(++channel->irq_count == 1000)) {
		    unlikely(++channel->irq_count == 1000)) {
			unsigned old_irq_moderation = channel->irq_moderation;

			if (unlikely(channel->irq_mod_score <
			if (unlikely(channel->irq_mod_score <
				     irq_adapt_low_thresh)) {
				     irq_adapt_low_thresh)) {
				channel->irq_moderation =
				if (channel->irq_moderation > 1) {
					max_t(int,
					channel->irq_moderation -= 1;
					      channel->irq_moderation -
					falcon_set_int_moderation(channel);
					      FALCON_IRQ_MOD_RESOLUTION,
				}
					      FALCON_IRQ_MOD_RESOLUTION);
			} else if (unlikely(channel->irq_mod_score >
			} else if (unlikely(channel->irq_mod_score >
					    irq_adapt_high_thresh)) {
					    irq_adapt_high_thresh)) {
				channel->irq_moderation =
				if (channel->irq_moderation <
					min(channel->irq_moderation +
				    efx->irq_rx_moderation) {
					    FALCON_IRQ_MOD_RESOLUTION,
					channel->irq_moderation += 1;
					    efx->irq_rx_moderation);
			}

			if (channel->irq_moderation != old_irq_moderation)
					falcon_set_int_moderation(channel);
					falcon_set_int_moderation(channel);

				}
			}
			channel->irq_count = 0;
			channel->irq_count = 0;
			channel->irq_mod_score = 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 */
/* Set interrupt moderation parameters */
void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
			     bool rx_adaptive)
			     bool rx_adaptive)
{
{
	struct efx_tx_queue *tx_queue;
	struct efx_tx_queue *tx_queue;
	struct efx_rx_queue *rx_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_ASSERT_RESET_SERIALISED(efx);


	efx_for_each_tx_queue(tx_queue, 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_adaptive = rx_adaptive;
	efx->irq_rx_moderation = rx_usecs;
	efx->irq_rx_moderation = rx_ticks;
	efx_for_each_rx_queue(rx_queue, efx)
	efx_for_each_rx_queue(rx_queue, efx)
		rx_queue->channel->irq_moderation = rx_usecs;
		rx_queue->channel->irq_moderation = rx_ticks;
}
}


/**************************************************************************
/**************************************************************************
+3 −5
Original line number Original line Diff line number Diff line
@@ -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->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
	coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
	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;
	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);
	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)
	efx_for_each_channel(channel, efx)
		falcon_set_int_moderation(channel);
		falcon_set_int_moderation(channel);


+1 −10
Original line number Original line Diff line number Diff line
@@ -1063,20 +1063,11 @@ void falcon_set_int_moderation(struct efx_channel *channel)


	/* Set timer register */
	/* Set timer register */
	if (channel->irq_moderation) {
	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,
		EFX_POPULATE_DWORD_2(timer_cmd,
				     FRF_AB_TC_TIMER_MODE,
				     FRF_AB_TC_TIMER_MODE,
				     FFE_BB_TIMER_MODE_INT_HLDOFF,
				     FFE_BB_TIMER_MODE_INT_HLDOFF,
				     FRF_AB_TC_TIMER_VAL,
				     FRF_AB_TC_TIMER_VAL,
				     channel->irq_moderation /
				     channel->irq_moderation - 1);
				     FALCON_IRQ_MOD_RESOLUTION - 1);
	} else {
	} else {
		EFX_POPULATE_DWORD_2(timer_cmd,
		EFX_POPULATE_DWORD_2(timer_cmd,
				     FRF_AB_TC_TIMER_MODE,
				     FRF_AB_TC_TIMER_MODE,
+1 −1
Original line number Original line Diff line number Diff line
@@ -327,7 +327,7 @@ enum efx_rx_alloc_method {
 * @used_flags: Channel is used by net driver
 * @used_flags: Channel is used by net driver
 * @enabled: Channel enabled indicator
 * @enabled: Channel enabled indicator
 * @irq: IRQ number (MSI and MSI-X only)
 * @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_dev: Net device used with NAPI
 * @napi_str: NAPI control structure
 * @napi_str: NAPI control structure
 * @reset_work: Scheduled reset work thread
 * @reset_work: Scheduled reset work thread