diff options
author | Mel Gorman <mel@csn.ul.ie> | 2008-04-28 05:12:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:19 -0400 |
commit | 19770b32609b6bf97a3dece2529089494cbfc549 (patch) | |
tree | 3b5922d1b20aabdf929bde9309f323841717747a /include/linux/mempolicy.h | |
parent | dd1a239f6f2d4d3eedd318583ec319aa145b324c (diff) |
mm: filter based on a nodemask as well as a gfp_mask
The MPOL_BIND policy creates a zonelist that is used for allocations
controlled by that mempolicy. As the per-node zonelist is already being
filtered based on a zone id, this patch adds a version of __alloc_pages() that
takes a nodemask for further filtering. This eliminates the need for
MPOL_BIND to create a custom zonelist.
A positive benefit of this is that allocations using MPOL_BIND now use the
local node's distance-ordered zonelist instead of a custom node-id-ordered
zonelist. I.e., pages will be allocated from the closest allowed node with
available memory.
[Lee.Schermerhorn@hp.com: Mempolicy: update stale documentation and comments]
[Lee.Schermerhorn@hp.com: Mempolicy: make dequeue_huge_page_vma() obey MPOL_BIND nodemask]
[Lee.Schermerhorn@hp.com: Mempolicy: make dequeue_huge_page_vma() obey MPOL_BIND nodemask rework]
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Acked-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/mempolicy.h')
-rw-r--r-- | include/linux/mempolicy.h | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 69160dc32d48..b8b3da7a3315 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
@@ -54,19 +54,20 @@ struct mm_struct; | |||
54 | * mmap_sem. | 54 | * mmap_sem. |
55 | * | 55 | * |
56 | * Freeing policy: | 56 | * Freeing policy: |
57 | * When policy is MPOL_BIND v.zonelist is kmalloc'ed and must be kfree'd. | 57 | * Mempolicy objects are reference counted. A mempolicy will be freed when |
58 | * All other policies don't have any external state. mpol_free() handles this. | 58 | * mpol_free() decrements the reference count to zero. |
59 | * | 59 | * |
60 | * Copying policy objects: | 60 | * Copying policy objects: |
61 | * For MPOL_BIND the zonelist must be always duplicated. mpol_clone() does this. | 61 | * mpol_copy() allocates a new mempolicy and copies the specified mempolicy |
62 | * to the new storage. The reference count of the new object is initialized | ||
63 | * to 1, representing the caller of mpol_copy(). | ||
62 | */ | 64 | */ |
63 | struct mempolicy { | 65 | struct mempolicy { |
64 | atomic_t refcnt; | 66 | atomic_t refcnt; |
65 | short policy; /* See MPOL_* above */ | 67 | short policy; /* See MPOL_* above */ |
66 | union { | 68 | union { |
67 | struct zonelist *zonelist; /* bind */ | ||
68 | short preferred_node; /* preferred */ | 69 | short preferred_node; /* preferred */ |
69 | nodemask_t nodes; /* interleave */ | 70 | nodemask_t nodes; /* interleave/bind */ |
70 | /* undefined for default */ | 71 | /* undefined for default */ |
71 | } v; | 72 | } v; |
72 | nodemask_t cpuset_mems_allowed; /* mempolicy relative to these nodes */ | 73 | nodemask_t cpuset_mems_allowed; /* mempolicy relative to these nodes */ |
@@ -151,7 +152,8 @@ extern void mpol_fix_fork_child_flag(struct task_struct *p); | |||
151 | 152 | ||
152 | extern struct mempolicy default_policy; | 153 | extern struct mempolicy default_policy; |
153 | extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, | 154 | extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, |
154 | unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol); | 155 | unsigned long addr, gfp_t gfp_flags, |
156 | struct mempolicy **mpol, nodemask_t **nodemask); | ||
155 | extern unsigned slab_node(struct mempolicy *policy); | 157 | extern unsigned slab_node(struct mempolicy *policy); |
156 | 158 | ||
157 | extern enum zone_type policy_zone; | 159 | extern enum zone_type policy_zone; |
@@ -239,8 +241,11 @@ static inline void mpol_fix_fork_child_flag(struct task_struct *p) | |||
239 | } | 241 | } |
240 | 242 | ||
241 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, | 243 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, |
242 | unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol) | 244 | unsigned long addr, gfp_t gfp_flags, |
245 | struct mempolicy **mpol, nodemask_t **nodemask) | ||
243 | { | 246 | { |
247 | *mpol = NULL; | ||
248 | *nodemask = NULL; | ||
244 | return node_zonelist(0, gfp_flags); | 249 | return node_zonelist(0, gfp_flags); |
245 | } | 250 | } |
246 | 251 | ||