aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorAyyappan Veeraiyan <ayyappan.veeraiyan@intel.com>2008-03-03 18:03:57 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:28 -0400
commitf494e8faa77bd4147324f7666441e0b780e7db94 (patch)
treeadcb7b1f344209de1db703abd1d1b25e497a613b /drivers/net/ixgbe
parent30eba97a3f076cf4e100b598ee9a1b1439b0cfaa (diff)
ixgbe: Introduce adaptive interrupt moderation
82598 can produce a formidable interrupt rate, and is largely unusable without some form of moderation. The default behaviour before this patch is to limit irq's to a reasonable number. However, just like our other drivers we can reduce latency for small packet-type traffic considerably by allowing the irq rate to go up dynamically. This patch introduces a simple irq moderation algorithm based on traffic analysis. The driver will use more CPU to service small packets quicker but will perform the same on bulk traffic as the old code. Signed-off-by: Ayyappan Veeraiyan <ayyappan.veeraiyan@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe.h9
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c24
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c211
3 files changed, 232 insertions, 12 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 20774772b608..79f5519e2aa9 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -136,6 +136,8 @@ struct ixgbe_ring {
136 u16 head; 136 u16 head;
137 u16 tail; 137 u16 tail;
138 138
139 unsigned int total_bytes;
140 unsigned int total_packets;
139 141
140 u16 reg_idx; /* holds the special value that gets the hardware register 142 u16 reg_idx; /* holds the special value that gets the hardware register
141 * offset associated with this ring, which is different 143 * offset associated with this ring, which is different
@@ -174,6 +176,8 @@ struct ixgbe_q_vector {
174 DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ 176 DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
175 u8 rxr_count; /* Rx ring count assigned to this vector */ 177 u8 rxr_count; /* Rx ring count assigned to this vector */
176 u8 txr_count; /* Tx ring count assigned to this vector */ 178 u8 txr_count; /* Tx ring count assigned to this vector */
179 u8 tx_eitr;
180 u8 rx_eitr;
177 u32 eitr; 181 u32 eitr;
178}; 182};
179 183
@@ -215,6 +219,11 @@ struct ixgbe_adapter {
215 struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS]; 219 struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
216 char name[MAX_MSIX_COUNT][IFNAMSIZ + 5]; 220 char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
217 221
222 /* Interrupt Throttle Rate */
223 u32 itr_setting;
224 u16 eitr_low;
225 u16 eitr_high;
226
218 /* TX */ 227 /* TX */
219 struct ixgbe_ring *tx_ring; /* One per active queue */ 228 struct ixgbe_ring *tx_ring; /* One per active queue */
220 u64 restart_queue; 229 u64 restart_queue;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 85b7d15e1217..4e463778bcfd 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -886,13 +886,13 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
886{ 886{
887 struct ixgbe_adapter *adapter = netdev_priv(netdev); 887 struct ixgbe_adapter *adapter = netdev_priv(netdev);
888 888
889 if (adapter->rx_eitr == 0) 889 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
890 ec->rx_coalesce_usecs = 0; 890 ec->rx_coalesce_usecs = adapter->rx_eitr;
891 else 891 else
892 ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; 892 ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
893 893
894 if (adapter->tx_eitr == 0) 894 if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
895 ec->tx_coalesce_usecs = 0; 895 ec->tx_coalesce_usecs = adapter->tx_eitr;
896 else 896 else
897 ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; 897 ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
898 898
@@ -906,22 +906,26 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
906 struct ixgbe_adapter *adapter = netdev_priv(netdev); 906 struct ixgbe_adapter *adapter = netdev_priv(netdev);
907 907
908 if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || 908 if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
909 ((ec->rx_coalesce_usecs > 0) && 909 ((ec->rx_coalesce_usecs != 0) &&
910 (ec->rx_coalesce_usecs != 1) &&
911 (ec->rx_coalesce_usecs != 3) &&
910 (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) 912 (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
911 return -EINVAL; 913 return -EINVAL;
912 if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || 914 if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
913 ((ec->tx_coalesce_usecs > 0) && 915 ((ec->tx_coalesce_usecs != 0) &&
916 (ec->tx_coalesce_usecs != 1) &&
917 (ec->tx_coalesce_usecs != 3) &&
914 (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) 918 (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
915 return -EINVAL; 919 return -EINVAL;
916 920
917 /* convert to rate of irq's per second */ 921 /* convert to rate of irq's per second */
918 if (ec->rx_coalesce_usecs == 0) 922 if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
919 adapter->rx_eitr = 0; 923 adapter->rx_eitr = ec->rx_coalesce_usecs;
920 else 924 else
921 adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); 925 adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
922 926
923 if (ec->tx_coalesce_usecs == 0) 927 if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
924 adapter->tx_eitr = 0; 928 adapter->tx_eitr = ec->rx_coalesce_usecs;
925 else 929 else
926 adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); 930 adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
927 931
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index fc1c226f5751..e1f11e686f47 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -282,6 +282,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
282 if (total_tx_packets >= tx_ring->work_limit) 282 if (total_tx_packets >= tx_ring->work_limit)
283 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value); 283 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
284 284
285 tx_ring->total_bytes += total_tx_bytes;
286 tx_ring->total_packets += total_tx_packets;
285 adapter->net_stats.tx_bytes += total_tx_bytes; 287 adapter->net_stats.tx_bytes += total_tx_bytes;
286 adapter->net_stats.tx_packets += total_tx_packets; 288 adapter->net_stats.tx_packets += total_tx_packets;
287 cleaned = total_tx_packets ? true : false; 289 cleaned = total_tx_packets ? true : false;
@@ -568,6 +570,11 @@ next_desc:
568 adapter->net_stats.rx_bytes += total_rx_bytes; 570 adapter->net_stats.rx_bytes += total_rx_bytes;
569 adapter->net_stats.rx_packets += total_rx_packets; 571 adapter->net_stats.rx_packets += total_rx_packets;
570 572
573 rx_ring->total_packets += total_rx_packets;
574 rx_ring->total_bytes += total_rx_bytes;
575 adapter->net_stats.rx_bytes += total_rx_bytes;
576 adapter->net_stats.rx_packets += total_rx_packets;
577
571 return cleaned; 578 return cleaned;
572} 579}
573 580
@@ -634,6 +641,144 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
634 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask); 641 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
635} 642}
636 643
644enum latency_range {
645 lowest_latency = 0,
646 low_latency = 1,
647 bulk_latency = 2,
648 latency_invalid = 255
649};
650
651/**
652 * ixgbe_update_itr - update the dynamic ITR value based on statistics
653 * @adapter: pointer to adapter
654 * @eitr: eitr setting (ints per sec) to give last timeslice
655 * @itr_setting: current throttle rate in ints/second
656 * @packets: the number of packets during this measurement interval
657 * @bytes: the number of bytes during this measurement interval
658 *
659 * Stores a new ITR value based on packets and byte
660 * counts during the last interrupt. The advantage of per interrupt
661 * computation is faster updates and more accurate ITR for the current
662 * traffic pattern. Constants in this function were computed
663 * based on theoretical maximum wire speed and thresholds were set based
664 * on testing data as well as attempting to minimize response time
665 * while increasing bulk throughput.
666 * this functionality is controlled by the InterruptThrottleRate module
667 * parameter (see ixgbe_param.c)
668 **/
669static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
670 u32 eitr, u8 itr_setting,
671 int packets, int bytes)
672{
673 unsigned int retval = itr_setting;
674 u32 timepassed_us;
675 u64 bytes_perint;
676
677 if (packets == 0)
678 goto update_itr_done;
679
680
681 /* simple throttlerate management
682 * 0-20MB/s lowest (100000 ints/s)
683 * 20-100MB/s low (20000 ints/s)
684 * 100-1249MB/s bulk (8000 ints/s)
685 */
686 /* what was last interrupt timeslice? */
687 timepassed_us = 1000000/eitr;
688 bytes_perint = bytes / timepassed_us; /* bytes/usec */
689
690 switch (itr_setting) {
691 case lowest_latency:
692 if (bytes_perint > adapter->eitr_low)
693 retval = low_latency;
694 break;
695 case low_latency:
696 if (bytes_perint > adapter->eitr_high)
697 retval = bulk_latency;
698 else if (bytes_perint <= adapter->eitr_low)
699 retval = lowest_latency;
700 break;
701 case bulk_latency:
702 if (bytes_perint <= adapter->eitr_high)
703 retval = low_latency;
704 break;
705 }
706
707update_itr_done:
708 return retval;
709}
710
711static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
712{
713 struct ixgbe_adapter *adapter = q_vector->adapter;
714 struct ixgbe_hw *hw = &adapter->hw;
715 u32 new_itr;
716 u8 current_itr, ret_itr;
717 int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
718 sizeof(struct ixgbe_q_vector);
719 struct ixgbe_ring *rx_ring, *tx_ring;
720
721 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
722 for (i = 0; i < q_vector->txr_count; i++) {
723 tx_ring = &(adapter->tx_ring[r_idx]);
724 ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
725 q_vector->tx_eitr,
726 tx_ring->total_packets,
727 tx_ring->total_bytes);
728 /* if the result for this queue would decrease interrupt
729 * rate for this vector then use that result */
730 q_vector->tx_eitr = ((q_vector->tx_eitr > ret_itr) ?
731 q_vector->tx_eitr - 1 : ret_itr);
732 r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
733 r_idx + 1);
734 }
735
736 r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
737 for (i = 0; i < q_vector->rxr_count; i++) {
738 rx_ring = &(adapter->rx_ring[r_idx]);
739 ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
740 q_vector->rx_eitr,
741 rx_ring->total_packets,
742 rx_ring->total_bytes);
743 /* if the result for this queue would decrease interrupt
744 * rate for this vector then use that result */
745 q_vector->rx_eitr = ((q_vector->rx_eitr > ret_itr) ?
746 q_vector->rx_eitr - 1 : ret_itr);
747 r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
748 r_idx + 1);
749 }
750
751 current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
752
753 switch (current_itr) {
754 /* counts and packets in update_itr are dependent on these numbers */
755 case lowest_latency:
756 new_itr = 100000;
757 break;
758 case low_latency:
759 new_itr = 20000; /* aka hwitr = ~200 */
760 break;
761 case bulk_latency:
762 default:
763 new_itr = 8000;
764 break;
765 }
766
767 if (new_itr != q_vector->eitr) {
768 u32 itr_reg;
769 /* do an exponential smoothing */
770 new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
771 q_vector->eitr = new_itr;
772 itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
773 /* must write high and low 16 bits to reset counter */
774 DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
775 itr_reg);
776 IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
777 }
778
779 return;
780}
781
637static irqreturn_t ixgbe_msix_lsc(int irq, void *data) 782static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
638{ 783{
639 struct net_device *netdev = data; 784 struct net_device *netdev = data;
@@ -666,12 +811,13 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
666 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); 811 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
667 for (i = 0; i < q_vector->txr_count; i++) { 812 for (i = 0; i < q_vector->txr_count; i++) {
668 txr = &(adapter->tx_ring[r_idx]); 813 txr = &(adapter->tx_ring[r_idx]);
814 txr->total_bytes = 0;
815 txr->total_packets = 0;
669 ixgbe_clean_tx_irq(adapter, txr); 816 ixgbe_clean_tx_irq(adapter, txr);
670 r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, 817 r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
671 r_idx + 1); 818 r_idx + 1);
672 } 819 }
673 820
674
675 return IRQ_HANDLED; 821 return IRQ_HANDLED;
676} 822}
677 823
@@ -694,6 +840,8 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
694 rxr = &(adapter->rx_ring[r_idx]); 840 rxr = &(adapter->rx_ring[r_idx]);
695 /* disable interrupts on this vector only */ 841 /* disable interrupts on this vector only */
696 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->v_idx); 842 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->v_idx);
843 rxr->total_bytes = 0;
844 rxr->total_packets = 0;
697 netif_rx_schedule(adapter->netdev, &q_vector->napi); 845 netif_rx_schedule(adapter->netdev, &q_vector->napi);
698 846
699 return IRQ_HANDLED; 847 return IRQ_HANDLED;
@@ -730,6 +878,8 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
730 /* If all Rx work done, exit the polling mode */ 878 /* If all Rx work done, exit the polling mode */
731 if (work_done < budget) { 879 if (work_done < budget) {
732 netif_rx_complete(adapter->netdev, napi); 880 netif_rx_complete(adapter->netdev, napi);
881 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
882 ixgbe_set_itr_msix(q_vector);
733 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 883 if (!test_bit(__IXGBE_DOWN, &adapter->state))
734 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rxr->v_idx); 884 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rxr->v_idx);
735 } 885 }
@@ -886,6 +1036,54 @@ out:
886 return err; 1036 return err;
887} 1037}
888 1038
1039static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
1040{
1041 struct ixgbe_hw *hw = &adapter->hw;
1042 struct ixgbe_q_vector *q_vector = adapter->q_vector;
1043 u8 current_itr;
1044 u32 new_itr = q_vector->eitr;
1045 struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
1046 struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
1047
1048 q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr,
1049 q_vector->tx_eitr,
1050 tx_ring->total_packets,
1051 tx_ring->total_bytes);
1052 q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr,
1053 q_vector->rx_eitr,
1054 rx_ring->total_packets,
1055 rx_ring->total_bytes);
1056
1057 current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
1058
1059 switch (current_itr) {
1060 /* counts and packets in update_itr are dependent on these numbers */
1061 case lowest_latency:
1062 new_itr = 100000;
1063 break;
1064 case low_latency:
1065 new_itr = 20000; /* aka hwitr = ~200 */
1066 break;
1067 case bulk_latency:
1068 new_itr = 8000;
1069 break;
1070 default:
1071 break;
1072 }
1073
1074 if (new_itr != q_vector->eitr) {
1075 u32 itr_reg;
1076 /* do an exponential smoothing */
1077 new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
1078 q_vector->eitr = new_itr;
1079 itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
1080 /* must write high and low 16 bits to reset counter */
1081 IXGBE_WRITE_REG(hw, IXGBE_EITR(0), itr_reg | (itr_reg)<<16);
1082 }
1083
1084 return;
1085}
1086
889static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter); 1087static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter);
890 1088
891/** 1089/**
@@ -916,6 +1114,10 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
916 1114
917 1115
918 if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) { 1116 if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
1117 adapter->tx_ring[0].total_packets = 0;
1118 adapter->tx_ring[0].total_bytes = 0;
1119 adapter->rx_ring[0].total_packets = 0;
1120 adapter->rx_ring[0].total_bytes = 0;
919 /* would disable interrupts here but EIAM disabled it */ 1121 /* would disable interrupts here but EIAM disabled it */
920 __netif_rx_schedule(netdev, &adapter->q_vector[0].napi); 1122 __netif_rx_schedule(netdev, &adapter->q_vector[0].napi);
921 } 1123 }
@@ -1367,7 +1569,6 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
1367 } 1569 }
1368} 1570}
1369 1571
1370
1371static void ixgbe_configure(struct ixgbe_adapter *adapter) 1572static void ixgbe_configure(struct ixgbe_adapter *adapter)
1372{ 1573{
1373 struct net_device *netdev = adapter->netdev; 1574 struct net_device *netdev = adapter->netdev;
@@ -1732,6 +1933,8 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
1732 /* If budget not fully consumed, exit the polling mode */ 1933 /* If budget not fully consumed, exit the polling mode */
1733 if (work_done < budget) { 1934 if (work_done < budget) {
1734 netif_rx_complete(adapter->netdev, napi); 1935 netif_rx_complete(adapter->netdev, napi);
1936 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
1937 ixgbe_set_itr(adapter);
1735 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 1938 if (!test_bit(__IXGBE_DOWN, &adapter->state))
1736 ixgbe_irq_enable(adapter); 1939 ixgbe_irq_enable(adapter);
1737 } 1940 }
@@ -2088,6 +2291,10 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
2088 adapter->ring_feature[RING_F_RSS].indices = rss; 2291 adapter->ring_feature[RING_F_RSS].indices = rss;
2089 adapter->flags |= IXGBE_FLAG_RSS_ENABLED; 2292 adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
2090 2293
2294 /* Enable Dynamic interrupt throttling by default */
2295 adapter->rx_eitr = 1;
2296 adapter->tx_eitr = 1;
2297
2091 /* default flow control settings */ 2298 /* default flow control settings */
2092 hw->fc.original_type = ixgbe_fc_full; 2299 hw->fc.original_type = ixgbe_fc_full;
2093 hw->fc.type = ixgbe_fc_full; 2300 hw->fc.type = ixgbe_fc_full;