diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb.c | 5 | ||||
-rw-r--r-- | mm/internal.h | 13 | ||||
-rw-r--r-- | mm/page_alloc.c | 14 |
3 files changed, 21 insertions, 11 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 39d49ecea8e8..20117a4b8ab6 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | 19 | ||
20 | #include <linux/hugetlb.h> | 20 | #include <linux/hugetlb.h> |
21 | #include "internal.h" | ||
21 | 22 | ||
22 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; | 23 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; |
23 | static unsigned long nr_huge_pages, free_huge_pages; | 24 | static unsigned long nr_huge_pages, free_huge_pages; |
@@ -106,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr) | |||
106 | return NULL; | 107 | return NULL; |
107 | } | 108 | } |
108 | spin_unlock(&hugetlb_lock); | 109 | spin_unlock(&hugetlb_lock); |
109 | set_page_count(page, 1); | 110 | set_page_refcounted(page); |
110 | for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) | 111 | for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) |
111 | clear_user_highpage(&page[i], addr); | 112 | clear_user_highpage(&page[i], addr); |
112 | return page; | 113 | return page; |
@@ -152,7 +153,7 @@ static void update_and_free_page(struct page *page) | |||
152 | 1 << PG_private | 1<< PG_writeback); | 153 | 1 << PG_private | 1<< PG_writeback); |
153 | } | 154 | } |
154 | page[1].lru.next = NULL; | 155 | page[1].lru.next = NULL; |
155 | set_page_count(page, 1); | 156 | set_page_refcounted(page); |
156 | __free_pages(page, HUGETLB_PAGE_ORDER); | 157 | __free_pages(page, HUGETLB_PAGE_ORDER); |
157 | } | 158 | } |
158 | 159 | ||
diff --git a/mm/internal.h b/mm/internal.h index 7bb339779818..d20e3cc4aef0 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -13,8 +13,19 @@ | |||
13 | 13 | ||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | 15 | ||
16 | static inline void set_page_refs(struct page *page, int order) | 16 | static inline void set_page_count(struct page *page, int v) |
17 | { | 17 | { |
18 | atomic_set(&page->_count, v); | ||
19 | } | ||
20 | |||
21 | /* | ||
22 | * Turn a non-refcounted page (->_count == 0) into refcounted with | ||
23 | * a count of one. | ||
24 | */ | ||
25 | static inline void set_page_refcounted(struct page *page) | ||
26 | { | ||
27 | BUG_ON(PageCompound(page) && page_private(page) != (unsigned long)page); | ||
28 | BUG_ON(atomic_read(&page->_count)); | ||
18 | set_page_count(page, 1); | 29 | set_page_count(page, 1); |
19 | } | 30 | } |
20 | 31 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e197818a7cf6..7f65b5a63bb3 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -442,7 +442,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order) | |||
442 | if (order == 0) { | 442 | if (order == 0) { |
443 | __ClearPageReserved(page); | 443 | __ClearPageReserved(page); |
444 | set_page_count(page, 0); | 444 | set_page_count(page, 0); |
445 | set_page_refs(page, 0); | 445 | set_page_refcounted(page); |
446 | __free_page(page); | 446 | __free_page(page); |
447 | } else { | 447 | } else { |
448 | int loop; | 448 | int loop; |
@@ -457,7 +457,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order) | |||
457 | set_page_count(p, 0); | 457 | set_page_count(p, 0); |
458 | } | 458 | } |
459 | 459 | ||
460 | set_page_refs(page, order); | 460 | set_page_refcounted(page); |
461 | __free_pages(page, order); | 461 | __free_pages(page, order); |
462 | } | 462 | } |
463 | } | 463 | } |
@@ -525,7 +525,7 @@ static int prep_new_page(struct page *page, int order) | |||
525 | 1 << PG_referenced | 1 << PG_arch_1 | | 525 | 1 << PG_referenced | 1 << PG_arch_1 | |
526 | 1 << PG_checked | 1 << PG_mappedtodisk); | 526 | 1 << PG_checked | 1 << PG_mappedtodisk); |
527 | set_page_private(page, 0); | 527 | set_page_private(page, 0); |
528 | set_page_refs(page, order); | 528 | set_page_refcounted(page); |
529 | kernel_map_pages(page, 1 << order, 1); | 529 | kernel_map_pages(page, 1 << order, 1); |
530 | return 0; | 530 | return 0; |
531 | } | 531 | } |
@@ -755,10 +755,8 @@ void split_page(struct page *page, unsigned int order) | |||
755 | 755 | ||
756 | BUG_ON(PageCompound(page)); | 756 | BUG_ON(PageCompound(page)); |
757 | BUG_ON(!page_count(page)); | 757 | BUG_ON(!page_count(page)); |
758 | for (i = 1; i < (1 << order); i++) { | 758 | for (i = 1; i < (1 << order); i++) |
759 | BUG_ON(page_count(page + i)); | 759 | set_page_refcounted(page + i); |
760 | set_page_count(page + i, 1); | ||
761 | } | ||
762 | } | 760 | } |
763 | 761 | ||
764 | /* | 762 | /* |
@@ -1771,7 +1769,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, | |||
1771 | continue; | 1769 | continue; |
1772 | page = pfn_to_page(pfn); | 1770 | page = pfn_to_page(pfn); |
1773 | set_page_links(page, zone, nid, pfn); | 1771 | set_page_links(page, zone, nid, pfn); |
1774 | set_page_count(page, 1); | 1772 | init_page_count(page); |
1775 | reset_page_mapcount(page); | 1773 | reset_page_mapcount(page); |
1776 | SetPageReserved(page); | 1774 | SetPageReserved(page); |
1777 | INIT_LIST_HEAD(&page->lru); | 1775 | INIT_LIST_HEAD(&page->lru); |