diff options
Diffstat (limited to 'mm/mempolicy.c')
| -rw-r--r-- | mm/mempolicy.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 3bd7fb7e4b75..bedfa4f09c80 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
| @@ -132,19 +132,29 @@ static int mpol_check_policy(int mode, nodemask_t *nodes) | |||
| 132 | } | 132 | } |
| 133 | return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL; | 133 | return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL; |
| 134 | } | 134 | } |
| 135 | |||
| 135 | /* Generate a custom zonelist for the BIND policy. */ | 136 | /* Generate a custom zonelist for the BIND policy. */ |
| 136 | static struct zonelist *bind_zonelist(nodemask_t *nodes) | 137 | static struct zonelist *bind_zonelist(nodemask_t *nodes) |
| 137 | { | 138 | { |
| 138 | struct zonelist *zl; | 139 | struct zonelist *zl; |
| 139 | int num, max, nd; | 140 | int num, max, nd, k; |
| 140 | 141 | ||
| 141 | max = 1 + MAX_NR_ZONES * nodes_weight(*nodes); | 142 | max = 1 + MAX_NR_ZONES * nodes_weight(*nodes); |
| 142 | zl = kmalloc(sizeof(void *) * max, GFP_KERNEL); | 143 | zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL); |
| 143 | if (!zl) | 144 | if (!zl) |
| 144 | return NULL; | 145 | return NULL; |
| 145 | num = 0; | 146 | num = 0; |
| 146 | for_each_node_mask(nd, *nodes) | 147 | /* First put in the highest zones from all nodes, then all the next |
| 147 | zl->zones[num++] = &NODE_DATA(nd)->node_zones[policy_zone]; | 148 | lower zones etc. Avoid empty zones because the memory allocator |
| 149 | doesn't like them. If you implement node hot removal you | ||
| 150 | have to fix that. */ | ||
| 151 | for (k = policy_zone; k >= 0; k--) { | ||
| 152 | for_each_node_mask(nd, *nodes) { | ||
| 153 | struct zone *z = &NODE_DATA(nd)->node_zones[k]; | ||
| 154 | if (z->present_pages > 0) | ||
| 155 | zl->zones[num++] = z; | ||
| 156 | } | ||
| 157 | } | ||
| 148 | zl->zones[num] = NULL; | 158 | zl->zones[num] = NULL; |
| 149 | return zl; | 159 | return zl; |
| 150 | } | 160 | } |
| @@ -798,6 +808,8 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, | |||
| 798 | nodes_clear(*nodes); | 808 | nodes_clear(*nodes); |
| 799 | if (maxnode == 0 || !nmask) | 809 | if (maxnode == 0 || !nmask) |
| 800 | return 0; | 810 | return 0; |
| 811 | if (maxnode > PAGE_SIZE) | ||
| 812 | return -EINVAL; | ||
| 801 | 813 | ||
| 802 | nlongs = BITS_TO_LONGS(maxnode); | 814 | nlongs = BITS_TO_LONGS(maxnode); |
| 803 | if ((maxnode % BITS_PER_LONG) == 0) | 815 | if ((maxnode % BITS_PER_LONG) == 0) |
