| 1 | From a4eb204a8029320c2dd748daf4f51fd48d337c3d Mon Sep 17 00:00:00 2001 |
| 2 | From: =?utf-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com> |
| 3 | Date: Wed, 18 Mar 2009 17:27:31 -0700 |
| 4 | Subject: [PATCH 056/134] mm: Check if any page in a pageblock is reserved before marking it MIGRATE_RESERVE |
| 5 | |
| 6 | This fixes a problem where the first pageblock got marked MIGRATE_RESERVE even |
| 7 | though it only had a few free pages. This in turn caused no contiguous memory |
| 8 | to be reserved and frequent kswapd wakeups that emptied the caches to get more |
| 9 | contiguous memory. |
| 10 | --- |
| 11 | mm/page_alloc.c | 16 +++++++++++++++- |
| 12 | 1 files changed, 15 insertions(+), 1 deletions(-) |
| 13 | |
| 14 | --- a/mm/page_alloc.c |
| 15 | +++ b/mm/page_alloc.c |
| 16 | @@ -2570,6 +2570,20 @@ static inline unsigned long wait_table_b |
| 17 | #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) |
| 18 | |
| 19 | /* |
| 20 | + * Check if a pageblock contains reserved pages |
| 21 | + */ |
| 22 | +static int pageblock_is_reserved(unsigned long start_pfn) |
| 23 | +{ |
| 24 | + unsigned long end_pfn = start_pfn + pageblock_nr_pages; |
| 25 | + unsigned long pfn; |
| 26 | + |
| 27 | + for (pfn = start_pfn; pfn < end_pfn; pfn++) |
| 28 | + if (PageReserved(pfn_to_page(pfn))) |
| 29 | + return 1; |
| 30 | + return 0; |
| 31 | +} |
| 32 | + |
| 33 | +/* |
| 34 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number |
| 35 | * of blocks reserved is based on zone->pages_min. The memory within the |
| 36 | * reserve will tend to store contiguous free pages. Setting min_free_kbytes |
| 37 | @@ -2598,7 +2612,7 @@ static void setup_zone_migrate_reserve(s |
| 38 | continue; |
| 39 | |
| 40 | /* Blocks with reserved pages will never free, skip them. */ |
| 41 | - if (PageReserved(page)) |
| 42 | + if (pageblock_is_reserved(pfn)) |
| 43 | continue; |
| 44 | |
| 45 | block_migratetype = get_pageblock_migratetype(page); |
| 46 | |