diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-05-30 07:43:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-05-30 17:13:00 -0400 |
commit | 0fc784fb09f6db8d6650aac137daa779da25c73b (patch) | |
tree | 2896a3243e31b5a220acbad7fb11c6a828243273 | |
parent | cf7eeea947efaf2348dd87542508b1d426b948cd (diff) |
cpuidle: governors: Consolidate PM QoS handling
There is some code duplication related to the PM QoS handling between
the existing cpuidle governors, so move that code to a common helper
function and call that from the governors.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpuidle/governor.c | 17 | ||||
-rw-r--r-- | drivers/cpuidle/governors/ladder.c | 9 | ||||
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 9 | ||||
-rw-r--r-- | include/linux/cpuidle.h | 1 |
4 files changed, 19 insertions, 17 deletions
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index 5d359aff3cc5..9fed1b829292 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c | |||
@@ -8,8 +8,10 @@ | |||
8 | * This code is licenced under the GPL. | 8 | * This code is licenced under the GPL. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/mutex.h> | 11 | #include <linux/cpu.h> |
12 | #include <linux/cpuidle.h> | 12 | #include <linux/cpuidle.h> |
13 | #include <linux/mutex.h> | ||
14 | #include <linux/pm_qos.h> | ||
13 | 15 | ||
14 | #include "cpuidle.h" | 16 | #include "cpuidle.h" |
15 | 17 | ||
@@ -93,3 +95,16 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) | |||
93 | 95 | ||
94 | return ret; | 96 | return ret; |
95 | } | 97 | } |
98 | |||
99 | /** | ||
100 | * cpuidle_governor_latency_req - Compute a latency constraint for CPU | ||
101 | * @cpu: Target CPU | ||
102 | */ | ||
103 | int cpuidle_governor_latency_req(unsigned int cpu) | ||
104 | { | ||
105 | int global_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | ||
106 | struct device *device = get_cpu_device(cpu); | ||
107 | int device_req = dev_pm_qos_raw_read_value(device); | ||
108 | |||
109 | return device_req < global_req ? device_req : global_req; | ||
110 | } | ||
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 060db5182bdb..704880a6612a 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c | |||
@@ -14,10 +14,8 @@ | |||
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/cpuidle.h> | 16 | #include <linux/cpuidle.h> |
17 | #include <linux/pm_qos.h> | ||
18 | #include <linux/jiffies.h> | 17 | #include <linux/jiffies.h> |
19 | #include <linux/tick.h> | 18 | #include <linux/tick.h> |
20 | #include <linux/cpu.h> | ||
21 | 19 | ||
22 | #include <asm/io.h> | 20 | #include <asm/io.h> |
23 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
@@ -69,15 +67,10 @@ static int ladder_select_state(struct cpuidle_driver *drv, | |||
69 | struct cpuidle_device *dev, bool *dummy) | 67 | struct cpuidle_device *dev, bool *dummy) |
70 | { | 68 | { |
71 | struct ladder_device *ldev = this_cpu_ptr(&ladder_devices); | 69 | struct ladder_device *ldev = this_cpu_ptr(&ladder_devices); |
72 | struct device *device = get_cpu_device(dev->cpu); | ||
73 | struct ladder_device_state *last_state; | 70 | struct ladder_device_state *last_state; |
74 | int last_residency, last_idx = ldev->last_state_idx; | 71 | int last_residency, last_idx = ldev->last_state_idx; |
75 | int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0; | 72 | int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0; |
76 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | 73 | int latency_req = cpuidle_governor_latency_req(dev->cpu); |
77 | int resume_latency = dev_pm_qos_raw_read_value(device); | ||
78 | |||
79 | if (resume_latency < latency_req) | ||
80 | latency_req = resume_latency; | ||
81 | 74 | ||
82 | /* Special case when user has set very strict latency requirement */ | 75 | /* Special case when user has set very strict latency requirement */ |
83 | if (unlikely(latency_req == 0)) { | 76 | if (unlikely(latency_req == 0)) { |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 5d15bc0ba2e0..1aef60d160eb 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/cpuidle.h> | 14 | #include <linux/cpuidle.h> |
15 | #include <linux/pm_qos.h> | ||
16 | #include <linux/time.h> | 15 | #include <linux/time.h> |
17 | #include <linux/ktime.h> | 16 | #include <linux/ktime.h> |
18 | #include <linux/hrtimer.h> | 17 | #include <linux/hrtimer.h> |
@@ -21,7 +20,6 @@ | |||
21 | #include <linux/sched/loadavg.h> | 20 | #include <linux/sched/loadavg.h> |
22 | #include <linux/sched/stat.h> | 21 | #include <linux/sched/stat.h> |
23 | #include <linux/math64.h> | 22 | #include <linux/math64.h> |
24 | #include <linux/cpu.h> | ||
25 | 23 | ||
26 | /* | 24 | /* |
27 | * Please note when changing the tuning values: | 25 | * Please note when changing the tuning values: |
@@ -286,15 +284,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, | |||
286 | bool *stop_tick) | 284 | bool *stop_tick) |
287 | { | 285 | { |
288 | struct menu_device *data = this_cpu_ptr(&menu_devices); | 286 | struct menu_device *data = this_cpu_ptr(&menu_devices); |
289 | struct device *device = get_cpu_device(dev->cpu); | 287 | int latency_req = cpuidle_governor_latency_req(dev->cpu); |
290 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | ||
291 | int i; | 288 | int i; |
292 | int first_idx; | 289 | int first_idx; |
293 | int idx; | 290 | int idx; |
294 | unsigned int interactivity_req; | 291 | unsigned int interactivity_req; |
295 | unsigned int expected_interval; | 292 | unsigned int expected_interval; |
296 | unsigned long nr_iowaiters, cpu_load; | 293 | unsigned long nr_iowaiters, cpu_load; |
297 | int resume_latency = dev_pm_qos_raw_read_value(device); | ||
298 | ktime_t delta_next; | 294 | ktime_t delta_next; |
299 | 295 | ||
300 | if (data->needs_update) { | 296 | if (data->needs_update) { |
@@ -302,9 +298,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, | |||
302 | data->needs_update = 0; | 298 | data->needs_update = 0; |
303 | } | 299 | } |
304 | 300 | ||
305 | if (resume_latency < latency_req) | ||
306 | latency_req = resume_latency; | ||
307 | |||
308 | /* Special case when user has set very strict latency requirement */ | 301 | /* Special case when user has set very strict latency requirement */ |
309 | if (unlikely(latency_req == 0)) { | 302 | if (unlikely(latency_req == 0)) { |
310 | *stop_tick = false; | 303 | *stop_tick = false; |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 1eefabf1621f..4325d6fdde9b 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -258,6 +258,7 @@ struct cpuidle_governor { | |||
258 | 258 | ||
259 | #ifdef CONFIG_CPU_IDLE | 259 | #ifdef CONFIG_CPU_IDLE |
260 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); | 260 | extern int cpuidle_register_governor(struct cpuidle_governor *gov); |
261 | extern int cpuidle_governor_latency_req(unsigned int cpu); | ||
261 | #else | 262 | #else |
262 | static inline int cpuidle_register_governor(struct cpuidle_governor *gov) | 263 | static inline int cpuidle_register_governor(struct cpuidle_governor *gov) |
263 | {return 0;} | 264 | {return 0;} |