diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-11 23:15:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 23:15:46 -0700 |
| commit | 3c7011b3e90508f2f3adb895d712d36b1cfdcfd2 (patch) | |
| tree | 7bc0c30404997ed7c4e631f9c947bbf8918509de /include | |
| parent | 60af4464478e1511998ad82d7cba3fbfb6c258dd (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.h | 6 | ||||
| -rw-r--r-- | include/linux/mm.h | 4 | ||||
| -rw-r--r-- | include/linux/slab.h | 4 |
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 */ |
