aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@shadowen.org>2006-12-06 23:33:32 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:25 -0500
commit33f2ef89f8e181486b63fdbdc97c6afa6ca9f34b (patch)
treeb90eac24ff367bc628c44eaa51a9f0ea1b69d1a4
parent3c517a6132098ca37e122a2980fc64a9e798b0d7 (diff)
[PATCH] mm: make compound page destructor handling explicit
Currently we we use the lru head link of the second page of a compound page to hold its destructor. This was ok when it was purely an internal implmentation detail. However, hugetlbfs overrides this destructor violating the layering. Abstract this out as explicit calls, also introduce a type for the callback function allowing them to be type checked. For each callback we pre-declare the function, causing a type error on definition rather than on use elsewhere. [akpm@osdl.org: cleanups] Signed-off-by: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--include/linux/mm.h18
-rw-r--r--mm/hugetlb.c2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/swap.c4
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);
296void split_page(struct page *page, unsigned int order); 296void 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 */
303typedef void compound_page_dtor(struct page *);
304
305static inline void set_compound_page_dtor(struct page *page,
306 compound_page_dtor *dtor)
307{
308 page[1].lru.next = (void *)dtor;
309}
310
311static 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;
diff --git a/mm/swap.c b/mm/swap.c
index d9a3770d8f3c..017e72ca9bbb 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -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}