aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch A Williams <mitch.a.williams@intel.com>2012-01-14 03:10:50 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-02-07 06:49:23 -0500
commitab50a2a430693b0961dc7b7d9fe2a4bd77d11ea6 (patch)
tree12922f9f8d20c29006f6d99c4d1b2a1989215412
parent59d74026fa4b5df72a268f1e9578af500154ad07 (diff)
igbvf: refactor Interrupt Throttle Rate code
The existing ITR code is broken and confusing, with lots of similarly-named variables that do different things. Additionally, after the driver carefully determines the optimal interrupt rate for the adapter, it then ignores it and always writes a fixed, suboptimal value. This patch refactors that code to make variable names more descriptive of what they actually do, and then actually writes the calculated result to the hardware. Preliminary testing shows that netperf TCP_STREAM tests goes from ~918Mbps to ~940Mbps, and TCP_RR goes from ~2k transactions/sec up to > 8k. Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Tested-by: Robert E Garrett <robertX.e.garrett@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/igbvf/ethtool.c19
-rw-r--r--drivers/net/ethernet/intel/igbvf/igbvf.h27
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c131
3 files changed, 99 insertions, 78 deletions
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index db7dce2351c2..8ce67064b9c5 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -343,10 +343,10 @@ static int igbvf_get_coalesce(struct net_device *netdev,
343{ 343{
344 struct igbvf_adapter *adapter = netdev_priv(netdev); 344 struct igbvf_adapter *adapter = netdev_priv(netdev);
345 345
346 if (adapter->itr_setting <= 3) 346 if (adapter->requested_itr <= 3)
347 ec->rx_coalesce_usecs = adapter->itr_setting; 347 ec->rx_coalesce_usecs = adapter->requested_itr;
348 else 348 else
349 ec->rx_coalesce_usecs = adapter->itr_setting >> 2; 349 ec->rx_coalesce_usecs = adapter->current_itr >> 2;
350 350
351 return 0; 351 return 0;
352} 352}
@@ -365,15 +365,16 @@ static int igbvf_set_coalesce(struct net_device *netdev,
365 365
366 /* convert to rate of irq's per second */ 366 /* convert to rate of irq's per second */
367 if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { 367 if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
368 adapter->itr = IGBVF_START_ITR; 368 adapter->current_itr = IGBVF_START_ITR;
369 adapter->itr_setting = ec->rx_coalesce_usecs; 369 adapter->requested_itr = ec->rx_coalesce_usecs;
370 } else { 370 } else {
371 adapter->itr = ec->rx_coalesce_usecs << 2; 371 adapter->current_itr = ec->rx_coalesce_usecs << 2;
372 adapter->itr_setting = adapter->itr; 372 adapter->requested_itr = 1000000000 /
373 (adapter->current_itr * 256);
373 } 374 }
374 375
375 writel(adapter->itr, 376 writel(adapter->current_itr,
376 hw->hw_addr + adapter->rx_ring[0].itr_register); 377 hw->hw_addr + adapter->rx_ring->itr_register);
377 378
378 return 0; 379 return 0;
379} 380}
diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h
index 2c6d87e4d3d9..a895e2f7b34d 100644
--- a/drivers/net/ethernet/intel/igbvf/igbvf.h
+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h
@@ -43,7 +43,18 @@ struct igbvf_info;
43struct igbvf_adapter; 43struct igbvf_adapter;
44 44
45/* Interrupt defines */ 45/* Interrupt defines */
46#define IGBVF_START_ITR 648 /* ~6000 ints/sec */ 46#define IGBVF_START_ITR 488 /* ~8000 ints/sec */
47#define IGBVF_4K_ITR 980
48#define IGBVF_20K_ITR 196
49#define IGBVF_70K_ITR 56
50
51enum latency_range {
52 lowest_latency = 0,
53 low_latency = 1,
54 bulk_latency = 2,
55 latency_invalid = 255
56};
57
47 58
48/* Interrupt modes, as used by the IntMode parameter */ 59/* Interrupt modes, as used by the IntMode parameter */
49#define IGBVF_INT_MODE_LEGACY 0 60#define IGBVF_INT_MODE_LEGACY 0
@@ -155,6 +166,7 @@ struct igbvf_ring {
155 char name[IFNAMSIZ + 5]; 166 char name[IFNAMSIZ + 5];
156 u32 eims_value; 167 u32 eims_value;
157 u32 itr_val; 168 u32 itr_val;
169 enum latency_range itr_range;
158 u16 itr_register; 170 u16 itr_register;
159 int set_itr; 171 int set_itr;
160 172
@@ -187,10 +199,8 @@ struct igbvf_adapter {
187 unsigned long state; 199 unsigned long state;
188 200
189 /* Interrupt Throttle Rate */ 201 /* Interrupt Throttle Rate */
190 u32 itr; 202 u32 requested_itr; /* ints/sec or adaptive */
191 u32 itr_setting; 203 u32 current_itr; /* Actual ITR register value, not ints/sec */
192 u16 tx_itr;
193 u16 rx_itr;
194 204
195 /* 205 /*
196 * Tx 206 * Tx
@@ -299,13 +309,6 @@ enum igbvf_state_t {
299 __IGBVF_DOWN 309 __IGBVF_DOWN
300}; 310};
301 311
302enum latency_range {
303 lowest_latency = 0,
304 low_latency = 1,
305 bulk_latency = 2,
306 latency_invalid = 255
307};
308
309extern char igbvf_driver_name[]; 312extern char igbvf_driver_name[];
310extern const char igbvf_driver_version[]; 313extern const char igbvf_driver_version[];
311 314
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 4e9141cfe81d..446297ff0104 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -632,14 +632,13 @@ void igbvf_free_rx_resources(struct igbvf_ring *rx_ring)
632 * traffic pattern. Constants in this function were computed 632 * traffic pattern. Constants in this function were computed
633 * based on theoretical maximum wire speed and thresholds were set based 633 * based on theoretical maximum wire speed and thresholds were set based
634 * on testing data as well as attempting to minimize response time 634 * on testing data as well as attempting to minimize response time
635 * while increasing bulk throughput. This functionality is controlled 635 * while increasing bulk throughput.
636 * by the InterruptThrottleRate module parameter.
637 **/ 636 **/
638static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter, 637static enum latency_range igbvf_update_itr(struct igbvf_adapter *adapter,
639 u16 itr_setting, int packets, 638 enum latency_range itr_setting,
640 int bytes) 639 int packets, int bytes)
641{ 640{
642 unsigned int retval = itr_setting; 641 enum latency_range retval = itr_setting;
643 642
644 if (packets == 0) 643 if (packets == 0)
645 goto update_itr_done; 644 goto update_itr_done;
@@ -675,65 +674,87 @@ static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
675 retval = low_latency; 674 retval = low_latency;
676 } 675 }
677 break; 676 break;
677 default:
678 break;
678 } 679 }
679 680
680update_itr_done: 681update_itr_done:
681 return retval; 682 return retval;
682} 683}
683 684
684static void igbvf_set_itr(struct igbvf_adapter *adapter) 685static int igbvf_range_to_itr(enum latency_range current_range)
685{ 686{
686 struct e1000_hw *hw = &adapter->hw; 687 int new_itr;
687 u16 current_itr;
688 u32 new_itr = adapter->itr;
689
690 adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr,
691 adapter->total_tx_packets,
692 adapter->total_tx_bytes);
693 /* conservative mode (itr 3) eliminates the lowest_latency setting */
694 if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
695 adapter->tx_itr = low_latency;
696
697 adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr,
698 adapter->total_rx_packets,
699 adapter->total_rx_bytes);
700 /* conservative mode (itr 3) eliminates the lowest_latency setting */
701 if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
702 adapter->rx_itr = low_latency;
703 688
704 current_itr = max(adapter->rx_itr, adapter->tx_itr); 689 switch (current_range) {
705
706 switch (current_itr) {
707 /* counts and packets in update_itr are dependent on these numbers */ 690 /* counts and packets in update_itr are dependent on these numbers */
708 case lowest_latency: 691 case lowest_latency:
709 new_itr = 70000; 692 new_itr = IGBVF_70K_ITR;
710 break; 693 break;
711 case low_latency: 694 case low_latency:
712 new_itr = 20000; /* aka hwitr = ~200 */ 695 new_itr = IGBVF_20K_ITR;
713 break; 696 break;
714 case bulk_latency: 697 case bulk_latency:
715 new_itr = 4000; 698 new_itr = IGBVF_4K_ITR;
716 break; 699 break;
717 default: 700 default:
701 new_itr = IGBVF_START_ITR;
718 break; 702 break;
719 } 703 }
704 return new_itr;
705}
706
707static void igbvf_set_itr(struct igbvf_adapter *adapter)
708{
709 u32 new_itr;
710
711 adapter->tx_ring->itr_range =
712 igbvf_update_itr(adapter,
713 adapter->tx_ring->itr_val,
714 adapter->total_tx_packets,
715 adapter->total_tx_bytes);
716
717 /* conservative mode (itr 3) eliminates the lowest_latency setting */
718 if (adapter->requested_itr == 3 &&
719 adapter->tx_ring->itr_range == lowest_latency)
720 adapter->tx_ring->itr_range = low_latency;
720 721
721 if (new_itr != adapter->itr) { 722 new_itr = igbvf_range_to_itr(adapter->tx_ring->itr_range);
723
724
725 if (new_itr != adapter->tx_ring->itr_val) {
726 u32 current_itr = adapter->tx_ring->itr_val;
722 /* 727 /*
723 * this attempts to bias the interrupt rate towards Bulk 728 * this attempts to bias the interrupt rate towards Bulk
724 * by adding intermediate steps when interrupt rate is 729 * by adding intermediate steps when interrupt rate is
725 * increasing 730 * increasing
726 */ 731 */
727 new_itr = new_itr > adapter->itr ? 732 new_itr = new_itr > current_itr ?
728 min(adapter->itr + (new_itr >> 2), new_itr) : 733 min(current_itr + (new_itr >> 2), new_itr) :
729 new_itr; 734 new_itr;
730 adapter->itr = new_itr; 735 adapter->tx_ring->itr_val = new_itr;
731 adapter->rx_ring->itr_val = 1952; 736
732 737 adapter->tx_ring->set_itr = 1;
733 if (adapter->msix_entries) 738 }
734 adapter->rx_ring->set_itr = 1; 739
735 else 740 adapter->rx_ring->itr_range =
736 ew32(ITR, 1952); 741 igbvf_update_itr(adapter, adapter->rx_ring->itr_val,
742 adapter->total_rx_packets,
743 adapter->total_rx_bytes);
744 if (adapter->requested_itr == 3 &&
745 adapter->rx_ring->itr_range == lowest_latency)
746 adapter->rx_ring->itr_range = low_latency;
747
748 new_itr = igbvf_range_to_itr(adapter->rx_ring->itr_range);
749
750 if (new_itr != adapter->rx_ring->itr_val) {
751 u32 current_itr = adapter->rx_ring->itr_val;
752 new_itr = new_itr > current_itr ?
753 min(current_itr + (new_itr >> 2), new_itr) :
754 new_itr;
755 adapter->rx_ring->itr_val = new_itr;
756
757 adapter->rx_ring->set_itr = 1;
737 } 758 }
738} 759}
739 760
@@ -835,6 +856,11 @@ static irqreturn_t igbvf_intr_msix_tx(int irq, void *data)
835 struct e1000_hw *hw = &adapter->hw; 856 struct e1000_hw *hw = &adapter->hw;
836 struct igbvf_ring *tx_ring = adapter->tx_ring; 857 struct igbvf_ring *tx_ring = adapter->tx_ring;
837 858
859 if (tx_ring->set_itr) {
860 writel(tx_ring->itr_val,
861 adapter->hw.hw_addr + tx_ring->itr_register);
862 adapter->tx_ring->set_itr = 0;
863 }
838 864
839 adapter->total_tx_bytes = 0; 865 adapter->total_tx_bytes = 0;
840 adapter->total_tx_packets = 0; 866 adapter->total_tx_packets = 0;
@@ -937,19 +963,10 @@ static void igbvf_configure_msix(struct igbvf_adapter *adapter)
937 963
938 igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++); 964 igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++);
939 adapter->eims_enable_mask |= tx_ring->eims_value; 965 adapter->eims_enable_mask |= tx_ring->eims_value;
940 if (tx_ring->itr_val) 966 writel(tx_ring->itr_val, hw->hw_addr + tx_ring->itr_register);
941 writel(tx_ring->itr_val,
942 hw->hw_addr + tx_ring->itr_register);
943 else
944 writel(1952, hw->hw_addr + tx_ring->itr_register);
945
946 igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++); 967 igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++);
947 adapter->eims_enable_mask |= rx_ring->eims_value; 968 adapter->eims_enable_mask |= rx_ring->eims_value;
948 if (rx_ring->itr_val) 969 writel(rx_ring->itr_val, hw->hw_addr + rx_ring->itr_register);
949 writel(rx_ring->itr_val,
950 hw->hw_addr + rx_ring->itr_register);
951 else
952 writel(1952, hw->hw_addr + rx_ring->itr_register);
953 970
954 /* set vector for other causes, i.e. link changes */ 971 /* set vector for other causes, i.e. link changes */
955 972
@@ -1027,7 +1044,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
1027 goto out; 1044 goto out;
1028 1045
1029 adapter->tx_ring->itr_register = E1000_EITR(vector); 1046 adapter->tx_ring->itr_register = E1000_EITR(vector);
1030 adapter->tx_ring->itr_val = 1952; 1047 adapter->tx_ring->itr_val = adapter->current_itr;
1031 vector++; 1048 vector++;
1032 1049
1033 err = request_irq(adapter->msix_entries[vector].vector, 1050 err = request_irq(adapter->msix_entries[vector].vector,
@@ -1037,7 +1054,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
1037 goto out; 1054 goto out;
1038 1055
1039 adapter->rx_ring->itr_register = E1000_EITR(vector); 1056 adapter->rx_ring->itr_register = E1000_EITR(vector);
1040 adapter->rx_ring->itr_val = 1952; 1057 adapter->rx_ring->itr_val = adapter->current_itr;
1041 vector++; 1058 vector++;
1042 1059
1043 err = request_irq(adapter->msix_entries[vector].vector, 1060 err = request_irq(adapter->msix_entries[vector].vector,
@@ -1151,7 +1168,7 @@ static int igbvf_poll(struct napi_struct *napi, int budget)
1151 if (work_done < budget) { 1168 if (work_done < budget) {
1152 napi_complete(napi); 1169 napi_complete(napi);
1153 1170
1154 if (adapter->itr_setting & 3) 1171 if (adapter->requested_itr & 3)
1155 igbvf_set_itr(adapter); 1172 igbvf_set_itr(adapter);
1156 1173
1157 if (!test_bit(__IGBVF_DOWN, &adapter->state)) 1174 if (!test_bit(__IGBVF_DOWN, &adapter->state))
@@ -1521,8 +1538,8 @@ static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter)
1521 adapter->tx_abs_int_delay = 32; 1538 adapter->tx_abs_int_delay = 32;
1522 adapter->rx_int_delay = 0; 1539 adapter->rx_int_delay = 0;
1523 adapter->rx_abs_int_delay = 8; 1540 adapter->rx_abs_int_delay = 8;
1524 adapter->itr_setting = 3; 1541 adapter->requested_itr = 3;
1525 adapter->itr = 20000; 1542 adapter->current_itr = IGBVF_START_ITR;
1526 1543
1527 /* Set various function pointers */ 1544 /* Set various function pointers */
1528 adapter->ei->init_ops(&adapter->hw); 1545 adapter->ei->init_ops(&adapter->hw);