diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2013-02-22 19:33:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-23 20:50:13 -0500 |
commit | d3eb1570a9221b1b3ea8f6f460a9674c1bb761f1 (patch) | |
tree | 35792d7c35ba7012ea8d43bf5243e04a6b90323f /mm/mempolicy.c | |
parent | 8a356ce38e134b3b09b439e88dc770f8f5567648 (diff) |
mempolicy: fix is_valid_nodemask()
is_valid_nodemask() was introduced by commit 19770b32609b ("mm: filter
based on a nodemask as well as a gfp_mask"). but it does not match its
comments, because it does not check the zone which > policy_zone.
Also in commit b377fd3982ad ("Apply memory policies to top two highest
zones when highest zone is ZONE_MOVABLE"), this commits told us, if
highest zone is ZONE_MOVABLE, we should also apply memory policies to
it. so ZONE_MOVABLE should be valid zone for policies.
is_valid_nodemask() need to be changed to match it.
Fix: check all zones, even its zoneid > policy_zone. Use
nodes_intersects() instead open code to check it.
Reported-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Jiang Liu <jiang.liu@huawei.com>
Cc: Jianguo Wu <wujianguo@huawei.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.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.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index e2df1c1fb41f..6f7979c566d9 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -161,19 +161,7 @@ static const struct mempolicy_operations { | |||
161 | /* Check that the nodemask contains at least one populated zone */ | 161 | /* Check that the nodemask contains at least one populated zone */ |
162 | static int is_valid_nodemask(const nodemask_t *nodemask) | 162 | static int is_valid_nodemask(const nodemask_t *nodemask) |
163 | { | 163 | { |
164 | int nd, k; | 164 | return nodes_intersects(*nodemask, node_states[N_MEMORY]); |
165 | |||
166 | for_each_node_mask(nd, *nodemask) { | ||
167 | struct zone *z; | ||
168 | |||
169 | for (k = 0; k <= policy_zone; k++) { | ||
170 | z = &NODE_DATA(nd)->node_zones[k]; | ||
171 | if (z->present_pages > 0) | ||
172 | return 1; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | 165 | } |
178 | 166 | ||
179 | static inline int mpol_store_user_nodemask(const struct mempolicy *pol) | 167 | static inline int mpol_store_user_nodemask(const struct mempolicy *pol) |
@@ -1644,6 +1632,26 @@ struct mempolicy *get_vma_policy(struct task_struct *task, | |||
1644 | return pol; | 1632 | return pol; |
1645 | } | 1633 | } |
1646 | 1634 | ||
1635 | static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone) | ||
1636 | { | ||
1637 | enum zone_type dynamic_policy_zone = policy_zone; | ||
1638 | |||
1639 | BUG_ON(dynamic_policy_zone == ZONE_MOVABLE); | ||
1640 | |||
1641 | /* | ||
1642 | * if policy->v.nodes has movable memory only, | ||
1643 | * we apply policy when gfp_zone(gfp) = ZONE_MOVABLE only. | ||
1644 | * | ||
1645 | * policy->v.nodes is intersect with node_states[N_MEMORY]. | ||
1646 | * so if the following test faile, it implies | ||
1647 | * policy->v.nodes has movable memory only. | ||
1648 | */ | ||
1649 | if (!nodes_intersects(policy->v.nodes, node_states[N_HIGH_MEMORY])) | ||
1650 | dynamic_policy_zone = ZONE_MOVABLE; | ||
1651 | |||
1652 | return zone >= dynamic_policy_zone; | ||
1653 | } | ||
1654 | |||
1647 | /* | 1655 | /* |
1648 | * Return a nodemask representing a mempolicy for filtering nodes for | 1656 | * Return a nodemask representing a mempolicy for filtering nodes for |
1649 | * page allocation | 1657 | * page allocation |
@@ -1652,7 +1660,7 @@ static nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy) | |||
1652 | { | 1660 | { |
1653 | /* Lower zones don't get a nodemask applied for MPOL_BIND */ | 1661 | /* Lower zones don't get a nodemask applied for MPOL_BIND */ |
1654 | if (unlikely(policy->mode == MPOL_BIND) && | 1662 | if (unlikely(policy->mode == MPOL_BIND) && |
1655 | gfp_zone(gfp) >= policy_zone && | 1663 | apply_policy_zone(policy, gfp_zone(gfp)) && |
1656 | cpuset_nodemask_valid_mems_allowed(&policy->v.nodes)) | 1664 | cpuset_nodemask_valid_mems_allowed(&policy->v.nodes)) |
1657 | return &policy->v.nodes; | 1665 | return &policy->v.nodes; |
1658 | 1666 | ||