diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 44019da9632e..01e6b614839d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3329,6 +3329,20 @@ static inline unsigned long wait_table_bits(unsigned long size) | |||
3329 | #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) | 3329 | #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) |
3330 | 3330 | ||
3331 | /* | 3331 | /* |
3332 | * Check if a pageblock contains reserved pages | ||
3333 | */ | ||
3334 | static int pageblock_is_reserved(unsigned long start_pfn, unsigned long end_pfn) | ||
3335 | { | ||
3336 | unsigned long pfn; | ||
3337 | |||
3338 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
3339 | if (!pfn_valid_within(pfn) || PageReserved(pfn_to_page(pfn))) | ||
3340 | return 1; | ||
3341 | } | ||
3342 | return 0; | ||
3343 | } | ||
3344 | |||
3345 | /* | ||
3332 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number | 3346 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number |
3333 | * of blocks reserved is based on min_wmark_pages(zone). The memory within | 3347 | * of blocks reserved is based on min_wmark_pages(zone). The memory within |
3334 | * the reserve will tend to store contiguous free pages. Setting min_free_kbytes | 3348 | * the reserve will tend to store contiguous free pages. Setting min_free_kbytes |
@@ -3337,7 +3351,7 @@ static inline unsigned long wait_table_bits(unsigned long size) | |||
3337 | */ | 3351 | */ |
3338 | static void setup_zone_migrate_reserve(struct zone *zone) | 3352 | static void setup_zone_migrate_reserve(struct zone *zone) |
3339 | { | 3353 | { |
3340 | unsigned long start_pfn, pfn, end_pfn; | 3354 | unsigned long start_pfn, pfn, end_pfn, block_end_pfn; |
3341 | struct page *page; | 3355 | struct page *page; |
3342 | unsigned long block_migratetype; | 3356 | unsigned long block_migratetype; |
3343 | int reserve; | 3357 | int reserve; |
@@ -3367,7 +3381,8 @@ static void setup_zone_migrate_reserve(struct zone *zone) | |||
3367 | continue; | 3381 | continue; |
3368 | 3382 | ||
3369 | /* Blocks with reserved pages will never free, skip them. */ | 3383 | /* Blocks with reserved pages will never free, skip them. */ |
3370 | if (PageReserved(page)) | 3384 | block_end_pfn = min(pfn + pageblock_nr_pages, end_pfn); |
3385 | if (pageblock_is_reserved(pfn, block_end_pfn)) | ||
3371 | continue; | 3386 | continue; |
3372 | 3387 | ||
3373 | block_migratetype = get_pageblock_migratetype(page); | 3388 | block_migratetype = get_pageblock_migratetype(page); |