Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm+acpi-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management fixes from Rafael Wysocki:

- Revert two cpuidle commits added during the 3.8 development cycle
that turn out to have introduced a significant performance regression
as requested by Jeremy Eder.

- The recent patches that made the freezer less heavy-weight introduced
a regression causing user-space-driven hibernation using the ioctl()
interface to block indefinitely when the hibernate process executes
try_to_freeze(). Fix from Colin Cross addresses this by adding a
process flag to mark the hibernate/suspend process to inform the
freezer that that process should be ignored.

- One of the recent cpufreq reverts uncovered a problem in the core
causing the cpufreq driver module refcount to become negative after a
system suspend-resume cycle. Fix from Rafael J Wysocki.

- The evaluation of the ACPI battery _BIX method has never worked
correctly, because the commit that added support for it forgot to
take the "Revision" field in the return package into account. As a
result, the reading of battery info doesn't work at all on some
systems, which is addressed by a fix from Lan Tianyu.

* tag 'pm+acpi-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
freezer: set PF_SUSPEND_TASK flag on tasks that call freeze_processes
ACPI / battery: Fix parsing _BIX return value
cpufreq: Fix cpufreq driver module refcount balance after suspend/resume
Revert "cpuidle: Quickly notice prediction failure for repeat mode"
Revert "cpuidle: Quickly notice prediction failure in general case"

+31 -125
+2
drivers/acpi/battery.c
··· 117 117 struct acpi_device *device; 118 118 struct notifier_block pm_nb; 119 119 unsigned long update_time; 120 + int revision; 120 121 int rate_now; 121 122 int capacity_now; 122 123 int voltage_now; ··· 360 359 }; 361 360 362 361 static struct acpi_offsets extended_info_offsets[] = { 362 + {offsetof(struct acpi_battery, revision), 0}, 363 363 {offsetof(struct acpi_battery, power_unit), 0}, 364 364 {offsetof(struct acpi_battery, design_capacity), 0}, 365 365 {offsetof(struct acpi_battery, full_charge_capacity), 0},
+10 -9
drivers/cpufreq/cpufreq.c
··· 1177 1177 __func__, cpu_dev->id, cpu); 1178 1178 } 1179 1179 1180 - if ((cpus == 1) && (cpufreq_driver->target)) 1181 - __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); 1182 - 1183 - pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); 1184 - cpufreq_cpu_put(data); 1185 - 1186 1180 /* If cpu is last user of policy, free policy */ 1187 1181 if (cpus == 1) { 1182 + if (cpufreq_driver->target) 1183 + __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); 1184 + 1188 1185 lock_policy_rwsem_read(cpu); 1189 1186 kobj = &data->kobj; 1190 1187 cmp = &data->kobj_unregister; ··· 1202 1205 free_cpumask_var(data->related_cpus); 1203 1206 free_cpumask_var(data->cpus); 1204 1207 kfree(data); 1205 - } else if (cpufreq_driver->target) { 1206 - __cpufreq_governor(data, CPUFREQ_GOV_START); 1207 - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); 1208 + } else { 1209 + pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); 1210 + cpufreq_cpu_put(data); 1211 + if (cpufreq_driver->target) { 1212 + __cpufreq_governor(data, CPUFREQ_GOV_START); 1213 + __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); 1214 + } 1208 1215 } 1209 1216 1210 1217 per_cpu(cpufreq_policy_cpu, cpu) = -1;
+4 -102
drivers/cpuidle/governors/menu.c
··· 28 28 #define MAX_INTERESTING 50000 29 29 #define STDDEV_THRESH 400 30 30 31 - /* 60 * 60 > STDDEV_THRESH * INTERVALS = 400 * 8 */ 32 - #define MAX_DEVIATION 60 33 - 34 - static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer); 35 - static DEFINE_PER_CPU(int, hrtimer_status); 36 - /* menu hrtimer mode */ 37 - enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL}; 38 31 39 32 /* 40 33 * Concepts and ideas behind the menu governor ··· 108 115 * represented in the system load average. 109 116 * 110 117 */ 111 - 112 - /* 113 - * The C-state residency is so long that is is worthwhile to exit 114 - * from the shallow C-state and re-enter into a deeper C-state. 115 - */ 116 - static unsigned int perfect_cstate_ms __read_mostly = 30; 117 - module_param(perfect_cstate_ms, uint, 0000); 118 118 119 119 struct menu_device { 120 120 int last_state_idx; ··· 191 205 return div_u64(dividend + (divisor / 2), divisor); 192 206 } 193 207 194 - /* Cancel the hrtimer if it is not triggered yet */ 195 - void menu_hrtimer_cancel(void) 196 - { 197 - int cpu = smp_processor_id(); 198 - struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu); 199 - 200 - /* The timer is still not time out*/ 201 - if (per_cpu(hrtimer_status, cpu)) { 202 - hrtimer_cancel(hrtmr); 203 - per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; 204 - } 205 - } 206 - EXPORT_SYMBOL_GPL(menu_hrtimer_cancel); 207 - 208 - /* Call back for hrtimer is triggered */ 209 - static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) 210 - { 211 - int cpu = smp_processor_id(); 212 - struct menu_device *data = &per_cpu(menu_devices, cpu); 213 - 214 - /* In general case, the expected residency is much larger than 215 - * deepest C-state target residency, but prediction logic still 216 - * predicts a small predicted residency, so the prediction 217 - * history is totally broken if the timer is triggered. 218 - * So reset the correction factor. 219 - */ 220 - if (per_cpu(hrtimer_status, cpu) == MENU_HRTIMER_GENERAL) 221 - data->correction_factor[data->bucket] = RESOLUTION * DECAY; 222 - 223 - per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; 224 - 225 - return HRTIMER_NORESTART; 226 - } 227 - 228 208 /* 229 209 * Try detecting repeating patterns by keeping track of the last 8 230 210 * intervals, and checking if the standard deviation of that set 231 211 * of points is below a threshold. If it is... then use the 232 212 * average of these 8 points as the estimated value. 233 213 */ 234 - static u32 get_typical_interval(struct menu_device *data) 214 + static void get_typical_interval(struct menu_device *data) 235 215 { 236 216 int i = 0, divisor = 0; 237 217 uint64_t max = 0, avg = 0, stddev = 0; 238 218 int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */ 239 - unsigned int ret = 0; 240 219 241 220 again: 242 221 ··· 242 291 if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3)) 243 292 || stddev <= 20) { 244 293 data->predicted_us = avg; 245 - ret = 1; 246 - return ret; 294 + return; 247 295 248 296 } else if ((divisor * 4) > INTERVALS * 3) { 249 297 /* Exclude the max interval */ 250 298 thresh = max - 1; 251 299 goto again; 252 300 } 253 - 254 - return ret; 255 301 } 256 302 257 303 /** ··· 263 315 int i; 264 316 int multiplier; 265 317 struct timespec t; 266 - int repeat = 0, low_predicted = 0; 267 - int cpu = smp_processor_id(); 268 - struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu); 269 318 270 319 if (data->needs_update) { 271 320 menu_update(drv, dev); ··· 297 352 data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], 298 353 RESOLUTION * DECAY); 299 354 300 - repeat = get_typical_interval(data); 355 + get_typical_interval(data); 301 356 302 357 /* 303 358 * We want to default to C1 (hlt), not to busy polling ··· 318 373 319 374 if (s->disabled || su->disable) 320 375 continue; 321 - if (s->target_residency > data->predicted_us) { 322 - low_predicted = 1; 376 + if (s->target_residency > data->predicted_us) 323 377 continue; 324 - } 325 378 if (s->exit_latency > latency_req) 326 379 continue; 327 380 if (s->exit_latency * multiplier > data->predicted_us) ··· 327 384 328 385 data->last_state_idx = i; 329 386 data->exit_us = s->exit_latency; 330 - } 331 - 332 - /* not deepest C-state chosen for low predicted residency */ 333 - if (low_predicted) { 334 - unsigned int timer_us = 0; 335 - unsigned int perfect_us = 0; 336 - 337 - /* 338 - * Set a timer to detect whether this sleep is much 339 - * longer than repeat mode predicted. If the timer 340 - * triggers, the code will evaluate whether to put 341 - * the CPU into a deeper C-state. 342 - * The timer is cancelled on CPU wakeup. 343 - */ 344 - timer_us = 2 * (data->predicted_us + MAX_DEVIATION); 345 - 346 - perfect_us = perfect_cstate_ms * 1000; 347 - 348 - if (repeat && (4 * timer_us < data->expected_us)) { 349 - RCU_NONIDLE(hrtimer_start(hrtmr, 350 - ns_to_ktime(1000 * timer_us), 351 - HRTIMER_MODE_REL_PINNED)); 352 - /* In repeat case, menu hrtimer is started */ 353 - per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT; 354 - } else if (perfect_us < data->expected_us) { 355 - /* 356 - * The next timer is long. This could be because 357 - * we did not make a useful prediction. 358 - * In that case, it makes sense to re-enter 359 - * into a deeper C-state after some time. 360 - */ 361 - RCU_NONIDLE(hrtimer_start(hrtmr, 362 - ns_to_ktime(1000 * timer_us), 363 - HRTIMER_MODE_REL_PINNED)); 364 - /* In general case, menu hrtimer is started */ 365 - per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_GENERAL; 366 - } 367 - 368 387 } 369 388 370 389 return data->last_state_idx; ··· 419 514 struct cpuidle_device *dev) 420 515 { 421 516 struct menu_device *data = &per_cpu(menu_devices, dev->cpu); 422 - struct hrtimer *t = &per_cpu(menu_hrtimer, dev->cpu); 423 - hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 424 - t->function = menu_hrtimer_notify; 425 517 426 518 memset(data, 0, sizeof(struct menu_device)); 427 519
+1
include/linux/sched.h
··· 1628 1628 #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ 1629 1629 #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ 1630 1630 #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ 1631 + #define PF_SUSPEND_TASK 0x80000000 /* this thread called freeze_processes and should not be frozen */ 1631 1632 1632 1633 /* 1633 1634 * Only the _current_ task can read/write to tsk->flags, but other
-6
include/linux/tick.h
··· 174 174 #endif 175 175 176 176 177 - # ifdef CONFIG_CPU_IDLE_GOV_MENU 178 - extern void menu_hrtimer_cancel(void); 179 - # else 180 - static inline void menu_hrtimer_cancel(void) {} 181 - # endif /* CONFIG_CPU_IDLE_GOV_MENU */ 182 - 183 177 #endif
+1 -1
kernel/freezer.c
··· 33 33 */ 34 34 bool freezing_slow_path(struct task_struct *p) 35 35 { 36 - if (p->flags & PF_NOFREEZE) 36 + if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK)) 37 37 return false; 38 38 39 39 if (pm_nosig_freezing || cgroup_freezing(p))
+11
kernel/power/process.c
··· 109 109 110 110 /** 111 111 * freeze_processes - Signal user space processes to enter the refrigerator. 112 + * The current thread will not be frozen. The same process that calls 113 + * freeze_processes must later call thaw_processes. 112 114 * 113 115 * On success, returns 0. On failure, -errno and system is fully thawed. 114 116 */ ··· 121 119 error = __usermodehelper_disable(UMH_FREEZING); 122 120 if (error) 123 121 return error; 122 + 123 + /* Make sure this task doesn't get frozen */ 124 + current->flags |= PF_SUSPEND_TASK; 124 125 125 126 if (!pm_freezing) 126 127 atomic_inc(&system_freezing_cnt); ··· 173 168 void thaw_processes(void) 174 169 { 175 170 struct task_struct *g, *p; 171 + struct task_struct *curr = current; 176 172 177 173 if (pm_freezing) 178 174 atomic_dec(&system_freezing_cnt); ··· 188 182 189 183 read_lock(&tasklist_lock); 190 184 do_each_thread(g, p) { 185 + /* No other threads should have PF_SUSPEND_TASK set */ 186 + WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK)); 191 187 __thaw_task(p); 192 188 } while_each_thread(g, p); 193 189 read_unlock(&tasklist_lock); 190 + 191 + WARN_ON(!(curr->flags & PF_SUSPEND_TASK)); 192 + curr->flags &= ~PF_SUSPEND_TASK; 194 193 195 194 usermodehelper_enable(); 196 195
+2 -7
kernel/time/tick-sched.c
··· 827 827 { 828 828 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); 829 829 830 - if (ts->inidle) { 831 - /* Cancel the timer because CPU already waken up from the C-states*/ 832 - menu_hrtimer_cancel(); 830 + if (ts->inidle) 833 831 __tick_nohz_idle_enter(ts); 834 - } else { 832 + else 835 833 tick_nohz_full_stop_tick(ts); 836 - } 837 834 } 838 835 839 836 /** ··· 928 931 929 932 ts->inidle = 0; 930 933 931 - /* Cancel the timer because CPU already waken up from the C-states*/ 932 - menu_hrtimer_cancel(); 933 934 if (ts->idle_active || ts->tick_stopped) 934 935 now = ktime_get(); 935 936