diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7f65b5a63bb3..bdff85899638 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -212,6 +212,15 @@ static void destroy_compound_page(struct page *page, unsigned long order) | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) | ||
216 | { | ||
217 | int i; | ||
218 | |||
219 | BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); | ||
220 | for (i = 0; i < (1 << order); i++) | ||
221 | clear_highpage(page + i); | ||
222 | } | ||
223 | |||
215 | /* | 224 | /* |
216 | * function for dealing with page's order in buddy system. | 225 | * function for dealing with page's order in buddy system. |
217 | * zone->lock is already acquired when we use these. | 226 | * zone->lock is already acquired when we use these. |
@@ -496,7 +505,7 @@ static inline void expand(struct zone *zone, struct page *page, | |||
496 | /* | 505 | /* |
497 | * This page is about to be returned from the page allocator | 506 | * This page is about to be returned from the page allocator |
498 | */ | 507 | */ |
499 | static int prep_new_page(struct page *page, int order) | 508 | static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) |
500 | { | 509 | { |
501 | if (unlikely(page_mapcount(page) | | 510 | if (unlikely(page_mapcount(page) | |
502 | (page->mapping != NULL) | | 511 | (page->mapping != NULL) | |
@@ -527,6 +536,13 @@ static int prep_new_page(struct page *page, int order) | |||
527 | set_page_private(page, 0); | 536 | set_page_private(page, 0); |
528 | set_page_refcounted(page); | 537 | set_page_refcounted(page); |
529 | kernel_map_pages(page, 1 << order, 1); | 538 | kernel_map_pages(page, 1 << order, 1); |
539 | |||
540 | if (gfp_flags & __GFP_ZERO) | ||
541 | prep_zero_page(page, order, gfp_flags); | ||
542 | |||
543 | if (order && (gfp_flags & __GFP_COMP)) | ||
544 | prep_compound_page(page, order); | ||
545 | |||
530 | return 0; | 546 | return 0; |
531 | } | 547 | } |
532 | 548 | ||
@@ -732,15 +748,6 @@ void fastcall free_cold_page(struct page *page) | |||
732 | free_hot_cold_page(page, 1); | 748 | free_hot_cold_page(page, 1); |
733 | } | 749 | } |
734 | 750 | ||
735 | static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) | ||
736 | { | ||
737 | int i; | ||
738 | |||
739 | BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); | ||
740 | for(i = 0; i < (1 << order); i++) | ||
741 | clear_highpage(page + i); | ||
742 | } | ||
743 | |||
744 | /* | 751 | /* |
745 | * split_page takes a non-compound higher-order page, and splits it into | 752 | * split_page takes a non-compound higher-order page, and splits it into |
746 | * n (1<<order) sub-pages: page[0..n] | 753 | * n (1<<order) sub-pages: page[0..n] |
@@ -802,14 +809,8 @@ again: | |||
802 | put_cpu(); | 809 | put_cpu(); |
803 | 810 | ||
804 | BUG_ON(bad_range(zone, page)); | 811 | BUG_ON(bad_range(zone, page)); |
805 | if (prep_new_page(page, order)) | 812 | if (prep_new_page(page, order, gfp_flags)) |
806 | goto again; | 813 | goto again; |
807 | |||
808 | if (gfp_flags & __GFP_ZERO) | ||
809 | prep_zero_page(page, order, gfp_flags); | ||
810 | |||
811 | if (order && (gfp_flags & __GFP_COMP)) | ||
812 | prep_compound_page(page, order); | ||
813 | return page; | 814 | return page; |
814 | 815 | ||
815 | failed: | 816 | failed: |