diff options
-rw-r--r-- | mm/page_alloc.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 676aec93d699..e1d87ee1d9c6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -765,6 +765,23 @@ int move_freepages_block(struct zone *zone, struct page *page, int migratetype) | |||
765 | return move_freepages(zone, start_page, end_page, migratetype); | 765 | return move_freepages(zone, start_page, end_page, migratetype); |
766 | } | 766 | } |
767 | 767 | ||
768 | /* Return the page with the lowest PFN in the list */ | ||
769 | static struct page *min_page(struct list_head *list) | ||
770 | { | ||
771 | unsigned long min_pfn = -1UL; | ||
772 | struct page *min_page = NULL, *page;; | ||
773 | |||
774 | list_for_each_entry(page, list, lru) { | ||
775 | unsigned long pfn = page_to_pfn(page); | ||
776 | if (pfn < min_pfn) { | ||
777 | min_pfn = pfn; | ||
778 | min_page = page; | ||
779 | } | ||
780 | } | ||
781 | |||
782 | return min_page; | ||
783 | } | ||
784 | |||
768 | /* Remove an element from the buddy allocator from the fallback list */ | 785 | /* Remove an element from the buddy allocator from the fallback list */ |
769 | static struct page *__rmqueue_fallback(struct zone *zone, int order, | 786 | static struct page *__rmqueue_fallback(struct zone *zone, int order, |
770 | int start_migratetype) | 787 | int start_migratetype) |
@@ -795,8 +812,11 @@ retry: | |||
795 | if (list_empty(&area->free_list[migratetype])) | 812 | if (list_empty(&area->free_list[migratetype])) |
796 | continue; | 813 | continue; |
797 | 814 | ||
815 | /* Bias kernel allocations towards low pfns */ | ||
798 | page = list_entry(area->free_list[migratetype].next, | 816 | page = list_entry(area->free_list[migratetype].next, |
799 | struct page, lru); | 817 | struct page, lru); |
818 | if (unlikely(start_migratetype != MIGRATE_MOVABLE)) | ||
819 | page = min_page(&area->free_list[migratetype]); | ||
800 | area->nr_free--; | 820 | area->nr_free--; |
801 | 821 | ||
802 | /* | 822 | /* |