diff options
| -rw-r--r-- | include/linux/cpuset.h | 6 | ||||
| -rw-r--r-- | kernel/cpuset.c | 16 | ||||
| -rw-r--r-- | kernel/power/process.c | 6 | ||||
| -rw-r--r-- | kernel/sched/core.c | 7 |
4 files changed, 29 insertions, 6 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index cc1b01cf2..7bc96dce8 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -19,7 +19,9 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */ extern int cpuset_init(void); extern void cpuset_init_smp(void); +extern void cpuset_force_rebuild(void); extern void cpuset_update_active_cpus(bool cpu_online); +extern void cpuset_wait_for_hotplug(void); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); extern void cpuset_cpus_allowed_fallback(struct task_struct *p); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); @@ -122,11 +124,15 @@ static inline void set_mems_allowed(nodemask_t nodemask) static inline int cpuset_init(void) { return 0; } static inline void cpuset_init_smp(void) {} +static inline void cpuset_force_rebuild(void) { } + static inline void cpuset_update_active_cpus(bool cpu_online) { partition_sched_domains(1, NULL, NULL); } +static inline void cpuset_wait_for_hotplug(void) { } + static inline void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask) { diff --git a/kernel/cpuset.c b/kernel/cpuset.c index dbe558161..ab0be4565 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -2150,6 +2150,13 @@ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs) css_put(&cs->css); } +static bool force_rebuild; + +void cpuset_force_rebuild(void) +{ + force_rebuild = true; +} + /** * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset * @@ -2221,8 +2228,10 @@ static void cpuset_hotplug_workfn(struct work_struct *work) flush_workqueue(cpuset_propagate_hotplug_wq); /* rebuild sched domains if cpus_allowed has changed */ - if (cpus_updated) + if (cpus_updated || force_rebuild) { + force_rebuild = false; rebuild_sched_domains(); + } } void cpuset_update_active_cpus(bool cpu_online) @@ -2241,6 +2250,11 @@ void cpuset_update_active_cpus(bool cpu_online) schedule_work(&cpuset_hotplug_work); } +void cpuset_wait_for_hotplug(void) +{ + flush_work(&cpuset_hotplug_work); +} + /* * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY]. * Call this routine anytime after node_states[N_MEMORY] changes. diff --git a/kernel/power/process.c b/kernel/power/process.c index 801934e99..f606d8210 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -18,7 +18,9 @@ #include <linux/workqueue.h> #include <linux/kmod.h> #include <linux/wakeup_reason.h> -/* +#include <linux/cpuset.h> + +/* * Timeout for stopping processes */ unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC; @@ -230,6 +232,8 @@ void thaw_processes(void) __usermodehelper_set_disable_depth(UMH_FREEZING); thaw_workqueues(); + cpuset_wait_for_hotplug(); + read_lock(&tasklist_lock); for_each_process_thread(g, p) { BUG_ON(!virt_addr_valid(next_task(g))); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 265f8359e..827544592 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7443,17 +7443,16 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action, * 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); + partition_sched_domains(1, NULL, NULL); + if (--num_cpus_frozen) break; - } /* * This is the last CPU online operation. So fall through and * restore the original sched domains by considering the * cpuset configurations. */ + cpuset_force_rebuild(); case CPU_ONLINE: case CPU_DOWN_FAILED: |
