diff options
author | Mel Gorman <mel@csn.ul.ie> | 2008-04-28 05:12:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:18 -0400 |
commit | 0e88460da6ab7bb6a7ef83675412ed5b6315d741 (patch) | |
tree | 1feb4de2362e4998a0deeab66af1efb9c7b8bb34 | |
parent | dac1d27bc8d5ca636d3014ecfdf94407031d1970 (diff) |
mm: introduce node_zonelist() for accessing the zonelist for a GFP mask
Introduce a node_zonelist() helper function. It is used to lookup the
appropriate zonelist given a node and a GFP mask. The patch on its own is a
cleanup but it helps clarify parts of the two-zonelist-per-node patchset. If
necessary, it can be merged with the next patch in this set without problems.
Reviewed-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
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: Christoph Lameter <clameter@sgi.com>
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>
-rw-r--r-- | drivers/char/sysrq.c | 3 | ||||
-rw-r--r-- | fs/buffer.c | 6 | ||||
-rw-r--r-- | include/linux/gfp.h | 8 | ||||
-rw-r--r-- | include/linux/mempolicy.h | 2 | ||||
-rw-r--r-- | mm/mempolicy.c | 6 | ||||
-rw-r--r-- | mm/page_alloc.c | 3 | ||||
-rw-r--r-- | mm/slab.c | 3 | ||||
-rw-r--r-- | mm/slub.c | 3 |
8 files changed, 17 insertions, 17 deletions
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index de60e1ea4fb3..1ade193c9128 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -271,8 +271,7 @@ static struct sysrq_key_op sysrq_term_op = { | |||
271 | 271 | ||
272 | static void moom_callback(struct work_struct *ignored) | 272 | static void moom_callback(struct work_struct *ignored) |
273 | { | 273 | { |
274 | out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], | 274 | out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0); |
275 | GFP_KERNEL, 0); | ||
276 | } | 275 | } |
277 | 276 | ||
278 | static DECLARE_WORK(moom_work, moom_callback); | 277 | static DECLARE_WORK(moom_work, moom_callback); |
diff --git a/fs/buffer.c b/fs/buffer.c index 1dae94acb3fe..71358499bc57 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -361,13 +361,13 @@ void invalidate_bdev(struct block_device *bdev) | |||
361 | static void free_more_memory(void) | 361 | static void free_more_memory(void) |
362 | { | 362 | { |
363 | struct zonelist *zonelist; | 363 | struct zonelist *zonelist; |
364 | pg_data_t *pgdat; | 364 | int nid; |
365 | 365 | ||
366 | wakeup_pdflush(1024); | 366 | wakeup_pdflush(1024); |
367 | yield(); | 367 | yield(); |
368 | 368 | ||
369 | for_each_online_pgdat(pgdat) { | 369 | for_each_online_node(nid) { |
370 | zonelist = &pgdat->node_zonelists[gfp_zone(GFP_NOFS)]; | 370 | zonelist = node_zonelist(nid, GFP_NOFS); |
371 | if (zonelist->zones[0]) | 371 | if (zonelist->zones[0]) |
372 | try_to_free_pages(zonelist, 0, GFP_NOFS); | 372 | try_to_free_pages(zonelist, 0, GFP_NOFS); |
373 | } | 373 | } |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index c17ba4945203..e865d51f1c74 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -154,10 +154,15 @@ static inline enum zone_type gfp_zone(gfp_t flags) | |||
154 | /* | 154 | /* |
155 | * We get the zone list from the current node and the gfp_mask. | 155 | * We get the zone list from the current node and the gfp_mask. |
156 | * This zone list contains a maximum of MAXNODES*MAX_NR_ZONES zones. | 156 | * This zone list contains a maximum of MAXNODES*MAX_NR_ZONES zones. |
157 | * There are many zonelists per node, two for each active zone. | ||
157 | * | 158 | * |
158 | * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets | 159 | * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets |
159 | * optimized to &contig_page_data at compile-time. | 160 | * optimized to &contig_page_data at compile-time. |
160 | */ | 161 | */ |
162 | static inline struct zonelist *node_zonelist(int nid, gfp_t flags) | ||
163 | { | ||
164 | return NODE_DATA(nid)->node_zonelists + gfp_zone(flags); | ||
165 | } | ||
161 | 166 | ||
162 | #ifndef HAVE_ARCH_FREE_PAGE | 167 | #ifndef HAVE_ARCH_FREE_PAGE |
163 | static inline void arch_free_page(struct page *page, int order) { } | 168 | static inline void arch_free_page(struct page *page, int order) { } |
@@ -178,8 +183,7 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, | |||
178 | if (nid < 0) | 183 | if (nid < 0) |
179 | nid = numa_node_id(); | 184 | nid = numa_node_id(); |
180 | 185 | ||
181 | return __alloc_pages(gfp_mask, order, | 186 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); |
182 | NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask)); | ||
183 | } | 187 | } |
184 | 188 | ||
185 | #ifdef CONFIG_NUMA | 189 | #ifdef CONFIG_NUMA |
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 59c4865bc85f..69160dc32d48 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
@@ -241,7 +241,7 @@ static inline void mpol_fix_fork_child_flag(struct task_struct *p) | |||
241 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, | 241 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, |
242 | unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol) | 242 | unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol) |
243 | { | 243 | { |
244 | return NODE_DATA(0)->node_zonelists + gfp_zone(gfp_flags); | 244 | return node_zonelist(0, gfp_flags); |
245 | } | 245 | } |
246 | 246 | ||
247 | static inline int do_migrate_pages(struct mm_struct *mm, | 247 | static inline int do_migrate_pages(struct mm_struct *mm, |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 3c3601121509..5d20bf44062f 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -1183,7 +1183,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy) | |||
1183 | nd = 0; | 1183 | nd = 0; |
1184 | BUG(); | 1184 | BUG(); |
1185 | } | 1185 | } |
1186 | return NODE_DATA(nd)->node_zonelists + gfp_zone(gfp); | 1186 | return node_zonelist(nd, gfp); |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | /* Do dynamic interleaving for a process */ | 1189 | /* Do dynamic interleaving for a process */ |
@@ -1299,7 +1299,7 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, | |||
1299 | if (unlikely(pol != &default_policy && | 1299 | if (unlikely(pol != &default_policy && |
1300 | pol != current->mempolicy)) | 1300 | pol != current->mempolicy)) |
1301 | __mpol_free(pol); /* finished with pol */ | 1301 | __mpol_free(pol); /* finished with pol */ |
1302 | return NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_flags); | 1302 | return node_zonelist(nid, gfp_flags); |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | zl = zonelist_policy(GFP_HIGHUSER, pol); | 1305 | zl = zonelist_policy(GFP_HIGHUSER, pol); |
@@ -1321,7 +1321,7 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, | |||
1321 | struct zonelist *zl; | 1321 | struct zonelist *zl; |
1322 | struct page *page; | 1322 | struct page *page; |
1323 | 1323 | ||
1324 | zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp); | 1324 | zl = node_zonelist(nid, gfp); |
1325 | page = __alloc_pages(gfp, order, zl); | 1325 | page = __alloc_pages(gfp, order, zl); |
1326 | if (page && page_zone(page) == zl->zones[0]) | 1326 | if (page && page_zone(page) == zl->zones[0]) |
1327 | inc_zone_page_state(page, NUMA_INTERLEAVE_HIT); | 1327 | inc_zone_page_state(page, NUMA_INTERLEAVE_HIT); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1bda771a072a..63ff71830ea4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1713,10 +1713,9 @@ EXPORT_SYMBOL(free_pages); | |||
1713 | static unsigned int nr_free_zone_pages(int offset) | 1713 | static unsigned int nr_free_zone_pages(int offset) |
1714 | { | 1714 | { |
1715 | /* Just pick one node, since fallback list is circular */ | 1715 | /* Just pick one node, since fallback list is circular */ |
1716 | pg_data_t *pgdat = NODE_DATA(numa_node_id()); | ||
1717 | unsigned int sum = 0; | 1716 | unsigned int sum = 0; |
1718 | 1717 | ||
1719 | struct zonelist *zonelist = pgdat->node_zonelists + offset; | 1718 | struct zonelist *zonelist = node_zonelist(numa_node_id(), GFP_KERNEL); |
1720 | struct zone **zonep = zonelist->zones; | 1719 | struct zone **zonep = zonelist->zones; |
1721 | struct zone *zone; | 1720 | struct zone *zone; |
1722 | 1721 | ||
@@ -3249,8 +3249,7 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) | |||
3249 | if (flags & __GFP_THISNODE) | 3249 | if (flags & __GFP_THISNODE) |
3250 | return NULL; | 3250 | return NULL; |
3251 | 3251 | ||
3252 | zonelist = &NODE_DATA(slab_node(current->mempolicy)) | 3252 | zonelist = node_zonelist(slab_node(current->mempolicy), flags); |
3253 | ->node_zonelists[gfp_zone(flags)]; | ||
3254 | local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK); | 3253 | local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK); |
3255 | 3254 | ||
3256 | retry: | 3255 | retry: |
@@ -1309,8 +1309,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags) | |||
1309 | get_cycles() % 1024 > s->remote_node_defrag_ratio) | 1309 | get_cycles() % 1024 > s->remote_node_defrag_ratio) |
1310 | return NULL; | 1310 | return NULL; |
1311 | 1311 | ||
1312 | zonelist = &NODE_DATA( | 1312 | zonelist = node_zonelist(slab_node(current->mempolicy), flags); |
1313 | slab_node(current->mempolicy))->node_zonelists[gfp_zone(flags)]; | ||
1314 | for (z = zonelist->zones; *z; z++) { | 1313 | for (z = zonelist->zones; *z; z++) { |
1315 | struct kmem_cache_node *n; | 1314 | struct kmem_cache_node *n; |
1316 | 1315 | ||