diff options
-rw-r--r-- | Documentation/cpusets.txt | 6 | ||||
-rw-r--r-- | kernel/cpuset.c | 33 |
2 files changed, 39 insertions, 0 deletions
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 159e2a0c3e80..76b44290c154 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt | |||
@@ -217,6 +217,12 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs) | |||
217 | to represent the cpuset hierarchy provides for a familiar permission | 217 | to represent the cpuset hierarchy provides for a familiar permission |
218 | and name space for cpusets, with a minimum of additional kernel code. | 218 | and name space for cpusets, with a minimum of additional kernel code. |
219 | 219 | ||
220 | The cpus file in the root (top_cpuset) cpuset is read-only. | ||
221 | It automatically tracks the value of cpu_online_map, using a CPU | ||
222 | hotplug notifier. If and when memory nodes can be hotplugged, | ||
223 | we expect to make the mems file in the root cpuset read-only | ||
224 | as well, and have it track the value of node_online_map. | ||
225 | |||
220 | 226 | ||
221 | 1.4 What are exclusive cpusets ? | 227 | 1.4 What are exclusive cpusets ? |
222 | -------------------------------- | 228 | -------------------------------- |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1a649f2bb9bb..f1dda98bdffe 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 | /** |