diff options
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r-- | include/linux/mmzone.h | 108 |
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 | */ | ||
370 | static 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 | |||
403 | static inline int populated_zone(struct zone *zone) | 353 | static 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 | ||
424 | static inline struct pglist_data *first_online_pgdat(void) | ||
425 | { | ||
426 | return NODE_DATA(first_online_node); | ||
427 | } | ||
428 | |||
429 | static 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 | */ | ||
452 | static 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 |