From: Andrew Morton Cc: Andy Whitcroft Cc: Peter Zijlstra Signed-off-by: Andrew Morton --- include/linux/swap.h | 3 ++- mm/vmscan.c | 35 +++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff -puN include/linux/swap.h~lumpy-reclaim-v2-tidy include/linux/swap.h --- a/include/linux/swap.h~lumpy-reclaim-v2-tidy +++ a/include/linux/swap.h @@ -186,7 +186,8 @@ extern int rotate_reclaimable_page(struc extern void swap_setup(void); /* linux/mm/vmscan.c */ -extern unsigned long try_to_free_pages(struct zone **, int, gfp_t); +extern unsigned long try_to_free_pages(struct zone **zones, int order, + gfp_t gfp_mask); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); diff -puN mm/vmscan.c~lumpy-reclaim-v2-tidy mm/vmscan.c --- a/mm/vmscan.c~lumpy-reclaim-v2-tidy +++ a/mm/vmscan.c @@ -605,12 +605,12 @@ keep: } /* - * Attempt to remove the specified page from its LRU. Only take this - * page if it is of the appropriate PageActive status. Pages which - * are being freed elsewhere are also ignored. + * Attempt to remove the specified page from its LRU. Only take this page if it + * is of the appropriate PageActive status. Pages which are being freed + * elsewhere are also ignored. * - * @page: page to consider - * @active: active/inactive flag only take pages of this type + * page: page to consider + * active: active/inactive flag only take pages of this type * * returns 0 on success, -ve errno on failure. */ @@ -648,6 +648,7 @@ int __isolate_lru_page(struct page *page * @src: The LRU list to pull pages off. * @dst: The temp list to put pages on to. * @scanned: The number of pages that were scanned. + * @order: The caller's attempted allocation order * * returns how many pages were moved onto *@dst. */ @@ -656,12 +657,16 @@ static unsigned long isolate_lru_pages(u unsigned long *scanned, int order) { unsigned long nr_taken = 0; - struct page *page, *tmp; - unsigned long scan, pfn, end_pfn, page_pfn; - int active; - int zone_id; + unsigned long scan; for (scan = 0; scan < nr_to_scan && !list_empty(src); scan++) { + struct page *page; + unsigned long pfn; + unsigned long end_pfn; + unsigned long page_pfn; + int active; + int zone_id; + page = lru_to_page(src); prefetchw_prev_lru_page(page, src, flags); @@ -696,24 +701,26 @@ static unsigned long isolate_lru_pages(u pfn = page_pfn & ~((1 << order) - 1); end_pfn = pfn + (1 << order); for (; pfn < end_pfn; pfn++) { + struct page *cursor_page; + if (unlikely(pfn == page_pfn)) continue; if (unlikely(!pfn_valid(pfn))) break; - tmp = pfn_to_page(pfn); - if (unlikely(page_zone_id(tmp) != zone_id)) + cursor_page = pfn_to_page(pfn); + if (unlikely(page_zone_id(cursor_page) != zone_id)) continue; scan++; - switch (__isolate_lru_page(tmp, active)) { + switch (__isolate_lru_page(cursor_page, active)) { case 0: - list_move(&tmp->lru, dst); + list_move(&cursor_page->lru, dst); nr_taken++; break; case -EBUSY: /* else it is being freed elsewhere */ - list_move(&tmp->lru, src); + list_move(&cursor_page->lru, src); default: break; } _