Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ab116c9 authored by Miao Xie's avatar Miao Xie Committed by Linus Torvalds
Browse files

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: default avatarMiao Xie <miaox@cn.fujitsu.com>
Acked-by: default avatarDavid Rientjes <rientjes@google.com>
Reported-by: default avatarNick Piggin <npiggin@suse.de>
Tested-by: default avatarNick 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 55741696
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -858,7 +858,7 @@ static int __init kernel_init(void * unused)
	/*
	 * init can allocate pages on any node
	 */
	set_mems_allowed(node_possible_map);
	set_mems_allowed(node_states[N_HIGH_MEMORY]);
	/*
	 * init can run on any cpu.
	 */
+12 −8
Original line number Diff line number Diff line
@@ -920,9 +920,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
 *    call to guarantee_online_mems(), as we know no one is changing
 *    our task's cpuset.
 *
 *    Hold callback_mutex around the two modifications of our tasks
 *    mems_allowed to synchronize with cpuset_mems_allowed().
 *
 *    While the mm_struct we are migrating is typically from some
 *    other task, the task_struct mems_allowed that we are hacking
 *    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,

	if (cs == &top_cpuset) {
		cpumask_copy(cpus_attach, cpu_possible_mask);
		to = node_possible_map;
	} else {
		guarantee_online_cpus(cs, cpus_attach);
		guarantee_online_mems(cs, &to);
	}
	guarantee_online_mems(cs, &to);

	/* do per-task migration stuff possibly for each in the threadgroup */
	cpuset_attach_task(tsk, &to, cs);
@@ -2090,14 +2086,22 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
static int cpuset_track_online_nodes(struct notifier_block *self,
				unsigned long action, void *arg)
{
	nodemask_t oldmems;

	cgroup_lock();
	switch (action) {
	case MEM_ONLINE:
	case MEM_OFFLINE:
		oldmems = top_cpuset.mems_allowed;
		mutex_lock(&callback_mutex);
		top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
		mutex_unlock(&callback_mutex);
		if (action == MEM_OFFLINE)
		update_tasks_nodemask(&top_cpuset, &oldmems, NULL);
		break;
	case MEM_OFFLINE:
		/*
		 * needn't update top_cpuset.mems_allowed explicitly because
		 * scan_for_empty_cpusets() will update it.
		 */
		scan_for_empty_cpusets(&top_cpuset);
		break;
	default:
+1 −1
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ int kthreadd(void *unused)
	set_task_comm(tsk, "kthreadd");
	ignore_signals(tsk);
	set_cpus_allowed_ptr(tsk, cpu_all_mask);
	set_mems_allowed(node_possible_map);
	set_mems_allowed(node_states[N_HIGH_MEMORY]);

	current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;