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) { |
