diff options
author | Mitch A Williams <mitch.a.williams@intel.com> | 2012-01-14 03:10:50 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-02-07 06:49:23 -0500 |
commit | ab50a2a430693b0961dc7b7d9fe2a4bd77d11ea6 (patch) | |
tree | 12922f9f8d20c29006f6d99c4d1b2a1989215412 /drivers/net/ethernet/intel/igbvf/netdev.c | |
parent | 59d74026fa4b5df72a268f1e9578af500154ad07 (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>
Diffstat (limited to 'drivers/net/ethernet/intel/igbvf/netdev.c')
-rw-r--r-- | drivers/net/ethernet/intel/igbvf/netdev.c | 131 |
1 files changed, 74 insertions, 57 deletions
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 | **/ |
638 | static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter, | 637 | static 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 | ||
680 | update_itr_done: | 681 | update_itr_done: |
681 | return retval; | 682 | return retval; |
682 | } | 683 | } |
683 | 684 | ||
684 | static void igbvf_set_itr(struct igbvf_adapter *adapter) | 685 | static 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 | |||
707 | static 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); |