diff options
-rw-r--r-- | drivers/cpufreq/arm_big_little.c | 5 | ||||
-rw-r--r-- | drivers/cpufreq/arm_big_little_dt.c | 2 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq-cpu0.c | 2 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_opp.c | 2 | ||||
-rw-r--r-- | drivers/cpufreq/integrator-cpufreq.c | 10 | ||||
-rw-r--r-- | drivers/cpufreq/speedstep-smi.c | 4 | ||||
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 43 | ||||
-rw-r--r-- | include/linux/sched.h | 3 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 21 | ||||
-rw-r--r-- | kernel/sched/core.c | 7 | ||||
-rw-r--r-- | kernel/sched/proc.c | 7 |
11 files changed, 66 insertions, 40 deletions
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 1f4d4e315057..a46c223c2506 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpufreq.h> | 24 | #include <linux/cpufreq.h> |
25 | #include <linux/cpumask.h> | 25 | #include <linux/cpumask.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | #include <linux/module.h> | ||
27 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
28 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
29 | #include <linux/pm_opp.h> | 30 | #include <linux/pm_opp.h> |
@@ -593,3 +594,7 @@ void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops) | |||
593 | arm_bL_ops = NULL; | 594 | arm_bL_ops = NULL; |
594 | } | 595 | } |
595 | EXPORT_SYMBOL_GPL(bL_cpufreq_unregister); | 596 | EXPORT_SYMBOL_GPL(bL_cpufreq_unregister); |
597 | |||
598 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); | ||
599 | MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver"); | ||
600 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 8d9d59108906..4550f6976768 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c | |||
@@ -114,4 +114,4 @@ module_platform_driver(generic_bL_platdrv); | |||
114 | 114 | ||
115 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); | 115 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); |
116 | MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); | 116 | MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); |
117 | MODULE_LICENSE("GPL"); | 117 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 86beda9f950b..0d2172b07765 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
@@ -137,7 +137,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
137 | * not yet registered, we should try defering probe. | 137 | * not yet registered, we should try defering probe. |
138 | */ | 138 | */ |
139 | if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { | 139 | if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { |
140 | dev_err(cpu_dev, "cpu0 regulator not ready, retry\n"); | 140 | dev_dbg(cpu_dev, "cpu0 regulator not ready, retry\n"); |
141 | ret = -EPROBE_DEFER; | 141 | ret = -EPROBE_DEFER; |
142 | goto out_put_node; | 142 | goto out_put_node; |
143 | } | 143 | } |
diff --git a/drivers/cpufreq/cpufreq_opp.c b/drivers/cpufreq/cpufreq_opp.c index c0c6f4a4eccf..f7a32d2326c6 100644 --- a/drivers/cpufreq/cpufreq_opp.c +++ b/drivers/cpufreq/cpufreq_opp.c | |||
@@ -60,7 +60,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, | |||
60 | goto out; | 60 | goto out; |
61 | } | 61 | } |
62 | 62 | ||
63 | freq_table = kzalloc(sizeof(*freq_table) * (max_opps + 1), GFP_KERNEL); | 63 | freq_table = kcalloc(sizeof(*freq_table), (max_opps + 1), GFP_ATOMIC); |
64 | if (!freq_table) { | 64 | if (!freq_table) { |
65 | ret = -ENOMEM; | 65 | ret = -ENOMEM; |
66 | goto out; | 66 | goto out; |
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index e5122f1bfe78..c1320528b9d0 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c | |||
@@ -92,7 +92,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, | |||
92 | * Bind to the specified CPU. When this call returns, | 92 | * Bind to the specified CPU. When this call returns, |
93 | * we should be running on the right CPU. | 93 | * we should be running on the right CPU. |
94 | */ | 94 | */ |
95 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 95 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
96 | BUG_ON(cpu != smp_processor_id()); | 96 | BUG_ON(cpu != smp_processor_id()); |
97 | 97 | ||
98 | /* get current setting */ | 98 | /* get current setting */ |
@@ -118,7 +118,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, | |||
118 | freqs.new = icst_hz(&cclk_params, vco) / 1000; | 118 | freqs.new = icst_hz(&cclk_params, vco) / 1000; |
119 | 119 | ||
120 | if (freqs.old == freqs.new) { | 120 | if (freqs.old == freqs.new) { |
121 | set_cpus_allowed(current, cpus_allowed); | 121 | set_cpus_allowed_ptr(current, &cpus_allowed); |
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
@@ -141,7 +141,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, | |||
141 | /* | 141 | /* |
142 | * Restore the CPUs allowed mask. | 142 | * Restore the CPUs allowed mask. |
143 | */ | 143 | */ |
144 | set_cpus_allowed(current, cpus_allowed); | 144 | set_cpus_allowed_ptr(current, &cpus_allowed); |
145 | 145 | ||
146 | cpufreq_freq_transition_end(policy, &freqs, 0); | 146 | cpufreq_freq_transition_end(policy, &freqs, 0); |
147 | 147 | ||
@@ -157,7 +157,7 @@ static unsigned int integrator_get(unsigned int cpu) | |||
157 | 157 | ||
158 | cpus_allowed = current->cpus_allowed; | 158 | cpus_allowed = current->cpus_allowed; |
159 | 159 | ||
160 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 160 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
161 | BUG_ON(cpu != smp_processor_id()); | 161 | BUG_ON(cpu != smp_processor_id()); |
162 | 162 | ||
163 | /* detect memory etc. */ | 163 | /* detect memory etc. */ |
@@ -173,7 +173,7 @@ static unsigned int integrator_get(unsigned int cpu) | |||
173 | 173 | ||
174 | current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */ | 174 | current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */ |
175 | 175 | ||
176 | set_cpus_allowed(current, cpus_allowed); | 176 | set_cpus_allowed_ptr(current, &cpus_allowed); |
177 | 177 | ||
178 | return current_freq; | 178 | return current_freq; |
179 | } | 179 | } |
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index 8635eec96da5..5fc96d5d656b 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c | |||
@@ -324,8 +324,8 @@ static int __init speedstep_init(void) | |||
324 | return -ENODEV; | 324 | return -ENODEV; |
325 | } | 325 | } |
326 | 326 | ||
327 | pr_debug("signature:0x%.8ulx, command:0x%.8ulx, " | 327 | pr_debug("signature:0x%.8x, command:0x%.8x, " |
328 | "event:0x%.8ulx, perf_level:0x%.8ulx.\n", | 328 | "event:0x%.8x, perf_level:0x%.8x.\n", |
329 | ist_info.signature, ist_info.command, | 329 | ist_info.signature, ist_info.command, |
330 | ist_info.event, ist_info.perf_level); | 330 | ist_info.event, ist_info.perf_level); |
331 | 331 | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c3732fa74f82..27702742b319 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -31,7 +31,8 @@ | |||
31 | * The default values do not overflow. | 31 | * The default values do not overflow. |
32 | */ | 32 | */ |
33 | #define BUCKETS 12 | 33 | #define BUCKETS 12 |
34 | #define INTERVALS 8 | 34 | #define INTERVAL_SHIFT 3 |
35 | #define INTERVALS (1UL << INTERVAL_SHIFT) | ||
35 | #define RESOLUTION 1024 | 36 | #define RESOLUTION 1024 |
36 | #define DECAY 8 | 37 | #define DECAY 8 |
37 | #define MAX_INTERESTING 50000 | 38 | #define MAX_INTERESTING 50000 |
@@ -133,15 +134,12 @@ struct menu_device { | |||
133 | #define LOAD_INT(x) ((x) >> FSHIFT) | 134 | #define LOAD_INT(x) ((x) >> FSHIFT) |
134 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) | 135 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) |
135 | 136 | ||
136 | static int get_loadavg(void) | 137 | static inline int get_loadavg(unsigned long load) |
137 | { | 138 | { |
138 | unsigned long this = this_cpu_load(); | 139 | return LOAD_INT(load) * 10 + LOAD_FRAC(load) / 10; |
139 | |||
140 | |||
141 | return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10; | ||
142 | } | 140 | } |
143 | 141 | ||
144 | static inline int which_bucket(unsigned int duration) | 142 | static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters) |
145 | { | 143 | { |
146 | int bucket = 0; | 144 | int bucket = 0; |
147 | 145 | ||
@@ -151,7 +149,7 @@ static inline int which_bucket(unsigned int duration) | |||
151 | * This allows us to calculate | 149 | * This allows us to calculate |
152 | * E(duration)|iowait | 150 | * E(duration)|iowait |
153 | */ | 151 | */ |
154 | if (nr_iowait_cpu(smp_processor_id())) | 152 | if (nr_iowaiters) |
155 | bucket = BUCKETS/2; | 153 | bucket = BUCKETS/2; |
156 | 154 | ||
157 | if (duration < 10) | 155 | if (duration < 10) |
@@ -174,16 +172,16 @@ static inline int which_bucket(unsigned int duration) | |||
174 | * to be, the higher this multiplier, and thus the higher | 172 | * to be, the higher this multiplier, and thus the higher |
175 | * the barrier to go to an expensive C state. | 173 | * the barrier to go to an expensive C state. |
176 | */ | 174 | */ |
177 | static inline int performance_multiplier(void) | 175 | static inline int performance_multiplier(unsigned long nr_iowaiters, unsigned long load) |
178 | { | 176 | { |
179 | int mult = 1; | 177 | int mult = 1; |
180 | 178 | ||
181 | /* for higher loadavg, we are more reluctant */ | 179 | /* for higher loadavg, we are more reluctant */ |
182 | 180 | ||
183 | mult += 2 * get_loadavg(); | 181 | mult += 2 * get_loadavg(load); |
184 | 182 | ||
185 | /* for IO wait tasks (per cpu!) we add 5x each */ | 183 | /* for IO wait tasks (per cpu!) we add 5x each */ |
186 | mult += 10 * nr_iowait_cpu(smp_processor_id()); | 184 | mult += 10 * nr_iowaiters; |
187 | 185 | ||
188 | return mult; | 186 | return mult; |
189 | } | 187 | } |
@@ -227,7 +225,10 @@ again: | |||
227 | max = value; | 225 | max = value; |
228 | } | 226 | } |
229 | } | 227 | } |
230 | do_div(avg, divisor); | 228 | if (divisor == INTERVALS) |
229 | avg >>= INTERVAL_SHIFT; | ||
230 | else | ||
231 | do_div(avg, divisor); | ||
231 | 232 | ||
232 | /* Then try to determine standard deviation */ | 233 | /* Then try to determine standard deviation */ |
233 | stddev = 0; | 234 | stddev = 0; |
@@ -238,7 +239,11 @@ again: | |||
238 | stddev += diff * diff; | 239 | stddev += diff * diff; |
239 | } | 240 | } |
240 | } | 241 | } |
241 | do_div(stddev, divisor); | 242 | if (divisor == INTERVALS) |
243 | stddev >>= INTERVAL_SHIFT; | ||
244 | else | ||
245 | do_div(stddev, divisor); | ||
246 | |||
242 | /* | 247 | /* |
243 | * The typical interval is obtained when standard deviation is small | 248 | * The typical interval is obtained when standard deviation is small |
244 | * or standard deviation is small compared to the average interval. | 249 | * or standard deviation is small compared to the average interval. |
@@ -288,7 +293,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
288 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | 293 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); |
289 | int i; | 294 | int i; |
290 | unsigned int interactivity_req; | 295 | unsigned int interactivity_req; |
291 | struct timespec t; | 296 | unsigned long nr_iowaiters, cpu_load; |
292 | 297 | ||
293 | if (data->needs_update) { | 298 | if (data->needs_update) { |
294 | menu_update(drv, dev); | 299 | menu_update(drv, dev); |
@@ -302,12 +307,10 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
302 | return 0; | 307 | return 0; |
303 | 308 | ||
304 | /* determine the expected residency time, round up */ | 309 | /* determine the expected residency time, round up */ |
305 | t = ktime_to_timespec(tick_nohz_get_sleep_length()); | 310 | data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length()); |
306 | data->next_timer_us = | ||
307 | t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; | ||
308 | |||
309 | 311 | ||
310 | data->bucket = which_bucket(data->next_timer_us); | 312 | get_iowait_load(&nr_iowaiters, &cpu_load); |
313 | data->bucket = which_bucket(data->next_timer_us, nr_iowaiters); | ||
311 | 314 | ||
312 | /* | 315 | /* |
313 | * Force the result of multiplication to be 64 bits even if both | 316 | * Force the result of multiplication to be 64 bits even if both |
@@ -325,7 +328,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
325 | * duration / latency ratio. Adjust the latency limit if | 328 | * duration / latency ratio. Adjust the latency limit if |
326 | * necessary. | 329 | * necessary. |
327 | */ | 330 | */ |
328 | interactivity_req = data->predicted_us / performance_multiplier(); | 331 | interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load); |
329 | if (latency_req > interactivity_req) | 332 | if (latency_req > interactivity_req) |
330 | latency_req = interactivity_req; | 333 | latency_req = interactivity_req; |
331 | 334 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 7c19d552dc3f..84729f7c472c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -168,8 +168,7 @@ extern int nr_processes(void); | |||
168 | extern unsigned long nr_running(void); | 168 | extern unsigned long nr_running(void); |
169 | extern unsigned long nr_iowait(void); | 169 | extern unsigned long nr_iowait(void); |
170 | extern unsigned long nr_iowait_cpu(int cpu); | 170 | extern unsigned long nr_iowait_cpu(int cpu); |
171 | extern unsigned long this_cpu_load(void); | 171 | extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load); |
172 | |||
173 | 172 | ||
174 | extern void calc_global_load(unsigned long ticks); | 173 | extern void calc_global_load(unsigned long ticks); |
175 | extern void update_cpu_load_nohz(void); | 174 | extern void update_cpu_load_nohz(void); |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 4fc5c32422b3..c4b8093c80b3 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -954,6 +954,25 @@ static void mark_nosave_pages(struct memory_bitmap *bm) | |||
954 | } | 954 | } |
955 | } | 955 | } |
956 | 956 | ||
957 | static bool is_nosave_page(unsigned long pfn) | ||
958 | { | ||
959 | struct nosave_region *region; | ||
960 | |||
961 | list_for_each_entry(region, &nosave_regions, list) { | ||
962 | if (pfn >= region->start_pfn && pfn < region->end_pfn) { | ||
963 | pr_err("PM: %#010llx in e820 nosave region: " | ||
964 | "[mem %#010llx-%#010llx]\n", | ||
965 | (unsigned long long) pfn << PAGE_SHIFT, | ||
966 | (unsigned long long) region->start_pfn << PAGE_SHIFT, | ||
967 | ((unsigned long long) region->end_pfn << PAGE_SHIFT) | ||
968 | - 1); | ||
969 | return true; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | return false; | ||
974 | } | ||
975 | |||
957 | /** | 976 | /** |
958 | * create_basic_memory_bitmaps - create bitmaps needed for marking page | 977 | * create_basic_memory_bitmaps - create bitmaps needed for marking page |
959 | * frames that should not be saved and free page frames. The pointers | 978 | * frames that should not be saved and free page frames. The pointers |
@@ -2015,7 +2034,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm) | |||
2015 | do { | 2034 | do { |
2016 | pfn = memory_bm_next_pfn(bm); | 2035 | pfn = memory_bm_next_pfn(bm); |
2017 | if (likely(pfn != BM_END_OF_MAP)) { | 2036 | if (likely(pfn != BM_END_OF_MAP)) { |
2018 | if (likely(pfn_valid(pfn))) | 2037 | if (likely(pfn_valid(pfn)) && !is_nosave_page(pfn)) |
2019 | swsusp_set_page_free(pfn_to_page(pfn)); | 2038 | swsusp_set_page_free(pfn_to_page(pfn)); |
2020 | else | 2039 | else |
2021 | return -EFAULT; | 2040 | return -EFAULT; |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1211575a2208..ec1a286684a5 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2393,6 +2393,13 @@ unsigned long nr_iowait_cpu(int cpu) | |||
2393 | return atomic_read(&this->nr_iowait); | 2393 | return atomic_read(&this->nr_iowait); |
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | void get_iowait_load(unsigned long *nr_waiters, unsigned long *load) | ||
2397 | { | ||
2398 | struct rq *this = this_rq(); | ||
2399 | *nr_waiters = atomic_read(&this->nr_iowait); | ||
2400 | *load = this->cpu_load[0]; | ||
2401 | } | ||
2402 | |||
2396 | #ifdef CONFIG_SMP | 2403 | #ifdef CONFIG_SMP |
2397 | 2404 | ||
2398 | /* | 2405 | /* |
diff --git a/kernel/sched/proc.c b/kernel/sched/proc.c index 16f5a30f9c88..8ecd552fe4f2 100644 --- a/kernel/sched/proc.c +++ b/kernel/sched/proc.c | |||
@@ -8,13 +8,6 @@ | |||
8 | 8 | ||
9 | #include "sched.h" | 9 | #include "sched.h" |
10 | 10 | ||
11 | unsigned long this_cpu_load(void) | ||
12 | { | ||
13 | struct rq *this = this_rq(); | ||
14 | return this->cpu_load[0]; | ||
15 | } | ||
16 | |||
17 | |||
18 | /* | 11 | /* |
19 | * Global load-average calculations | 12 | * Global load-average calculations |
20 | * | 13 | * |