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 | /** |
