aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2010-03-23 16:35:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-24 19:31:21 -0400
commit5ab116c9349ef52d6fbd2e2917a53f13194b048e (patch)
tree636a6cf02d5ca47c6da5d4935b07ddf08666a09c
parent5574169613b40b85d6f4c67208fa4846b897a0a1 (diff)
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>
-rw-r--r--init/main.c2
-rw-r--r--kernel/cpuset.c20
-rw-r--r--kernel/kthread.c2
3 files changed, 14 insertions, 10 deletions
diff --git a/init/main.c b/init/main.c
index a1ab78ceb4b6..cbead27caefc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -858,7 +858,7 @@ static int __init kernel_init(void * unused)
858 /* 858 /*
859 * init can allocate pages on any node 859 * init can allocate pages on any node
860 */ 860 */
861 set_mems_allowed(node_possible_map); 861 set_mems_allowed(node_states[N_HIGH_MEMORY]);
862 /* 862 /*
863 * init can run on any cpu. 863 * init can run on any cpu.
864 */ 864 */
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index ba401fab459f..5d38bd74483c 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -920,9 +920,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
920 * call to guarantee_online_mems(), as we know no one is changing 920 * call to guarantee_online_mems(), as we know no one is changing
921 * our task's cpuset. 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 * While the mm_struct we are migrating is typically from some 923 * While the mm_struct we are migrating is typically from some
927 * other task, the task_struct mems_allowed that we are hacking 924 * other task, the task_struct mems_allowed that we are hacking
928 * is for our current task, which must allocate new pages for that 925 * is for our current task, which must allocate new pages for that
@@ -1391,11 +1388,10 @@ static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont,
1391 1388
1392 if (cs == &top_cpuset) { 1389 if (cs == &top_cpuset) {
1393 cpumask_copy(cpus_attach, cpu_possible_mask); 1390 cpumask_copy(cpus_attach, cpu_possible_mask);
1394 to = node_possible_map;
1395 } else { 1391 } else {
1396 guarantee_online_cpus(cs, cpus_attach); 1392 guarantee_online_cpus(cs, cpus_attach);
1397 guarantee_online_mems(cs, &to);
1398 } 1393 }
1394 guarantee_online_mems(cs, &to);
1399 1395
1400 /* do per-task migration stuff possibly for each in the threadgroup */ 1396 /* do per-task migration stuff possibly for each in the threadgroup */
1401 cpuset_attach_task(tsk, &to, cs); 1397 cpuset_attach_task(tsk, &to, cs);
@@ -2090,15 +2086,23 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
2090static int cpuset_track_online_nodes(struct notifier_block *self, 2086static int cpuset_track_online_nodes(struct notifier_block *self,
2091 unsigned long action, void *arg) 2087 unsigned long action, void *arg)
2092{ 2088{
2089 nodemask_t oldmems;
2090
2093 cgroup_lock(); 2091 cgroup_lock();
2094 switch (action) { 2092 switch (action) {
2095 case MEM_ONLINE: 2093 case MEM_ONLINE:
2096 case MEM_OFFLINE: 2094 oldmems = top_cpuset.mems_allowed;
2097 mutex_lock(&callback_mutex); 2095 mutex_lock(&callback_mutex);
2098 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; 2096 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
2099 mutex_unlock(&callback_mutex); 2097 mutex_unlock(&callback_mutex);
2100 if (action == MEM_OFFLINE) 2098 update_tasks_nodemask(&top_cpuset, &oldmems, NULL);
2101 scan_for_empty_cpusets(&top_cpuset); 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 break; 2106 break;
2103 default: 2107 default:
2104 break; 2108 break;
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 82ed0ea15194..83911c780175 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -219,7 +219,7 @@ int kthreadd(void *unused)
219 set_task_comm(tsk, "kthreadd"); 219 set_task_comm(tsk, "kthreadd");
220 ignore_signals(tsk); 220 ignore_signals(tsk);
221 set_cpus_allowed_ptr(tsk, cpu_all_mask); 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 current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; 224 current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
225 225