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

Commit 8af5e2eb authored by KAMEZAWA Hiroyuki's avatar KAMEZAWA Hiroyuki Committed by Linus Torvalds
Browse files

[PATCH] fix mempolicy's check on a system with memory-less-node



bind_zonelist() can create zero-length zonelist if there is a
memory-less-node.  This patch checks the length of zonelist.  If length is
0, returns -EINVAL.

tested on ia64/NUMA with memory-less-node.

Signed-off-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: default avatarAndi Kleen <ak@suse.de>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b446b60e
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes)
	max++;			/* space for zlcache_ptr (see mmzone.h) */
	zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL);
	if (!zl)
		return NULL;
		return ERR_PTR(-ENOMEM);
	zl->zlcache_ptr = NULL;
	num = 0;
	/* First put in the highest zones from all nodes, then all the next 
@@ -162,6 +162,10 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes)
			break;
		k--;
	}
	if (num == 0) {
		kfree(zl);
		return ERR_PTR(-EINVAL);
	}
	zl->zones[num] = NULL;
	return zl;
}
@@ -193,9 +197,10 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
		break;
	case MPOL_BIND:
		policy->v.zonelist = bind_zonelist(nodes);
		if (policy->v.zonelist == NULL) {
		if (IS_ERR(policy->v.zonelist)) {
			void *error_code = policy->v.zonelist;
			kmem_cache_free(policy_cache, policy);
			return ERR_PTR(-ENOMEM);
			return error_code;
		}
		break;
	}
@@ -1667,7 +1672,7 @@ void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
		 * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
		 */

		if (zonelist) {
		if (!IS_ERR(zonelist)) {
			/* Good - got mem - substitute new zonelist */
			kfree(pol->v.zonelist);
			pol->v.zonelist = zonelist;