aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeepthi Dharwar <deepthi@linux.vnet.ibm.com>2011-10-28 06:50:09 -0400
committerLen Brown <len.brown@intel.com>2011-11-06 21:13:30 -0500
commite978aa7d7d57d04eb5f88a7507c4fb98577def77 (patch)
treed6d6dfe1dba4d4749c7eafe348351aa499c3c5eb /drivers
parentc3b92c8787367a8bb53d57d9789b558f1295cc96 (diff)
cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state
Cpuidle governor only suggests the state to enter using the governor->select() interface, but allows the low level driver to override the recommended state. The actual entered state may be different because of software or hardware demotion. Software demotion is done by the back-end cpuidle driver and can be accounted correctly. Current cpuidle code uses last_state field to capture the actual state entered and based on that updates the statistics for the state entered. Ideally the driver enter routine should update the counters, and it should return the state actually entered rather than the time spent there. The generic cpuidle code should simply handle where the counters live in the sysfs namespace, not updating the counters. Reference: https://lkml.org/lkml/2011/3/25/52 Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Tested-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_idle.c75
-rw-r--r--drivers/cpuidle/cpuidle.c32
-rw-r--r--drivers/cpuidle/governors/ladder.c13
-rw-r--r--drivers/cpuidle/governors/menu.c7
-rw-r--r--drivers/idle/intel_idle.c12
5 files changed, 91 insertions, 48 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 431ab11c8c1b..9cd08cecb347 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -741,22 +741,24 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
741/** 741/**
742 * acpi_idle_enter_c1 - enters an ACPI C1 state-type 742 * acpi_idle_enter_c1 - enters an ACPI C1 state-type
743 * @dev: the target CPU 743 * @dev: the target CPU
744 * @state: the state data 744 * @index: index of target state
745 * 745 *
746 * This is equivalent to the HALT instruction. 746 * This is equivalent to the HALT instruction.
747 */ 747 */
748static int acpi_idle_enter_c1(struct cpuidle_device *dev, 748static int acpi_idle_enter_c1(struct cpuidle_device *dev,
749 struct cpuidle_state *state) 749 int index)
750{ 750{
751 ktime_t kt1, kt2; 751 ktime_t kt1, kt2;
752 s64 idle_time; 752 s64 idle_time;
753 struct acpi_processor *pr; 753 struct acpi_processor *pr;
754 struct cpuidle_state *state = &dev->states[index];
754 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 755 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
755 756
756 pr = __this_cpu_read(processors); 757 pr = __this_cpu_read(processors);
758 dev->last_residency = 0;
757 759
758 if (unlikely(!pr)) 760 if (unlikely(!pr))
759 return 0; 761 return -EINVAL;
760 762
761 local_irq_disable(); 763 local_irq_disable();
762 764
@@ -764,7 +766,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
764 if (acpi_idle_suspend) { 766 if (acpi_idle_suspend) {
765 local_irq_enable(); 767 local_irq_enable();
766 cpu_relax(); 768 cpu_relax();
767 return 0; 769 return -EINVAL;
768 } 770 }
769 771
770 lapic_timer_state_broadcast(pr, cx, 1); 772 lapic_timer_state_broadcast(pr, cx, 1);
@@ -773,37 +775,46 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
773 kt2 = ktime_get_real(); 775 kt2 = ktime_get_real();
774 idle_time = ktime_to_us(ktime_sub(kt2, kt1)); 776 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
775 777
778 /* Update device last_residency*/
779 dev->last_residency = (int)idle_time;
780
776 local_irq_enable(); 781 local_irq_enable();
777 cx->usage++; 782 cx->usage++;
778 lapic_timer_state_broadcast(pr, cx, 0); 783 lapic_timer_state_broadcast(pr, cx, 0);
779 784
780 return idle_time; 785 return index;
781} 786}
782 787
783/** 788/**
784 * acpi_idle_enter_simple - enters an ACPI state without BM handling 789 * acpi_idle_enter_simple - enters an ACPI state without BM handling
785 * @dev: the target CPU 790 * @dev: the target CPU
786 * @state: the state data 791 * @index: the index of suggested state
787 */ 792 */
788static int acpi_idle_enter_simple(struct cpuidle_device *dev, 793static int acpi_idle_enter_simple(struct cpuidle_device *dev,
789 struct cpuidle_state *state) 794 int index)
790{ 795{
791 struct acpi_processor *pr; 796 struct acpi_processor *pr;
797 struct cpuidle_state *state = &dev->states[index];
792 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 798 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
793 ktime_t kt1, kt2; 799 ktime_t kt1, kt2;
794 s64 idle_time_ns; 800 s64 idle_time_ns;
795 s64 idle_time; 801 s64 idle_time;
796 802
797 pr = __this_cpu_read(processors); 803 pr = __this_cpu_read(processors);
804 dev->last_residency = 0;
798 805
799 if (unlikely(!pr)) 806 if (unlikely(!pr))
800 return 0; 807 return -EINVAL;
801
802 if (acpi_idle_suspend)
803 return(acpi_idle_enter_c1(dev, state));
804 808
805 local_irq_disable(); 809 local_irq_disable();
806 810
811 if (acpi_idle_suspend) {
812 local_irq_enable();
813 cpu_relax();
814 return -EINVAL;
815 }
816
817
807 if (cx->entry_method != ACPI_CSTATE_FFH) { 818 if (cx->entry_method != ACPI_CSTATE_FFH) {
808 current_thread_info()->status &= ~TS_POLLING; 819 current_thread_info()->status &= ~TS_POLLING;
809 /* 820 /*
@@ -815,7 +826,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
815 if (unlikely(need_resched())) { 826 if (unlikely(need_resched())) {
816 current_thread_info()->status |= TS_POLLING; 827 current_thread_info()->status |= TS_POLLING;
817 local_irq_enable(); 828 local_irq_enable();
818 return 0; 829 return -EINVAL;
819 } 830 }
820 } 831 }
821 832
@@ -837,6 +848,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
837 idle_time = idle_time_ns; 848 idle_time = idle_time_ns;
838 do_div(idle_time, NSEC_PER_USEC); 849 do_div(idle_time, NSEC_PER_USEC);
839 850
851 /* Update device last_residency*/
852 dev->last_residency = (int)idle_time;
853
840 /* Tell the scheduler how much we idled: */ 854 /* Tell the scheduler how much we idled: */
841 sched_clock_idle_wakeup_event(idle_time_ns); 855 sched_clock_idle_wakeup_event(idle_time_ns);
842 856
@@ -848,7 +862,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
848 862
849 lapic_timer_state_broadcast(pr, cx, 0); 863 lapic_timer_state_broadcast(pr, cx, 0);
850 cx->time += idle_time; 864 cx->time += idle_time;
851 return idle_time; 865 return index;
852} 866}
853 867
854static int c3_cpu_count; 868static int c3_cpu_count;
@@ -857,14 +871,15 @@ static DEFINE_SPINLOCK(c3_lock);
857/** 871/**
858 * acpi_idle_enter_bm - enters C3 with proper BM handling 872 * acpi_idle_enter_bm - enters C3 with proper BM handling
859 * @dev: the target CPU 873 * @dev: the target CPU
860 * @state: the state data 874 * @index: the index of suggested state
861 * 875 *
862 * If BM is detected, the deepest non-C3 idle state is entered instead. 876 * If BM is detected, the deepest non-C3 idle state is entered instead.
863 */ 877 */
864static int acpi_idle_enter_bm(struct cpuidle_device *dev, 878static int acpi_idle_enter_bm(struct cpuidle_device *dev,
865 struct cpuidle_state *state) 879 int index)
866{ 880{
867 struct acpi_processor *pr; 881 struct acpi_processor *pr;
882 struct cpuidle_state *state = &dev->states[index];
868 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 883 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
869 ktime_t kt1, kt2; 884 ktime_t kt1, kt2;
870 s64 idle_time_ns; 885 s64 idle_time_ns;
@@ -872,22 +887,26 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
872 887
873 888
874 pr = __this_cpu_read(processors); 889 pr = __this_cpu_read(processors);
890 dev->last_residency = 0;
875 891
876 if (unlikely(!pr)) 892 if (unlikely(!pr))
877 return 0; 893 return -EINVAL;
878 894
879 if (acpi_idle_suspend) 895
880 return(acpi_idle_enter_c1(dev, state)); 896 if (acpi_idle_suspend) {
897 cpu_relax();
898 return -EINVAL;
899 }
881 900
882 if (!cx->bm_sts_skip && acpi_idle_bm_check()) { 901 if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
883 if (dev->safe_state) { 902 if (dev->safe_state_index >= 0) {
884 dev->last_state = dev->safe_state; 903 return dev->states[dev->safe_state_index].enter(dev,
885 return dev->safe_state->enter(dev, dev->safe_state); 904 dev->safe_state_index);
886 } else { 905 } else {
887 local_irq_disable(); 906 local_irq_disable();
888 acpi_safe_halt(); 907 acpi_safe_halt();
889 local_irq_enable(); 908 local_irq_enable();
890 return 0; 909 return -EINVAL;
891 } 910 }
892 } 911 }
893 912
@@ -904,7 +923,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
904 if (unlikely(need_resched())) { 923 if (unlikely(need_resched())) {
905 current_thread_info()->status |= TS_POLLING; 924 current_thread_info()->status |= TS_POLLING;
906 local_irq_enable(); 925 local_irq_enable();
907 return 0; 926 return -EINVAL;
908 } 927 }
909 } 928 }
910 929
@@ -954,6 +973,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
954 idle_time = idle_time_ns; 973 idle_time = idle_time_ns;
955 do_div(idle_time, NSEC_PER_USEC); 974 do_div(idle_time, NSEC_PER_USEC);
956 975
976 /* Update device last_residency*/
977 dev->last_residency = (int)idle_time;
978
957 /* Tell the scheduler how much we idled: */ 979 /* Tell the scheduler how much we idled: */
958 sched_clock_idle_wakeup_event(idle_time_ns); 980 sched_clock_idle_wakeup_event(idle_time_ns);
959 981
@@ -965,7 +987,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
965 987
966 lapic_timer_state_broadcast(pr, cx, 0); 988 lapic_timer_state_broadcast(pr, cx, 0);
967 cx->time += idle_time; 989 cx->time += idle_time;
968 return idle_time; 990 return index;
969} 991}
970 992
971struct cpuidle_driver acpi_idle_driver = { 993struct cpuidle_driver acpi_idle_driver = {
@@ -992,6 +1014,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
992 } 1014 }
993 1015
994 dev->cpu = pr->id; 1016 dev->cpu = pr->id;
1017 dev->safe_state_index = -1;
995 for (i = 0; i < CPUIDLE_STATE_MAX; i++) { 1018 for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
996 dev->states[i].name[0] = '\0'; 1019 dev->states[i].name[0] = '\0';
997 dev->states[i].desc[0] = '\0'; 1020 dev->states[i].desc[0] = '\0';
@@ -1027,13 +1050,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1027 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1050 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1028 1051
1029 state->enter = acpi_idle_enter_c1; 1052 state->enter = acpi_idle_enter_c1;
1030 dev->safe_state = state; 1053 dev->safe_state_index = count;
1031 break; 1054 break;
1032 1055
1033 case ACPI_STATE_C2: 1056 case ACPI_STATE_C2:
1034 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1057 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1035 state->enter = acpi_idle_enter_simple; 1058 state->enter = acpi_idle_enter_simple;
1036 dev->safe_state = state; 1059 dev->safe_state_index = count;
1037 break; 1060 break;
1038 1061
1039 case ACPI_STATE_C3: 1062 case ACPI_STATE_C3:
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index d4c542372886..88bd12104396 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -62,7 +62,7 @@ int cpuidle_idle_call(void)
62{ 62{
63 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); 63 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
64 struct cpuidle_state *target_state; 64 struct cpuidle_state *target_state;
65 int next_state; 65 int next_state, entered_state;
66 66
67 if (off) 67 if (off)
68 return -ENODEV; 68 return -ENODEV;
@@ -102,26 +102,27 @@ int cpuidle_idle_call(void)
102 102
103 target_state = &dev->states[next_state]; 103 target_state = &dev->states[next_state];
104 104
105 /* enter the state and update stats */
106 dev->last_state = target_state;
107
108 trace_power_start(POWER_CSTATE, next_state, dev->cpu); 105 trace_power_start(POWER_CSTATE, next_state, dev->cpu);
109 trace_cpu_idle(next_state, dev->cpu); 106 trace_cpu_idle(next_state, dev->cpu);
110 107
111 dev->last_residency = target_state->enter(dev, target_state); 108 entered_state = target_state->enter(dev, next_state);
112 109
113 trace_power_end(dev->cpu); 110 trace_power_end(dev->cpu);
114 trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); 111 trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
115 112
116 if (dev->last_state) 113 if (entered_state >= 0) {
117 target_state = dev->last_state; 114 /* Update cpuidle counters */
118 115 /* This can be moved to within driver enter routine
119 target_state->time += (unsigned long long)dev->last_residency; 116 * but that results in multiple copies of same code.
120 target_state->usage++; 117 */
118 dev->states[entered_state].time +=
119 (unsigned long long)dev->last_residency;
120 dev->states[entered_state].usage++;
121 }
121 122
122 /* give the governor an opportunity to reflect on the outcome */ 123 /* give the governor an opportunity to reflect on the outcome */
123 if (cpuidle_curr_governor->reflect) 124 if (cpuidle_curr_governor->reflect)
124 cpuidle_curr_governor->reflect(dev); 125 cpuidle_curr_governor->reflect(dev, entered_state);
125 126
126 return 0; 127 return 0;
127} 128}
@@ -172,11 +173,10 @@ void cpuidle_resume_and_unlock(void)
172EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); 173EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
173 174
174#ifdef CONFIG_ARCH_HAS_CPU_RELAX 175#ifdef CONFIG_ARCH_HAS_CPU_RELAX
175static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) 176static int poll_idle(struct cpuidle_device *dev, int index)
176{ 177{
177 ktime_t t1, t2; 178 ktime_t t1, t2;
178 s64 diff; 179 s64 diff;
179 int ret;
180 180
181 t1 = ktime_get(); 181 t1 = ktime_get();
182 local_irq_enable(); 182 local_irq_enable();
@@ -188,8 +188,9 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
188 if (diff > INT_MAX) 188 if (diff > INT_MAX)
189 diff = INT_MAX; 189 diff = INT_MAX;
190 190
191 ret = (int) diff; 191 dev->last_residency = (int) diff;
192 return ret; 192
193 return index;
193} 194}
194 195
195static void poll_idle_init(struct cpuidle_device *dev) 196static void poll_idle_init(struct cpuidle_device *dev)
@@ -248,7 +249,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
248 dev->states[i].time = 0; 249 dev->states[i].time = 0;
249 } 250 }
250 dev->last_residency = 0; 251 dev->last_residency = 0;
251 dev->last_state = NULL;
252 252
253 smp_wmb(); 253 smp_wmb();
254 254
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 12c98900dcf8..6a686a76711f 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -153,11 +153,24 @@ static int ladder_enable_device(struct cpuidle_device *dev)
153 return 0; 153 return 0;
154} 154}
155 155
156/**
157 * ladder_reflect - update the correct last_state_idx
158 * @dev: the CPU
159 * @index: the index of actual state entered
160 */
161static void ladder_reflect(struct cpuidle_device *dev, int index)
162{
163 struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
164 if (index > 0)
165 ldev->last_state_idx = index;
166}
167
156static struct cpuidle_governor ladder_governor = { 168static struct cpuidle_governor ladder_governor = {
157 .name = "ladder", 169 .name = "ladder",
158 .rating = 10, 170 .rating = 10,
159 .enable = ladder_enable_device, 171 .enable = ladder_enable_device,
160 .select = ladder_select_state, 172 .select = ladder_select_state,
173 .reflect = ladder_reflect,
161 .owner = THIS_MODULE, 174 .owner = THIS_MODULE,
162}; 175};
163 176
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index c47f3d09c1ee..e4b200c5b441 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -310,14 +310,17 @@ static int menu_select(struct cpuidle_device *dev)
310/** 310/**
311 * menu_reflect - records that data structures need update 311 * menu_reflect - records that data structures need update
312 * @dev: the CPU 312 * @dev: the CPU
313 * @index: the index of actual entered state
313 * 314 *
314 * NOTE: it's important to be fast here because this operation will add to 315 * NOTE: it's important to be fast here because this operation will add to
315 * the overall exit latency. 316 * the overall exit latency.
316 */ 317 */
317static void menu_reflect(struct cpuidle_device *dev) 318static void menu_reflect(struct cpuidle_device *dev, int index)
318{ 319{
319 struct menu_device *data = &__get_cpu_var(menu_devices); 320 struct menu_device *data = &__get_cpu_var(menu_devices);
320 data->needs_update = 1; 321 data->last_state_idx = index;
322 if (index >= 0)
323 data->needs_update = 1;
321} 324}
322 325
323/** 326/**
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index a46dddf61078..a1c888d2216a 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -81,7 +81,7 @@ static unsigned int mwait_substates;
81static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ 81static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
82 82
83static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 83static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
84static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); 84static int intel_idle(struct cpuidle_device *dev, int index);
85 85
86static struct cpuidle_state *cpuidle_state_table; 86static struct cpuidle_state *cpuidle_state_table;
87 87
@@ -209,12 +209,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
209/** 209/**
210 * intel_idle 210 * intel_idle
211 * @dev: cpuidle_device 211 * @dev: cpuidle_device
212 * @state: cpuidle state 212 * @index: index of cpuidle state
213 * 213 *
214 */ 214 */
215static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) 215static int intel_idle(struct cpuidle_device *dev, int index)
216{ 216{
217 unsigned long ecx = 1; /* break on interrupt flag */ 217 unsigned long ecx = 1; /* break on interrupt flag */
218 struct cpuidle_state *state = &dev->states[index];
218 unsigned long eax = (unsigned long)cpuidle_get_statedata(state); 219 unsigned long eax = (unsigned long)cpuidle_get_statedata(state);
219 unsigned int cstate; 220 unsigned int cstate;
220 ktime_t kt_before, kt_after; 221 ktime_t kt_before, kt_after;
@@ -256,7 +257,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
256 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 257 if (!(lapic_timer_reliable_states & (1 << (cstate))))
257 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); 258 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
258 259
259 return usec_delta; 260 /* Update cpuidle counters */
261 dev->last_residency = (int)usec_delta;
262
263 return index;
260} 264}
261 265
262static void __setup_broadcast_timer(void *arg) 266static void __setup_broadcast_timer(void *arg)