diff options
-rw-r--r-- | fs/buffer.c | 2 | ||||
-rw-r--r-- | fs/inode.c | 10 | ||||
-rw-r--r-- | fs/ramfs/inode.c | 1 | ||||
-rw-r--r-- | include/asm-alpha/page.h | 3 | ||||
-rw-r--r-- | include/asm-cris/page.h | 3 | ||||
-rw-r--r-- | include/asm-h8300/page.h | 3 | ||||
-rw-r--r-- | include/asm-i386/page.h | 3 | ||||
-rw-r--r-- | include/asm-ia64/page.h | 13 | ||||
-rw-r--r-- | include/asm-m32r/page.h | 3 | ||||
-rw-r--r-- | include/asm-m68knommu/page.h | 3 | ||||
-rw-r--r-- | include/asm-s390/page.h | 3 | ||||
-rw-r--r-- | include/asm-x86_64/page.h | 3 | ||||
-rw-r--r-- | include/linux/gfp.h | 16 | ||||
-rw-r--r-- | include/linux/highmem.h | 51 | ||||
-rw-r--r-- | mm/memory.c | 9 | ||||
-rw-r--r-- | mm/mempolicy.c | 5 | ||||
-rw-r--r-- | mm/migrate.c | 3 | ||||
-rw-r--r-- | mm/shmem.c | 7 | ||||
-rw-r--r-- | mm/swap_state.c | 3 |
19 files changed, 114 insertions, 30 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 424165b569f8..94344b2e0b46 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -982,7 +982,7 @@ grow_dev_page(struct block_device *bdev, sector_t block, | |||
982 | struct buffer_head *bh; | 982 | struct buffer_head *bh; |
983 | 983 | ||
984 | page = find_or_create_page(inode->i_mapping, index, | 984 | page = find_or_create_page(inode->i_mapping, index, |
985 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 985 | (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); |
986 | if (!page) | 986 | if (!page) |
987 | return NULL; | 987 | return NULL; |
988 | 988 | ||
diff --git a/fs/inode.c b/fs/inode.c index 9a012cc5b6cd..47b87b071de3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -145,7 +145,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
145 | mapping->a_ops = &empty_aops; | 145 | mapping->a_ops = &empty_aops; |
146 | mapping->host = inode; | 146 | mapping->host = inode; |
147 | mapping->flags = 0; | 147 | mapping->flags = 0; |
148 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER); | 148 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE); |
149 | mapping->assoc_mapping = NULL; | 149 | mapping->assoc_mapping = NULL; |
150 | mapping->backing_dev_info = &default_backing_dev_info; | 150 | mapping->backing_dev_info = &default_backing_dev_info; |
151 | 151 | ||
@@ -519,7 +519,13 @@ repeat: | |||
519 | * new_inode - obtain an inode | 519 | * new_inode - obtain an inode |
520 | * @sb: superblock | 520 | * @sb: superblock |
521 | * | 521 | * |
522 | * Allocates a new inode for given superblock. | 522 | * Allocates a new inode for given superblock. The default gfp_mask |
523 | * for allocations related to inode->i_mapping is GFP_HIGHUSER_PAGECACHE. | ||
524 | * If HIGHMEM pages are unsuitable or it is known that pages allocated | ||
525 | * for the page cache are not reclaimable or migratable, | ||
526 | * mapping_set_gfp_mask() must be called with suitable flags on the | ||
527 | * newly created inode's mapping | ||
528 | * | ||
523 | */ | 529 | */ |
524 | struct inode *new_inode(struct super_block *sb) | 530 | struct inode *new_inode(struct super_block *sb) |
525 | { | 531 | { |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index d40d22b347b7..ef2b46d099ff 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -60,6 +60,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
60 | inode->i_blocks = 0; | 60 | inode->i_blocks = 0; |
61 | inode->i_mapping->a_ops = &ramfs_aops; | 61 | inode->i_mapping->a_ops = &ramfs_aops; |
62 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | 62 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
63 | mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); | ||
63 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 64 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
64 | switch (mode & S_IFMT) { | 65 | switch (mode & S_IFMT) { |
65 | default: | 66 | default: |
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index d2bed3cb33ff..bae7f05716d4 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h | |||
@@ -17,7 +17,8 @@ | |||
17 | extern void clear_page(void *page); | 17 | extern void clear_page(void *page); |
18 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 18 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
19 | 19 | ||
20 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vmaddr) | 20 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
21 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vmaddr) | ||
21 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 22 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
22 | 23 | ||
23 | extern void copy_page(void * _to, void * _from); | 24 | extern void copy_page(void * _to, void * _from); |
diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index 9f13c32552bf..0648e3153f81 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h | |||
@@ -20,7 +20,8 @@ | |||
20 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 20 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
21 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 21 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
22 | 22 | ||
23 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 23 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
24 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
24 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 25 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
25 | 26 | ||
26 | /* | 27 | /* |
diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h index 3b4f2903f91d..c8cc81a3aca5 100644 --- a/include/asm-h8300/page.h +++ b/include/asm-h8300/page.h | |||
@@ -22,7 +22,8 @@ | |||
22 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 22 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
23 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 23 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
24 | 24 | ||
25 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 25 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
26 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
26 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 27 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
27 | 28 | ||
28 | /* | 29 | /* |
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 818ac8bf01e2..99cf5d3692a9 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h | |||
@@ -34,7 +34,8 @@ | |||
34 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 34 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
35 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 35 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
36 | 36 | ||
37 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 37 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
38 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
38 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 39 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
39 | 40 | ||
40 | /* | 41 | /* |
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 485759ba9e36..d6345464a2b3 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h | |||
@@ -87,12 +87,13 @@ do { \ | |||
87 | } while (0) | 87 | } while (0) |
88 | 88 | ||
89 | 89 | ||
90 | #define alloc_zeroed_user_highpage(vma, vaddr) \ | 90 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
91 | ({ \ | 91 | ({ \ |
92 | struct page *page = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr); \ | 92 | struct page *page = alloc_page_vma( \ |
93 | if (page) \ | 93 | GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr); \ |
94 | flush_dcache_page(page); \ | 94 | if (page) \ |
95 | page; \ | 95 | flush_dcache_page(page); \ |
96 | page; \ | ||
96 | }) | 97 | }) |
97 | 98 | ||
98 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 99 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h index 6f6ecf7d14a3..04fd183a2c58 100644 --- a/include/asm-m32r/page.h +++ b/include/asm-m32r/page.h | |||
@@ -15,7 +15,8 @@ extern void copy_page(void *to, void *from); | |||
15 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 15 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
16 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 16 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
17 | 17 | ||
18 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 18 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
19 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
19 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 20 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
20 | 21 | ||
21 | /* | 22 | /* |
diff --git a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h index 2a1b8bdcb29c..9efa0a9851b1 100644 --- a/include/asm-m68knommu/page.h +++ b/include/asm-m68knommu/page.h | |||
@@ -22,7 +22,8 @@ | |||
22 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 22 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
23 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 23 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
24 | 24 | ||
25 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 25 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
26 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
26 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 27 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
27 | 28 | ||
28 | /* | 29 | /* |
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index 05ea6f172786..f326451ed6ec 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h | |||
@@ -64,7 +64,8 @@ static inline void copy_page(void *to, void *from) | |||
64 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 64 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
65 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 65 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
66 | 66 | ||
67 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 67 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
68 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
68 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 69 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
69 | 70 | ||
70 | /* | 71 | /* |
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index e327c830da0c..88adf1afb0a2 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h | |||
@@ -48,7 +48,8 @@ void copy_page(void *, void *); | |||
48 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 48 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
49 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 49 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
50 | 50 | ||
51 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | 51 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ |
52 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
52 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 53 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
53 | /* | 54 | /* |
54 | * These are used to make use of C type-checking.. | 55 | * These are used to make use of C type-checking.. |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0d2ef0b082a6..e5882fe49f83 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -30,6 +30,9 @@ struct vm_area_struct; | |||
30 | * cannot handle allocation failures. | 30 | * cannot handle allocation failures. |
31 | * | 31 | * |
32 | * __GFP_NORETRY: The VM implementation must not retry indefinitely. | 32 | * __GFP_NORETRY: The VM implementation must not retry indefinitely. |
33 | * | ||
34 | * __GFP_MOVABLE: Flag that this page will be movable by the page migration | ||
35 | * mechanism or reclaimed | ||
33 | */ | 36 | */ |
34 | #define __GFP_WAIT ((__force gfp_t)0x10u) /* Can wait and reschedule? */ | 37 | #define __GFP_WAIT ((__force gfp_t)0x10u) /* Can wait and reschedule? */ |
35 | #define __GFP_HIGH ((__force gfp_t)0x20u) /* Should access emergency pools? */ | 38 | #define __GFP_HIGH ((__force gfp_t)0x20u) /* Should access emergency pools? */ |
@@ -45,6 +48,7 @@ struct vm_area_struct; | |||
45 | #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */ | 48 | #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */ |
46 | #define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ | 49 | #define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ |
47 | #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ | 50 | #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ |
51 | #define __GFP_MOVABLE ((__force gfp_t)0x80000u) /* Page is movable */ | ||
48 | 52 | ||
49 | #define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */ | 53 | #define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */ |
50 | #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) | 54 | #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) |
@@ -53,7 +57,8 @@ struct vm_area_struct; | |||
53 | #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ | 57 | #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ |
54 | __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ | 58 | __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ |
55 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_COMP| \ | 59 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_COMP| \ |
56 | __GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_THISNODE) | 60 | __GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_THISNODE| \ |
61 | __GFP_MOVABLE) | ||
57 | 62 | ||
58 | /* This equals 0, but use constants in case they ever change */ | 63 | /* This equals 0, but use constants in case they ever change */ |
59 | #define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) | 64 | #define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) |
@@ -65,6 +70,15 @@ struct vm_area_struct; | |||
65 | #define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL) | 70 | #define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL) |
66 | #define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ | 71 | #define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ |
67 | __GFP_HIGHMEM) | 72 | __GFP_HIGHMEM) |
73 | #define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \ | ||
74 | __GFP_HARDWALL | __GFP_HIGHMEM | \ | ||
75 | __GFP_MOVABLE) | ||
76 | #define GFP_NOFS_PAGECACHE (__GFP_WAIT | __GFP_IO | __GFP_MOVABLE) | ||
77 | #define GFP_USER_PAGECACHE (__GFP_WAIT | __GFP_IO | __GFP_FS | \ | ||
78 | __GFP_HARDWALL | __GFP_MOVABLE) | ||
79 | #define GFP_HIGHUSER_PAGECACHE (__GFP_WAIT | __GFP_IO | __GFP_FS | \ | ||
80 | __GFP_HARDWALL | __GFP_HIGHMEM | \ | ||
81 | __GFP_MOVABLE) | ||
68 | 82 | ||
69 | #ifdef CONFIG_NUMA | 83 | #ifdef CONFIG_NUMA |
70 | #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) | 84 | #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 98e2cce996a4..12c5e4e3135a 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -73,10 +73,27 @@ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 75 | #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
76 | /** | ||
77 | * __alloc_zeroed_user_highpage - Allocate a zeroed HIGHMEM page for a VMA with caller-specified movable GFP flags | ||
78 | * @movableflags: The GFP flags related to the pages future ability to move like __GFP_MOVABLE | ||
79 | * @vma: The VMA the page is to be allocated for | ||
80 | * @vaddr: The virtual address the page will be inserted into | ||
81 | * | ||
82 | * This function will allocate a page for a VMA but the caller is expected | ||
83 | * to specify via movableflags whether the page will be movable in the | ||
84 | * future or not | ||
85 | * | ||
86 | * An architecture may override this function by defining | ||
87 | * __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE and providing their own | ||
88 | * implementation. | ||
89 | */ | ||
76 | static inline struct page * | 90 | static inline struct page * |
77 | alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr) | 91 | __alloc_zeroed_user_highpage(gfp_t movableflags, |
92 | struct vm_area_struct *vma, | ||
93 | unsigned long vaddr) | ||
78 | { | 94 | { |
79 | struct page *page = alloc_page_vma(GFP_HIGHUSER, vma, vaddr); | 95 | struct page *page = alloc_page_vma(GFP_HIGHUSER | movableflags, |
96 | vma, vaddr); | ||
80 | 97 | ||
81 | if (page) | 98 | if (page) |
82 | clear_user_highpage(page, vaddr); | 99 | clear_user_highpage(page, vaddr); |
@@ -85,6 +102,36 @@ alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr) | |||
85 | } | 102 | } |
86 | #endif | 103 | #endif |
87 | 104 | ||
105 | /** | ||
106 | * alloc_zeroed_user_highpage - Allocate a zeroed HIGHMEM page for a VMA | ||
107 | * @vma: The VMA the page is to be allocated for | ||
108 | * @vaddr: The virtual address the page will be inserted into | ||
109 | * | ||
110 | * This function will allocate a page for a VMA that the caller knows will | ||
111 | * not be able to move in the future using move_pages() or reclaim. If it | ||
112 | * is known that the page can move, use alloc_zeroed_user_highpage_movable | ||
113 | */ | ||
114 | static inline struct page * | ||
115 | alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr) | ||
116 | { | ||
117 | return __alloc_zeroed_user_highpage(0, vma, vaddr); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * alloc_zeroed_user_highpage_movable - Allocate a zeroed HIGHMEM page for a VMA that the caller knows can move | ||
122 | * @vma: The VMA the page is to be allocated for | ||
123 | * @vaddr: The virtual address the page will be inserted into | ||
124 | * | ||
125 | * This function will allocate a page for a VMA that the caller knows will | ||
126 | * be able to migrate in the future using move_pages() or reclaimed | ||
127 | */ | ||
128 | static inline struct page * | ||
129 | alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, | ||
130 | unsigned long vaddr) | ||
131 | { | ||
132 | return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr); | ||
133 | } | ||
134 | |||
88 | static inline void clear_highpage(struct page *page) | 135 | static inline void clear_highpage(struct page *page) |
89 | { | 136 | { |
90 | void *kaddr = kmap_atomic(page, KM_USER0); | 137 | void *kaddr = kmap_atomic(page, KM_USER0); |
diff --git a/mm/memory.c b/mm/memory.c index b3d73bb1f680..9c6ff7fffdc8 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1715,11 +1715,11 @@ gotten: | |||
1715 | if (unlikely(anon_vma_prepare(vma))) | 1715 | if (unlikely(anon_vma_prepare(vma))) |
1716 | goto oom; | 1716 | goto oom; |
1717 | if (old_page == ZERO_PAGE(address)) { | 1717 | if (old_page == ZERO_PAGE(address)) { |
1718 | new_page = alloc_zeroed_user_highpage(vma, address); | 1718 | new_page = alloc_zeroed_user_highpage_movable(vma, address); |
1719 | if (!new_page) | 1719 | if (!new_page) |
1720 | goto oom; | 1720 | goto oom; |
1721 | } else { | 1721 | } else { |
1722 | new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); | 1722 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); |
1723 | if (!new_page) | 1723 | if (!new_page) |
1724 | goto oom; | 1724 | goto oom; |
1725 | cow_user_page(new_page, old_page, address, vma); | 1725 | cow_user_page(new_page, old_page, address, vma); |
@@ -2237,7 +2237,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2237 | 2237 | ||
2238 | if (unlikely(anon_vma_prepare(vma))) | 2238 | if (unlikely(anon_vma_prepare(vma))) |
2239 | goto oom; | 2239 | goto oom; |
2240 | page = alloc_zeroed_user_highpage(vma, address); | 2240 | page = alloc_zeroed_user_highpage_movable(vma, address); |
2241 | if (!page) | 2241 | if (!page) |
2242 | goto oom; | 2242 | goto oom; |
2243 | 2243 | ||
@@ -2340,7 +2340,8 @@ retry: | |||
2340 | 2340 | ||
2341 | if (unlikely(anon_vma_prepare(vma))) | 2341 | if (unlikely(anon_vma_prepare(vma))) |
2342 | goto oom; | 2342 | goto oom; |
2343 | page = alloc_page_vma(GFP_HIGHUSER, vma, address); | 2343 | page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, |
2344 | vma, address); | ||
2344 | if (!page) | 2345 | if (!page) |
2345 | goto oom; | 2346 | goto oom; |
2346 | copy_user_highpage(page, new_page, address, vma); | 2347 | copy_user_highpage(page, new_page, address, vma); |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 188f8d9c4aed..4c0f99996811 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -594,7 +594,7 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, | |||
594 | 594 | ||
595 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) | 595 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) |
596 | { | 596 | { |
597 | return alloc_pages_node(node, GFP_HIGHUSER, 0); | 597 | return alloc_pages_node(node, GFP_HIGHUSER_MOVABLE, 0); |
598 | } | 598 | } |
599 | 599 | ||
600 | /* | 600 | /* |
@@ -710,7 +710,8 @@ static struct page *new_vma_page(struct page *page, unsigned long private, int * | |||
710 | { | 710 | { |
711 | struct vm_area_struct *vma = (struct vm_area_struct *)private; | 711 | struct vm_area_struct *vma = (struct vm_area_struct *)private; |
712 | 712 | ||
713 | return alloc_page_vma(GFP_HIGHUSER, vma, page_address_in_vma(page, vma)); | 713 | return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, |
714 | page_address_in_vma(page, vma)); | ||
714 | } | 715 | } |
715 | #else | 716 | #else |
716 | 717 | ||
diff --git a/mm/migrate.c b/mm/migrate.c index a91ca00abebe..34d8ada053e4 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -761,7 +761,8 @@ static struct page *new_page_node(struct page *p, unsigned long private, | |||
761 | 761 | ||
762 | *result = &pm->status; | 762 | *result = &pm->status; |
763 | 763 | ||
764 | return alloc_pages_node(pm->node, GFP_HIGHUSER | GFP_THISNODE, 0); | 764 | return alloc_pages_node(pm->node, |
765 | GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); | ||
765 | } | 766 | } |
766 | 767 | ||
767 | /* | 768 | /* |
diff --git a/mm/shmem.c b/mm/shmem.c index 0493e4d0bcaa..e49181d9d893 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -93,8 +93,11 @@ static inline struct page *shmem_dir_alloc(gfp_t gfp_mask) | |||
93 | * The above definition of ENTRIES_PER_PAGE, and the use of | 93 | * The above definition of ENTRIES_PER_PAGE, and the use of |
94 | * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE: | 94 | * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE: |
95 | * might be reconsidered if it ever diverges from PAGE_SIZE. | 95 | * might be reconsidered if it ever diverges from PAGE_SIZE. |
96 | * | ||
97 | * __GFP_MOVABLE is masked out as swap vectors cannot move | ||
96 | */ | 98 | */ |
97 | return alloc_pages(gfp_mask, PAGE_CACHE_SHIFT-PAGE_SHIFT); | 99 | return alloc_pages((gfp_mask & ~__GFP_MOVABLE) | __GFP_ZERO, |
100 | PAGE_CACHE_SHIFT-PAGE_SHIFT); | ||
98 | } | 101 | } |
99 | 102 | ||
100 | static inline void shmem_dir_free(struct page *page) | 103 | static inline void shmem_dir_free(struct page *page) |
@@ -372,7 +375,7 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long | |||
372 | } | 375 | } |
373 | 376 | ||
374 | spin_unlock(&info->lock); | 377 | spin_unlock(&info->lock); |
375 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO); | 378 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping)); |
376 | if (page) | 379 | if (page) |
377 | set_page_private(page, 0); | 380 | set_page_private(page, 0); |
378 | spin_lock(&info->lock); | 381 | spin_lock(&info->lock); |
diff --git a/mm/swap_state.c b/mm/swap_state.c index 925d5c50f18d..67daecb6031a 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -334,7 +334,8 @@ struct page *read_swap_cache_async(swp_entry_t entry, | |||
334 | * Get a new page to read into from swap. | 334 | * Get a new page to read into from swap. |
335 | */ | 335 | */ |
336 | if (!new_page) { | 336 | if (!new_page) { |
337 | new_page = alloc_page_vma(GFP_HIGHUSER, vma, addr); | 337 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, |
338 | vma, addr); | ||
338 | if (!new_page) | 339 | if (!new_page) |
339 | break; /* Out of memory */ | 340 | break; /* Out of memory */ |
340 | } | 341 | } |