diff options
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r-- | include/linux/mmzone.h | 64 |
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 | */ | ||
475 | struct 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 | |||
481 | struct zonelist { | 497 | struct 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 | ||
732 | static inline struct zone *zonelist_zone(struct zoneref *zoneref) | ||
733 | { | ||
734 | return zoneref->zone; | ||
735 | } | ||
736 | |||
737 | static inline int zonelist_zone_idx(struct zoneref *zoneref) | ||
738 | { | ||
739 | return zoneref->zone_idx; | ||
740 | } | ||
741 | |||
742 | static 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 | |||
752 | static 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 */ |
717 | static inline struct zone **first_zones_zonelist(struct zonelist *zonelist, | 759 | static 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 */ |
731 | static inline struct zone **next_zones_zonelist(struct zone **z, | 773 | static 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> |