summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 0e266fe1b4c..a17b147c61e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -296,6 +296,24 @@ void put_pages_list(struct list_head *pages);
void split_page(struct page *page, unsigned int order);
/*
+ * Compound pages have a destructor function. Provide a
+ * prototype for that function and accessor functions.
+ * These are _only_ valid on the head of a PG_compound page.
+ */
+typedef void compound_page_dtor(struct page *);
+
+static inline void set_compound_page_dtor(struct page *page,
+ compound_page_dtor *dtor)
+{
+ page[1].lru.next = (void *)dtor;
+}
+
+static inline compound_page_dtor *get_compound_page_dtor(struct page *page)
+{
+ return (compound_page_dtor *)page[1].lru.next;
+}
+
+/*
* Multiple processes may "see" the same page. E.g. for untouched
* mappings of /dev/null, all processes see the same page full of
* zeroes, and text pages of executables and shared libraries have
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 2911a364481..0ccc7f23025 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -109,7 +109,7 @@ static int alloc_fresh_huge_page(void)
if (nid == MAX_NUMNODES)
nid = first_node(node_online_map);
if (page) {
- page[1].lru.next = (void *)free_huge_page; /* dtor */
+ set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock);
nr_huge_pages++;
nr_huge_pages_node[page_to_nid(page)]++;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dc8753bdd47..d539f83c62b 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)
int i;
int nr_pages = 1 << order;
- page[1].lru.next = (void *)free_compound_page; /* set dtor */
+ set_compound_page_dtor(page, free_compound_page);
page[1].lru.prev = (void *)order;
for (i = 0; i < nr_pages; i++) {
struct page *p = page + i;
diff --git a/mm/swap.c b/mm/swap.c
index d9a3770d8f3..017e72ca9bb 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -57,9 +57,9 @@ static void put_compound_page(struct page *page)
{
page = (struct page *)page_private(page);
if (put_page_testzero(page)) {
- void (*dtor)(struct page *page);
+ compound_page_dtor *dtor;
- dtor = (void (*)(struct page *))page[1].lru.next;
+ dtor = get_compound_page_dtor(page);
(*dtor)(page);
}
}