peeling off zone from physical memory layout [6/10] for each page in zone.
Subsystems (4)
RFC 1/1 peeling off zone from physical memory layout [6/10] for each page in zone.
Some codes want to walk all page sturct in a zone. This patch addes for_each_page_in_zone() to help them.
Because memory_map_list is not sorted, page will appear in random way. If this is a problem, some fix will be needed.
Signed-off-by KAMEZAWA Hiroyuki <[email protected]>
include/linux/memorymap.h +37 -0
@@ -40,4 +40,41 @@ static inline void memory_resize_unlock(#endif +/* +* Rarely used, but some codes searchs all pages in zone. +* which is done just by pfn++ in old days. +* pfn_to_zone can be done by page_zone(pfn_to_page(page)), so memory_map +* doesn't support such ops. +*/ + +static inline struct page *next_page_in_zone (struct page *page,struct zone *z,void **iter) +{ +unsigned long pfn =page_to_pfn (page); +struct memory_map * ent = (struct memory_map *)*iter; +if (pfn +1 < ent->end_pfn) +return pfn_to_page (pfn +1 ); +list_for_each_entry_continue (ent, &memory_map_list, list) { +if (ent->zone == z) +return pfn_to_page (ent->start_pfn); + } +return NULL ; +} + +static inline unsigned long lookup_zone_page (struct zone *z,void **iter) +{ +struct memory_map *ent; +list_for_each_entry (ent, &memory_map_list, list) { +if (ent->zone == z) { + *iter = ent; +return ent->start_pfn; + } + } +BUG (); +} + +/* iter is void*. memory resize lock has to be held.*/ +#define for_each_page_in_zone (p, z, iter) \ + for (p = pfn_to_page(lookup_zone_page( z, &iter)), iter=NULL; \ + p != NULL;\ + p = next_page_in_zone(p, z, &iter))#endif
mm/page_alloc.c +5 -3
@@ -643,7 +643,9 @@ static void __drain_pages(unsigned int cvoid mark_free_pages (struct zone *zone) { -unsigned long zone_pfn, flags; +struct page *page; +void *iter; +unsigned long flags;int order;struct list_head *curr;
@@ -651,8 +653,8 @@ void mark_free_pages(struct zone *zone)return ;spin_lock_irqsave (&zone->lock, flags); -for (zone_pfn =0 ; zone_pfn < zone->spanned_pages; ++zone_pfn) -ClearPageNosaveFree (pfn_to_page (zone_pfn + zone->zone_start_pfn)); +for_each_page_in_zone (page, zone, iter) +ClearPageNosaveFree (page);for (order =MAX_ORDER -1 ; order >=0 ; --order)list_for_each (curr, &zone->free_area[order].free_list) {
kernel/power/snapshot.c +26 -43
142 lines not on this page · raw message
kernel/power/swsusp.c +5 -4
@@ -60,6 +60,7 @@#include <linux/syscalls.h> #include <linux/highmem.h> #include <linux/bio.h> +#include <linux/memorymap.h> #include <asm/uaccess.h> #include <asm/mmu_context.h>
@@ -673,6 +674,8 @@ static void mark_unsafe_pages(struct pbe {struct zone *zone;unsigned long zone_pfn; +struct page *page; +void *iter;struct pbe *p;if (!pblist)/* a sanity check */
@@ -680,10 +683,8 @@ static void mark_unsafe_pages(struct pbe/* Clear page flags */ for_each_zone (zone) { -for (zone_pfn =0 ; zone_pfn < zone->spanned_pages; ++zone_pfn) -if (pfn_valid (zone_pfn + zone->zone_start_pfn)) -ClearPageNosaveFree (pfn_to_page (zone_pfn + - zone->zone_start_pfn)); +for_each_page_in_zone (page, zone, iter) +ClearPageNosaveFree (page); }/* Mark orig addresses */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>