Commit 5ab116c9349ef52d6fbd2e2917a53f13194b048e
Committed by
Linus Torvalds
1 parent
5574169613
Exists in
master
and in
39 other branches
cpuset: fix the problem that cpuset_mem_spread_node() returns an offline node
cpuset_mem_spread_node() returns an offline node, and causes an oops. This patch fixes it by initializing task->mems_allowed to node_states[N_HIGH_MEMORY], and updating task->mems_allowed when doing memory hotplug. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Acked-by: David Rientjes <rientjes@google.com> Reported-by: Nick Piggin <npiggin@suse.de> Tested-by: Nick Piggin <npiggin@suse.de> Cc: Paul Menage <menage@google.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 14 additions and 10 deletions Side-by-side Diff
init/main.c
kernel/cpuset.c
... | ... | @@ -920,9 +920,6 @@ |
920 | 920 | * call to guarantee_online_mems(), as we know no one is changing |
921 | 921 | * our task's cpuset. |
922 | 922 | * |
923 | - * Hold callback_mutex around the two modifications of our tasks | |
924 | - * mems_allowed to synchronize with cpuset_mems_allowed(). | |
925 | - * | |
926 | 923 | * While the mm_struct we are migrating is typically from some |
927 | 924 | * other task, the task_struct mems_allowed that we are hacking |
928 | 925 | * is for our current task, which must allocate new pages for that |
929 | 926 | |
930 | 927 | |
... | ... | @@ -1391,11 +1388,10 @@ |
1391 | 1388 | |
1392 | 1389 | if (cs == &top_cpuset) { |
1393 | 1390 | cpumask_copy(cpus_attach, cpu_possible_mask); |
1394 | - to = node_possible_map; | |
1395 | 1391 | } else { |
1396 | 1392 | guarantee_online_cpus(cs, cpus_attach); |
1397 | - guarantee_online_mems(cs, &to); | |
1398 | 1393 | } |
1394 | + guarantee_online_mems(cs, &to); | |
1399 | 1395 | |
1400 | 1396 | /* do per-task migration stuff possibly for each in the threadgroup */ |
1401 | 1397 | cpuset_attach_task(tsk, &to, cs); |
1402 | 1398 | |
1403 | 1399 | |
... | ... | @@ -2090,15 +2086,23 @@ |
2090 | 2086 | static int cpuset_track_online_nodes(struct notifier_block *self, |
2091 | 2087 | unsigned long action, void *arg) |
2092 | 2088 | { |
2089 | + nodemask_t oldmems; | |
2090 | + | |
2093 | 2091 | cgroup_lock(); |
2094 | 2092 | switch (action) { |
2095 | 2093 | case MEM_ONLINE: |
2096 | - case MEM_OFFLINE: | |
2094 | + oldmems = top_cpuset.mems_allowed; | |
2097 | 2095 | mutex_lock(&callback_mutex); |
2098 | 2096 | top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; |
2099 | 2097 | mutex_unlock(&callback_mutex); |
2100 | - if (action == MEM_OFFLINE) | |
2101 | - scan_for_empty_cpusets(&top_cpuset); | |
2098 | + update_tasks_nodemask(&top_cpuset, &oldmems, NULL); | |
2099 | + break; | |
2100 | + case MEM_OFFLINE: | |
2101 | + /* | |
2102 | + * needn't update top_cpuset.mems_allowed explicitly because | |
2103 | + * scan_for_empty_cpusets() will update it. | |
2104 | + */ | |
2105 | + scan_for_empty_cpusets(&top_cpuset); | |
2102 | 2106 | break; |
2103 | 2107 | default: |
2104 | 2108 | break; |
kernel/kthread.c
... | ... | @@ -219,7 +219,7 @@ |
219 | 219 | set_task_comm(tsk, "kthreadd"); |
220 | 220 | ignore_signals(tsk); |
221 | 221 | set_cpus_allowed_ptr(tsk, cpu_all_mask); |
222 | - set_mems_allowed(node_possible_map); | |
222 | + set_mems_allowed(node_states[N_HIGH_MEMORY]); | |
223 | 223 | |
224 | 224 | current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; |
225 | 225 |