diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2009-03-20 09:30:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-21 22:06:58 -0400 |
commit | 6fb70fd1b57707a5c7b9fb167b7790b2cba13f04 (patch) | |
tree | 311192bd4de07e1da571f1a6ac6a3ad123ab3f50 /drivers/net/sfc/ethtool.c | |
parent | 85451a951b9511605475fadcc0a8d3aeccefded8 (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/ethtool.c')
-rw-r--r-- | drivers/net/sfc/ethtool.c | 19 |
1 files changed, 6 insertions, 13 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 589d13292969..64309f4e8b19 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -604,7 +604,6 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, | |||
604 | { | 604 | { |
605 | struct efx_nic *efx = netdev_priv(net_dev); | 605 | struct efx_nic *efx = netdev_priv(net_dev); |
606 | struct efx_tx_queue *tx_queue; | 606 | struct efx_tx_queue *tx_queue; |
607 | struct efx_rx_queue *rx_queue; | ||
608 | struct efx_channel *channel; | 607 | struct efx_channel *channel; |
609 | 608 | ||
610 | memset(coalesce, 0, sizeof(*coalesce)); | 609 | memset(coalesce, 0, sizeof(*coalesce)); |
@@ -622,14 +621,8 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, | |||
622 | } | 621 | } |
623 | } | 622 | } |
624 | 623 | ||
625 | /* Find lowest IRQ moderation across all used RX queues */ | 624 | coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive; |
626 | coalesce->rx_coalesce_usecs_irq = ~((u32) 0); | 625 | coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation; |
627 | efx_for_each_rx_queue(rx_queue, efx) { | ||
628 | channel = rx_queue->channel; | ||
629 | if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq) | ||
630 | coalesce->rx_coalesce_usecs_irq = | ||
631 | channel->irq_moderation; | ||
632 | } | ||
633 | 626 | ||
634 | return 0; | 627 | return 0; |
635 | } | 628 | } |
@@ -643,10 +636,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
643 | struct efx_nic *efx = netdev_priv(net_dev); | 636 | struct efx_nic *efx = netdev_priv(net_dev); |
644 | struct efx_channel *channel; | 637 | struct efx_channel *channel; |
645 | struct efx_tx_queue *tx_queue; | 638 | struct efx_tx_queue *tx_queue; |
646 | unsigned tx_usecs, rx_usecs; | 639 | unsigned tx_usecs, rx_usecs, adaptive; |
647 | 640 | ||
648 | if (coalesce->use_adaptive_rx_coalesce || | 641 | if (coalesce->use_adaptive_tx_coalesce) |
649 | coalesce->use_adaptive_tx_coalesce) | ||
650 | return -EOPNOTSUPP; | 642 | return -EOPNOTSUPP; |
651 | 643 | ||
652 | if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { | 644 | if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { |
@@ -657,6 +649,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
657 | 649 | ||
658 | rx_usecs = coalesce->rx_coalesce_usecs_irq; | 650 | rx_usecs = coalesce->rx_coalesce_usecs_irq; |
659 | tx_usecs = coalesce->tx_coalesce_usecs_irq; | 651 | tx_usecs = coalesce->tx_coalesce_usecs_irq; |
652 | adaptive = coalesce->use_adaptive_rx_coalesce; | ||
660 | 653 | ||
661 | /* If the channel is shared only allow RX parameters to be set */ | 654 | /* If the channel is shared only allow RX parameters to be set */ |
662 | efx_for_each_tx_queue(tx_queue, efx) { | 655 | efx_for_each_tx_queue(tx_queue, efx) { |
@@ -668,7 +661,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
668 | } | 661 | } |
669 | } | 662 | } |
670 | 663 | ||
671 | efx_init_irq_moderation(efx, tx_usecs, rx_usecs); | 664 | efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive); |
672 | 665 | ||
673 | /* Reset channel to pick up new moderation value. Note that | 666 | /* Reset channel to pick up new moderation value. Note that |
674 | * this may change the value of the irq_moderation field | 667 | * this may change the value of the irq_moderation field |