|
@@ -7097,34 +7097,66 @@ match2:
|
|
|
mutex_unlock(&sched_domains_mutex);
|
|
|
}
|
|
|
|
|
|
+static int num_cpus_frozen; /* used to mark begin/end of suspend/resume */
|
|
|
+
|
|
|
/*
|
|
|
* Update cpusets according to cpu_active mask. If cpusets are
|
|
|
* disabled, cpuset_update_active_cpus() becomes a simple wrapper
|
|
|
* around partition_sched_domains().
|
|
|
+ *
|
|
|
+ * If we come here as part of a suspend/resume, don't touch cpusets because we
|
|
|
+ * want to restore it back to its original state upon resume anyway.
|
|
|
*/
|
|
|
static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
|
|
|
void *hcpu)
|
|
|
{
|
|
|
- switch (action & ~CPU_TASKS_FROZEN) {
|
|
|
+ switch (action) {
|
|
|
+ case CPU_ONLINE_FROZEN:
|
|
|
+ case CPU_DOWN_FAILED_FROZEN:
|
|
|
+
|
|
|
+ /*
|
|
|
+ * num_cpus_frozen tracks how many CPUs are involved in suspend
|
|
|
+ * resume sequence. As long as this is not the last online
|
|
|
+ * operation in the resume sequence, just build a single sched
|
|
|
+ * domain, ignoring cpusets.
|
|
|
+ */
|
|
|
+ num_cpus_frozen--;
|
|
|
+ if (likely(num_cpus_frozen)) {
|
|
|
+ partition_sched_domains(1, NULL, NULL);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This is the last CPU online operation. So fall through and
|
|
|
+ * restore the original sched domains by considering the
|
|
|
+ * cpuset configurations.
|
|
|
+ */
|
|
|
+
|
|
|
case CPU_ONLINE:
|
|
|
case CPU_DOWN_FAILED:
|
|
|
cpuset_update_active_cpus();
|
|
|
- return NOTIFY_OK;
|
|
|
+ break;
|
|
|
default:
|
|
|
return NOTIFY_DONE;
|
|
|
}
|
|
|
+ return NOTIFY_OK;
|
|
|
}
|
|
|
|
|
|
static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
|
|
|
void *hcpu)
|
|
|
{
|
|
|
- switch (action & ~CPU_TASKS_FROZEN) {
|
|
|
+ switch (action) {
|
|
|
case CPU_DOWN_PREPARE:
|
|
|
cpuset_update_active_cpus();
|
|
|
- return NOTIFY_OK;
|
|
|
+ break;
|
|
|
+ case CPU_DOWN_PREPARE_FROZEN:
|
|
|
+ num_cpus_frozen++;
|
|
|
+ partition_sched_domains(1, NULL, NULL);
|
|
|
+ break;
|
|
|
default:
|
|
|
return NOTIFY_DONE;
|
|
|
}
|
|
|
+ return NOTIFY_OK;
|
|
|
}
|
|
|
|
|
|
void __init sched_init_smp(void)
|