aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmzone.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r--include/linux/mmzone.h64
1 files changed, 54 insertions, 10 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index d5c33a0b89e9..d34b4c290017 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -469,6 +469,15 @@ struct zonelist_cache;
469#endif 469#endif
470 470
471/* 471/*
472 * This struct contains information about a zone in a zonelist. It is stored
473 * here to avoid dereferences into large structures and lookups of tables
474 */
475struct zoneref {
476 struct zone *zone; /* Pointer to actual zone */
477 int zone_idx; /* zone_idx(zoneref->zone) */
478};
479
480/*
472 * One allocation request operates on a zonelist. A zonelist 481 * One allocation request operates on a zonelist. A zonelist
473 * is a list of zones, the first one is the 'goal' of the 482 * is a list of zones, the first one is the 'goal' of the
474 * allocation, the other zones are fallback zones, in decreasing 483 * allocation, the other zones are fallback zones, in decreasing
@@ -476,11 +485,18 @@ struct zonelist_cache;
476 * 485 *
477 * If zlcache_ptr is not NULL, then it is just the address of zlcache, 486 * If zlcache_ptr is not NULL, then it is just the address of zlcache,
478 * as explained above. If zlcache_ptr is NULL, there is no zlcache. 487 * as explained above. If zlcache_ptr is NULL, there is no zlcache.
488 * *
489 * To speed the reading of the zonelist, the zonerefs contain the zone index
490 * of the entry being read. Helper functions to access information given
491 * a struct zoneref are
492 *
493 * zonelist_zone() - Return the struct zone * for an entry in _zonerefs
494 * zonelist_zone_idx() - Return the index of the zone for an entry
495 * zonelist_node_idx() - Return the index of the node for an entry
479 */ 496 */
480
481struct zonelist { 497struct zonelist {
482 struct zonelist_cache *zlcache_ptr; // NULL or &zlcache 498 struct zonelist_cache *zlcache_ptr; // NULL or &zlcache
483 struct zone *zones[MAX_ZONES_PER_ZONELIST + 1]; // NULL delimited 499 struct zoneref _zonerefs[MAX_ZONES_PER_ZONELIST + 1];
484#ifdef CONFIG_NUMA 500#ifdef CONFIG_NUMA
485 struct zonelist_cache zlcache; // optional ... 501 struct zonelist_cache zlcache; // optional ...
486#endif 502#endif
@@ -713,26 +729,52 @@ extern struct zone *next_zone(struct zone *zone);
713 zone; \ 729 zone; \
714 zone = next_zone(zone)) 730 zone = next_zone(zone))
715 731
732static inline struct zone *zonelist_zone(struct zoneref *zoneref)
733{
734 return zoneref->zone;
735}
736
737static inline int zonelist_zone_idx(struct zoneref *zoneref)
738{
739 return zoneref->zone_idx;
740}
741
742static inline int zonelist_node_idx(struct zoneref *zoneref)
743{
744#ifdef CONFIG_NUMA
745 /* zone_to_nid not available in this context */
746 return zoneref->zone->node;
747#else
748 return 0;
749#endif /* CONFIG_NUMA */
750}
751
752static inline void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref)
753{
754 zoneref->zone = zone;
755 zoneref->zone_idx = zone_idx(zone);
756}
757
716/* Returns the first zone at or below highest_zoneidx in a zonelist */ 758/* Returns the first zone at or below highest_zoneidx in a zonelist */
717static inline struct zone **first_zones_zonelist(struct zonelist *zonelist, 759static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
718 enum zone_type highest_zoneidx) 760 enum zone_type highest_zoneidx)
719{ 761{
720 struct zone **z; 762 struct zoneref *z;
721 763
722 /* Find the first suitable zone to use for the allocation */ 764 /* Find the first suitable zone to use for the allocation */
723 z = zonelist->zones; 765 z = zonelist->_zonerefs;
724 while (*z && zone_idx(*z) > highest_zoneidx) 766 while (zonelist_zone_idx(z) > highest_zoneidx)
725 z++; 767 z++;
726 768
727 return z; 769 return z;
728} 770}
729 771
730/* Returns the next zone at or below highest_zoneidx in a zonelist */ 772/* Returns the next zone at or below highest_zoneidx in a zonelist */
731static inline struct zone **next_zones_zonelist(struct zone **z, 773static inline struct zoneref *next_zones_zonelist(struct zoneref *z,
732 enum zone_type highest_zoneidx) 774 enum zone_type highest_zoneidx)
733{ 775{
734 /* Find the next suitable zone to use for the allocation */ 776 /* Find the next suitable zone to use for the allocation */
735 while (*z && zone_idx(*z) > highest_zoneidx) 777 while (zonelist_zone_idx(z) > highest_zoneidx)
736 z++; 778 z++;
737 779
738 return z; 780 return z;
@@ -748,9 +790,11 @@ static inline struct zone **next_zones_zonelist(struct zone **z,
748 * This iterator iterates though all zones at or below a given zone index. 790 * This iterator iterates though all zones at or below a given zone index.
749 */ 791 */
750#define for_each_zone_zonelist(zone, z, zlist, highidx) \ 792#define for_each_zone_zonelist(zone, z, zlist, highidx) \
751 for (z = first_zones_zonelist(zlist, highidx), zone = *z++; \ 793 for (z = first_zones_zonelist(zlist, highidx), \
794 zone = zonelist_zone(z++); \
752 zone; \ 795 zone; \
753 z = next_zones_zonelist(z, highidx), zone = *z++) 796 z = next_zones_zonelist(z, highidx), \
797 zone = zonelist_zone(z++))
754 798
755#ifdef CONFIG_SPARSEMEM 799#ifdef CONFIG_SPARSEMEM
756#include <asm/sparsemem.h> 800#include <asm/sparsemem.h>