diff options
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1a649f2bb9bb..4ea6f0dc2fc5 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -816,6 +816,10 @@ static int update_cpumask(struct cpuset *cs, char *buf) | |||
816 | struct cpuset trialcs; | 816 | struct cpuset trialcs; |
817 | int retval, cpus_unchanged; | 817 | int retval, cpus_unchanged; |
818 | 818 | ||
819 | /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */ | ||
820 | if (cs == &top_cpuset) | ||
821 | return -EACCES; | ||
822 | |||
819 | trialcs = *cs; | 823 | trialcs = *cs; |
820 | retval = cpulist_parse(buf, trialcs.cpus_allowed); | 824 | retval = cpulist_parse(buf, trialcs.cpus_allowed); |
821 | if (retval < 0) | 825 | if (retval < 0) |
@@ -2033,6 +2037,33 @@ out: | |||
2033 | return err; | 2037 | return err; |
2034 | } | 2038 | } |
2035 | 2039 | ||
2040 | /* | ||
2041 | * The top_cpuset tracks what CPUs and Memory Nodes are online, | ||
2042 | * period. This is necessary in order to make cpusets transparent | ||
2043 | * (of no affect) on systems that are actively using CPU hotplug | ||
2044 | * but making no active use of cpusets. | ||
2045 | * | ||
2046 | * This handles CPU hotplug (cpuhp) events. If someday Memory | ||
2047 | * Nodes can be hotplugged (dynamically changing node_online_map) | ||
2048 | * then we should handle that too, perhaps in a similar way. | ||
2049 | */ | ||
2050 | |||
2051 | #ifdef CONFIG_HOTPLUG_CPU | ||
2052 | static int cpuset_handle_cpuhp(struct notifier_block *nb, | ||
2053 | unsigned long phase, void *cpu) | ||
2054 | { | ||
2055 | mutex_lock(&manage_mutex); | ||
2056 | mutex_lock(&callback_mutex); | ||
2057 | |||
2058 | top_cpuset.cpus_allowed = cpu_online_map; | ||
2059 | |||
2060 | mutex_unlock(&callback_mutex); | ||
2061 | mutex_unlock(&manage_mutex); | ||
2062 | |||
2063 | return 0; | ||
2064 | } | ||
2065 | #endif | ||
2066 | |||
2036 | /** | 2067 | /** |
2037 | * cpuset_init_smp - initialize cpus_allowed | 2068 | * cpuset_init_smp - initialize cpus_allowed |
2038 | * | 2069 | * |
@@ -2043,6 +2074,8 @@ void __init cpuset_init_smp(void) | |||
2043 | { | 2074 | { |
2044 | top_cpuset.cpus_allowed = cpu_online_map; | 2075 | top_cpuset.cpus_allowed = cpu_online_map; |
2045 | top_cpuset.mems_allowed = node_online_map; | 2076 | top_cpuset.mems_allowed = node_online_map; |
2077 | |||
2078 | hotcpu_notifier(cpuset_handle_cpuhp, 0); | ||
2046 | } | 2079 | } |
2047 | 2080 | ||
2048 | /** | 2081 | /** |
@@ -2387,7 +2420,7 @@ EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); | |||
2387 | int cpuset_excl_nodes_overlap(const struct task_struct *p) | 2420 | int cpuset_excl_nodes_overlap(const struct task_struct *p) |
2388 | { | 2421 | { |
2389 | const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */ | 2422 | const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */ |
2390 | int overlap = 0; /* do cpusets overlap? */ | 2423 | int overlap = 1; /* do cpusets overlap? */ |
2391 | 2424 | ||
2392 | task_lock(current); | 2425 | task_lock(current); |
2393 | if (current->flags & PF_EXITING) { | 2426 | if (current->flags & PF_EXITING) { |