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"
This commit is contained in:
+1
-1
@@ -33,7 +33,7 @@ static DEFINE_SPINLOCK(freezer_lock);
|
||||
*/
|
||||
bool freezing_slow_path(struct task_struct *p)
|
||||
{
|
||||
if (p->flags & PF_NOFREEZE)
|
||||
if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
|
||||
return false;
|
||||
|
||||
if (pm_nosig_freezing || cgroup_freezing(p))
|
||||
|
||||
@@ -109,6 +109,8 @@ static int try_to_freeze_tasks(bool user_only)
|
||||
|
||||
/**
|
||||
* freeze_processes - Signal user space processes to enter the refrigerator.
|
||||
* The current thread will not be frozen. The same process that calls
|
||||
* freeze_processes must later call thaw_processes.
|
||||
*
|
||||
* On success, returns 0. On failure, -errno and system is fully thawed.
|
||||
*/
|
||||
@@ -120,6 +122,9 @@ int freeze_processes(void)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Make sure this task doesn't get frozen */
|
||||
current->flags |= PF_SUSPEND_TASK;
|
||||
|
||||
if (!pm_freezing)
|
||||
atomic_inc(&system_freezing_cnt);
|
||||
|
||||
@@ -168,6 +173,7 @@ int freeze_kernel_threads(void)
|
||||
void thaw_processes(void)
|
||||
{
|
||||
struct task_struct *g, *p;
|
||||
struct task_struct *curr = current;
|
||||
|
||||
if (pm_freezing)
|
||||
atomic_dec(&system_freezing_cnt);
|
||||
@@ -182,10 +188,15 @@ void thaw_processes(void)
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(g, p) {
|
||||
/* No other threads should have PF_SUSPEND_TASK set */
|
||||
WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK));
|
||||
__thaw_task(p);
|
||||
} while_each_thread(g, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
WARN_ON(!(curr->flags & PF_SUSPEND_TASK));
|
||||
curr->flags &= ~PF_SUSPEND_TASK;
|
||||
|
||||
usermodehelper_enable();
|
||||
|
||||
schedule();
|
||||
|
||||
@@ -827,13 +827,10 @@ void tick_nohz_irq_exit(void)
|
||||
{
|
||||
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
|
||||
|
||||
if (ts->inidle) {
|
||||
/* Cancel the timer because CPU already waken up from the C-states*/
|
||||
menu_hrtimer_cancel();
|
||||
if (ts->inidle)
|
||||
__tick_nohz_idle_enter(ts);
|
||||
} else {
|
||||
else
|
||||
tick_nohz_full_stop_tick(ts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -931,8 +928,6 @@ void tick_nohz_idle_exit(void)
|
||||
|
||||
ts->inidle = 0;
|
||||
|
||||
/* Cancel the timer because CPU already waken up from the C-states*/
|
||||
menu_hrtimer_cancel();
|
||||
if (ts->idle_active || ts->tick_stopped)
|
||||
now = ktime_get();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user