2 * menu.c - the menu idle governor
4 * Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
6 * This code is licenced under the GPL.
9 #include <linux/kernel.h>
10 #include <linux/cpuidle.h>
11 #include <linux/pm_qos_params.h>
12 #include <linux/time.h>
13 #include <linux/ktime.h>
14 #include <linux/hrtimer.h>
15 #include <linux/tick.h>
17 #define BREAK_FUZZ 4 /* 4 us */
18 #define PRED_HISTORY_PCT 50
23 unsigned int expected_us
;
24 unsigned int predicted_us
;
25 unsigned int current_predicted_us
;
26 unsigned int last_measured_us
;
27 unsigned int elapsed_us
;
30 static DEFINE_PER_CPU(struct menu_device
, menu_devices
);
33 * menu_select - selects the next idle state to enter
36 static int menu_select(struct cpuidle_device
*dev
)
38 struct menu_device
*data
= &__get_cpu_var(menu_devices
);
39 int latency_req
= pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY
);
42 /* Special case when user has set very strict latency requirement */
43 if (unlikely(latency_req
== 0)) {
44 data
->last_state_idx
= 0;
48 /* determine the expected residency time */
50 (u32
) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
52 /* Recalculate predicted_us based on prediction_history_pct */
53 data
->predicted_us
*= PRED_HISTORY_PCT
;
54 data
->predicted_us
+= (100 - PRED_HISTORY_PCT
) *
55 data
->current_predicted_us
;
56 data
->predicted_us
/= 100;
58 /* find the deepest idle state that satisfies our constraints */
59 for (i
= CPUIDLE_DRIVER_STATE_START
+ 1; i
< dev
->state_count
; i
++) {
60 struct cpuidle_state
*s
= &dev
->states
[i
];
62 if (s
->target_residency
> data
->expected_us
)
64 if (s
->target_residency
> data
->predicted_us
)
66 if (s
->exit_latency
> latency_req
)
70 data
->last_state_idx
= i
- 1;
75 * menu_reflect - attempts to guess what happened after entry
78 * NOTE: it's important to be fast here because this operation will add to
79 * the overall exit latency.
81 static void menu_reflect(struct cpuidle_device
*dev
)
83 struct menu_device
*data
= &__get_cpu_var(menu_devices
);
84 int last_idx
= data
->last_state_idx
;
85 unsigned int last_idle_us
= cpuidle_get_last_residency(dev
);
86 struct cpuidle_state
*target
= &dev
->states
[last_idx
];
87 unsigned int measured_us
;
90 * Ugh, this idle state doesn't support residency measurements, so we
91 * are basically lost in the dark. As a compromise, assume we slept
92 * for one full standard timer tick. However, be aware that this
93 * could potentially result in a suboptimal state transition.
95 if (unlikely(!(target
->flags
& CPUIDLE_FLAG_TIME_VALID
)))
96 last_idle_us
= USEC_PER_SEC
/ HZ
;
99 * measured_us and elapsed_us are the cumulative idle time, since the
100 * last time we were woken out of idle by an interrupt.
102 if (data
->elapsed_us
<= data
->elapsed_us
+ last_idle_us
)
103 measured_us
= data
->elapsed_us
+ last_idle_us
;
107 /* Predict time until next break event */
108 data
->current_predicted_us
= max(measured_us
, data
->last_measured_us
);
110 if (last_idle_us
+ BREAK_FUZZ
<
111 data
->expected_us
- target
->exit_latency
) {
112 data
->last_measured_us
= measured_us
;
113 data
->elapsed_us
= 0;
115 data
->elapsed_us
= measured_us
;
120 * menu_enable_device - scans a CPU's states and does setup
123 static int menu_enable_device(struct cpuidle_device
*dev
)
125 struct menu_device
*data
= &per_cpu(menu_devices
, dev
->cpu
);
127 memset(data
, 0, sizeof(struct menu_device
));
132 static struct cpuidle_governor menu_governor
= {
135 .enable
= menu_enable_device
,
136 .select
= menu_select
,
137 .reflect
= menu_reflect
,
138 .owner
= THIS_MODULE
,
142 * init_menu - initializes the governor
144 static int __init
init_menu(void)
146 return cpuidle_register_governor(&menu_governor
);
150 * exit_menu - exits the governor
152 static void __exit
exit_menu(void)
154 cpuidle_unregister_governor(&menu_governor
);
157 MODULE_LICENSE("GPL");
158 module_init(init_menu
);
159 module_exit(exit_menu
);