aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmzone.h
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2006-03-27 04:15:57 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:47 -0500
commit8357f8695d58b50fbf2bd507b4b0fc2cd1e43bd6 (patch)
tree8f7326f570ee80d129add7356c7b5c44fb995447 /include/linux/mmzone.h
parenta0140c1d85637ee5f4ea7c78f066e3611a6a79dc (diff)
[PATCH] define for_each_online_pgdat
This patch defines for_each_online_pgdat() as a replacement of for_each_pgdat() Now, online nodes are managed by node_online_map. But for_each_pgdat() uses pgdat_link to iterate over all nodes(pgdat). This means management structure for online pgdat is duplicated. I think using node_online_map for for_each_pgdat() is simple and sane rather ather than pgdat_link. New macro is named as for_each_online_pgdat(). Following patch will fix callers of for_each_pgdat(). The bootmem allocater uses for_each_pgdat() before pgdat initialization. I don't think it's sane. Following patch will fix it. Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r--include/linux/mmzone.h108
1 files changed, 57 insertions, 51 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ace31c515a8c..96eb08025092 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -13,6 +13,7 @@
13#include <linux/numa.h> 13#include <linux/numa.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/seqlock.h> 15#include <linux/seqlock.h>
16#include <linux/nodemask.h>
16#include <asm/atomic.h> 17#include <asm/atomic.h>
17 18
18/* Free memory management - zoned buddy allocator. */ 19/* Free memory management - zoned buddy allocator. */
@@ -349,57 +350,6 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
349 */ 350 */
350#define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones) 351#define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones)
351 352
352/**
353 * for_each_pgdat - helper macro to iterate over all nodes
354 * @pgdat - pointer to a pg_data_t variable
355 *
356 * Meant to help with common loops of the form
357 * pgdat = pgdat_list;
358 * while(pgdat) {
359 * ...
360 * pgdat = pgdat->pgdat_next;
361 * }
362 */
363#define for_each_pgdat(pgdat) \
364 for (pgdat = pgdat_list; pgdat; pgdat = pgdat->pgdat_next)
365
366/*
367 * next_zone - helper magic for for_each_zone()
368 * Thanks to William Lee Irwin III for this piece of ingenuity.
369 */
370static inline struct zone *next_zone(struct zone *zone)
371{
372 pg_data_t *pgdat = zone->zone_pgdat;
373
374 if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
375 zone++;
376 else if (pgdat->pgdat_next) {
377 pgdat = pgdat->pgdat_next;
378 zone = pgdat->node_zones;
379 } else
380 zone = NULL;
381
382 return zone;
383}
384
385/**
386 * for_each_zone - helper macro to iterate over all memory zones
387 * @zone - pointer to struct zone variable
388 *
389 * The user only needs to declare the zone variable, for_each_zone
390 * fills it in. This basically means for_each_zone() is an
391 * easier to read version of this piece of code:
392 *
393 * for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
394 * for (i = 0; i < MAX_NR_ZONES; ++i) {
395 * struct zone * z = pgdat->node_zones + i;
396 * ...
397 * }
398 * }
399 */
400#define for_each_zone(zone) \
401 for (zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
402
403static inline int populated_zone(struct zone *zone) 353static inline int populated_zone(struct zone *zone)
404{ 354{
405 return (!!zone->present_pages); 355 return (!!zone->present_pages);
@@ -471,6 +421,62 @@ extern struct pglist_data contig_page_data;
471 421
472#endif /* !CONFIG_NEED_MULTIPLE_NODES */ 422#endif /* !CONFIG_NEED_MULTIPLE_NODES */
473 423
424static inline struct pglist_data *first_online_pgdat(void)
425{
426 return NODE_DATA(first_online_node);
427}
428
429static inline struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
430{
431 int nid = next_online_node(pgdat->node_id);
432
433 if (nid == MAX_NUMNODES)
434 return NULL;
435 return NODE_DATA(nid);
436}
437
438
439/**
440 * for_each_pgdat - helper macro to iterate over all nodes
441 * @pgdat - pointer to a pg_data_t variable
442 */
443#define for_each_online_pgdat(pgdat) \
444 for (pgdat = first_online_pgdat(); \
445 pgdat; \
446 pgdat = next_online_pgdat(pgdat))
447
448/*
449 * next_zone - helper magic for for_each_zone()
450 * Thanks to William Lee Irwin III for this piece of ingenuity.
451 */
452static inline struct zone *next_zone(struct zone *zone)
453{
454 pg_data_t *pgdat = zone->zone_pgdat;
455
456 if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
457 zone++;
458 else {
459 pgdat = next_online_pgdat(pgdat);
460 if (pgdat)
461 zone = pgdat->node_zones;
462 else
463 zone = NULL;
464 }
465 return zone;
466}
467
468/**
469 * for_each_zone - helper macro to iterate over all memory zones
470 * @zone - pointer to struct zone variable
471 *
472 * The user only needs to declare the zone variable, for_each_zone
473 * fills it in.
474 */
475#define for_each_zone(zone) \
476 for (zone = (first_online_pgdat())->node_zones; \
477 zone; \
478 zone = next_zone(zone))
479
474#ifdef CONFIG_SPARSEMEM 480#ifdef CONFIG_SPARSEMEM
475#include <asm/sparsemem.h> 481#include <asm/sparsemem.h>
476#endif 482#endif