aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2007-02-20 16:57:49 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-20 20:10:13 -0500
commit8af5e2eb3cc4450ffba9496c875beac41bf4f4f8 (patch)
treed15c56e8add1b53d5ed4d5dcb5d1f016d8f2b1c9 /mm/mempolicy.c
parentb446b60e4eb5e5457120c4728ada871b1209c1d0 (diff)
[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: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Andi Kleen <ak@suse.de> Cc: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 259a706bd83e..cf2a5381030a 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -144,7 +144,7 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes)
144 max++; /* space for zlcache_ptr (see mmzone.h) */ 144 max++; /* space for zlcache_ptr (see mmzone.h) */
145 zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL); 145 zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL);
146 if (!zl) 146 if (!zl)
147 return NULL; 147 return ERR_PTR(-ENOMEM);
148 zl->zlcache_ptr = NULL; 148 zl->zlcache_ptr = NULL;
149 num = 0; 149 num = 0;
150 /* First put in the highest zones from all nodes, then all the next 150 /* 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)
162 break; 162 break;
163 k--; 163 k--;
164 } 164 }
165 if (num == 0) {
166 kfree(zl);
167 return ERR_PTR(-EINVAL);
168 }
165 zl->zones[num] = NULL; 169 zl->zones[num] = NULL;
166 return zl; 170 return zl;
167} 171}
@@ -193,9 +197,10 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
193 break; 197 break;
194 case MPOL_BIND: 198 case MPOL_BIND:
195 policy->v.zonelist = bind_zonelist(nodes); 199 policy->v.zonelist = bind_zonelist(nodes);
196 if (policy->v.zonelist == NULL) { 200 if (IS_ERR(policy->v.zonelist)) {
201 void *error_code = policy->v.zonelist;
197 kmem_cache_free(policy_cache, policy); 202 kmem_cache_free(policy_cache, policy);
198 return ERR_PTR(-ENOMEM); 203 return error_code;
199 } 204 }
200 break; 205 break;
201 } 206 }
@@ -1667,7 +1672,7 @@ void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
1667 * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT. 1672 * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
1668 */ 1673 */
1669 1674
1670 if (zonelist) { 1675 if (!IS_ERR(zonelist)) {
1671 /* Good - got mem - substitute new zonelist */ 1676 /* Good - got mem - substitute new zonelist */
1672 kfree(pol->v.zonelist); 1677 kfree(pol->v.zonelist);
1673 pol->v.zonelist = zonelist; 1678 pol->v.zonelist = zonelist;