diff options
-rw-r--r-- | include/linux/mm.h | 18 | ||||
-rw-r--r-- | mm/hugetlb.c | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 | ||||
-rw-r--r-- | mm/swap.c | 4 |
4 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e266fe1b4c4..a17b147c61e7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -296,6 +296,24 @@ void put_pages_list(struct list_head *pages); | |||
296 | void split_page(struct page *page, unsigned int order); | 296 | void split_page(struct page *page, unsigned int order); |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * Compound pages have a destructor function. Provide a | ||
300 | * prototype for that function and accessor functions. | ||
301 | * These are _only_ valid on the head of a PG_compound page. | ||
302 | */ | ||
303 | typedef void compound_page_dtor(struct page *); | ||
304 | |||
305 | static inline void set_compound_page_dtor(struct page *page, | ||
306 | compound_page_dtor *dtor) | ||
307 | { | ||
308 | page[1].lru.next = (void *)dtor; | ||
309 | } | ||
310 | |||
311 | static inline compound_page_dtor *get_compound_page_dtor(struct page *page) | ||
312 | { | ||
313 | return (compound_page_dtor *)page[1].lru.next; | ||
314 | } | ||
315 | |||
316 | /* | ||
299 | * Multiple processes may "see" the same page. E.g. for untouched | 317 | * Multiple processes may "see" the same page. E.g. for untouched |
300 | * mappings of /dev/null, all processes see the same page full of | 318 | * mappings of /dev/null, all processes see the same page full of |
301 | * zeroes, and text pages of executables and shared libraries have | 319 | * zeroes, and text pages of executables and shared libraries have |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 2911a364481e..0ccc7f230252 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -109,7 +109,7 @@ static int alloc_fresh_huge_page(void) | |||
109 | if (nid == MAX_NUMNODES) | 109 | if (nid == MAX_NUMNODES) |
110 | nid = first_node(node_online_map); | 110 | nid = first_node(node_online_map); |
111 | if (page) { | 111 | if (page) { |
112 | page[1].lru.next = (void *)free_huge_page; /* dtor */ | 112 | set_compound_page_dtor(page, free_huge_page); |
113 | spin_lock(&hugetlb_lock); | 113 | spin_lock(&hugetlb_lock); |
114 | nr_huge_pages++; | 114 | nr_huge_pages++; |
115 | nr_huge_pages_node[page_to_nid(page)]++; | 115 | nr_huge_pages_node[page_to_nid(page)]++; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index dc8753bdd47e..d539f83c62b6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -230,7 +230,7 @@ static void prep_compound_page(struct page *page, unsigned long order) | |||
230 | int i; | 230 | int i; |
231 | int nr_pages = 1 << order; | 231 | int nr_pages = 1 << order; |
232 | 232 | ||
233 | page[1].lru.next = (void *)free_compound_page; /* set dtor */ | 233 | set_compound_page_dtor(page, free_compound_page); |
234 | page[1].lru.prev = (void *)order; | 234 | page[1].lru.prev = (void *)order; |
235 | for (i = 0; i < nr_pages; i++) { | 235 | for (i = 0; i < nr_pages; i++) { |
236 | struct page *p = page + i; | 236 | struct page *p = page + i; |
@@ -57,9 +57,9 @@ static void put_compound_page(struct page *page) | |||
57 | { | 57 | { |
58 | page = (struct page *)page_private(page); | 58 | page = (struct page *)page_private(page); |
59 | if (put_page_testzero(page)) { | 59 | if (put_page_testzero(page)) { |
60 | void (*dtor)(struct page *page); | 60 | compound_page_dtor *dtor; |
61 | 61 | ||
62 | dtor = (void (*)(struct page *))page[1].lru.next; | 62 | dtor = get_compound_page_dtor(page); |
63 | (*dtor)(page); | 63 | (*dtor)(page); |
64 | } | 64 | } |
65 | } | 65 | } |