summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 23:15:46 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 23:15:46 -0700
commit3c7011b3e90508f2f3adb895d712d36b1cfdcfd2 (patch)
tree7bc0c30404997ed7c4e631f9c947bbf8918509de /include
parent60af4464478e1511998ad82d7cba3fbfb6c258dd (diff)
[PATCH] use compound pages for hugetlb pages only
The compound page logic is a little fragile - it relies on additional metadata in the pageframes which some other kernel code likes to stomp on (xfs was doing this). Also, because we're treating all higher-order pages as compound pages it is no longer possible to free individual lower-order pages from the middle of higher-order pages. At least one ARM driver insists on doing this. We only really need the compound page logic for higher-order pages which can be mapped into user pagetables and placed under direct-io. This covers hugetlb pages and, conceivably, soundcard DMA buffers which were allcoated with a higher-order allocation but which weren't marked PageReserved. The patch arranges for the hugetlb implications to allocate their pages with compound page metadata, and all other higher-order allocations go back to the old way. (Andrea supplied the GFP_LEVEL_MASK fix)
Diffstat (limited to 'include')
-rw-r--r--include/linux/gfp.h6
-rw-r--r--include/linux/mm.h4
-rw-r--r--include/linux/slab.h4
3 files changed, 9 insertions, 5 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index c9695427a435..679fc963f842 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -32,10 +32,16 @@
#define __GFP_NOFAIL 0x800 /* Retry for ever. Cannot fail */
#define __GFP_NORETRY 0x1000 /* Do not retry. Might fail */
#define __GFP_NO_GROW 0x2000 /* Slab internal usage */
+#define __GFP_COMP 0x4000 /* Add compound page metadata */
#define __GFP_BITS_SHIFT 16 /* Room for 16 __GFP_FOO bits */
#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
+/* if you forget to add the bitmask here kernel will crash, period */
+#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
+ __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
+ __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP)
+
#define GFP_ATOMIC (__GFP_HIGH)
#define GFP_NOIO (__GFP_WAIT)
#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2ba5ab34cbdd..f827be900157 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -247,14 +247,14 @@ static inline int page_count(struct page *p)
static inline void get_page(struct page *page)
{
- if (PageCompound(page))
+ if (unlikely(PageCompound(page)))
page = (struct page *)page->private;
atomic_inc(&page->count);
}
static inline void put_page(struct page *page)
{
- if (PageCompound(page)) {
+ if (unlikely(PageCompound(page))) {
page = (struct page *)page->private;
if (put_page_testzero(page)) {
if (page[1].mapping) { /* destructor? */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 69be5b308a11..806cc52abd3a 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -25,9 +25,7 @@ typedef struct kmem_cache_s kmem_cache_t;
#define SLAB_KERNEL GFP_KERNEL
#define SLAB_DMA GFP_DMA
-#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
- __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT|\
- __GFP_NOFAIL|__GFP_NORETRY)
+#define SLAB_LEVEL_MASK GFP_LEVEL_MASK
#define SLAB_NO_GROW __GFP_NO_GROW /* don't grow a cache */