diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-24 04:11:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-24 04:11:23 -0400 |
commit | 416dfdcdb894432547ead4fcb9fa6a36b396059e (patch) | |
tree | 8033fdda07397a59c5fa98c88927040906ce6c1a /mm | |
parent | 56449f437add737a1e5e1cb7e00f63ac8ead1938 (diff) | |
parent | 091069740304c979f957ceacec39c461d0192158 (diff) |
Merge commit 'v2.6.30-rc3' into tracing/hw-branch-tracing
Conflicts:
arch/x86/kernel/ptrace.c
Merge reason: fix the conflict above, and also pick up the CONFIG_BROKEN
dependency change from upstream so that we can remove it
here.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/Kconfig | 2 | ||||
-rw-r--r-- | mm/filemap.c | 5 | ||||
-rw-r--r-- | mm/memcontrol.c | 2 | ||||
-rw-r--r-- | mm/mmap.c | 2 | ||||
-rw-r--r-- | mm/pdflush.c | 47 | ||||
-rw-r--r-- | mm/shmem.c | 27 | ||||
-rw-r--r-- | mm/util.c | 16 | ||||
-rw-r--r-- | mm/vmscan.c | 17 |
8 files changed, 91 insertions, 27 deletions
diff --git a/mm/Kconfig b/mm/Kconfig index b53427ad30a3..57971d2ab848 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -213,6 +213,8 @@ config UNEVICTABLE_LRU | |||
213 | will use one page flag and increase the code size a little, | 213 | will use one page flag and increase the code size a little, |
214 | say Y unless you know what you are doing. | 214 | say Y unless you know what you are doing. |
215 | 215 | ||
216 | See Documentation/vm/unevictable-lru.txt for more information. | ||
217 | |||
216 | config HAVE_MLOCK | 218 | config HAVE_MLOCK |
217 | bool | 219 | bool |
218 | default y if MMU=y | 220 | default y if MMU=y |
diff --git a/mm/filemap.c b/mm/filemap.c index 2e2d38ebda4b..379ff0bcbf6e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -441,6 +441,7 @@ int filemap_write_and_wait_range(struct address_space *mapping, | |||
441 | } | 441 | } |
442 | return err; | 442 | return err; |
443 | } | 443 | } |
444 | EXPORT_SYMBOL(filemap_write_and_wait_range); | ||
444 | 445 | ||
445 | /** | 446 | /** |
446 | * add_to_page_cache_locked - add a locked page to the pagecache | 447 | * add_to_page_cache_locked - add a locked page to the pagecache |
@@ -567,8 +568,8 @@ EXPORT_SYMBOL(wait_on_page_bit); | |||
567 | 568 | ||
568 | /** | 569 | /** |
569 | * add_page_wait_queue - Add an arbitrary waiter to a page's wait queue | 570 | * add_page_wait_queue - Add an arbitrary waiter to a page's wait queue |
570 | * @page - Page defining the wait queue of interest | 571 | * @page: Page defining the wait queue of interest |
571 | * @waiter - Waiter to add to the queue | 572 | * @waiter: Waiter to add to the queue |
572 | * | 573 | * |
573 | * Add an arbitrary @waiter to the wait queue for the nominated @page. | 574 | * Add an arbitrary @waiter to the wait queue for the nominated @page. |
574 | */ | 575 | */ |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2fc6d6c48238..e44fb0fbb80e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -932,7 +932,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, | |||
932 | if (unlikely(!mem)) | 932 | if (unlikely(!mem)) |
933 | return 0; | 933 | return 0; |
934 | 934 | ||
935 | VM_BUG_ON(mem_cgroup_is_obsolete(mem)); | 935 | VM_BUG_ON(!mem || mem_cgroup_is_obsolete(mem)); |
936 | 936 | ||
937 | while (1) { | 937 | while (1) { |
938 | int ret; | 938 | int ret; |
@@ -1575,7 +1575,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns | |||
1575 | * Overcommit.. This must be the final test, as it will | 1575 | * Overcommit.. This must be the final test, as it will |
1576 | * update security statistics. | 1576 | * update security statistics. |
1577 | */ | 1577 | */ |
1578 | if (security_vm_enough_memory(grow)) | 1578 | if (security_vm_enough_memory_mm(mm, grow)) |
1579 | return -ENOMEM; | 1579 | return -ENOMEM; |
1580 | 1580 | ||
1581 | /* Ok, everything looks good - let it rip */ | 1581 | /* Ok, everything looks good - let it rip */ |
diff --git a/mm/pdflush.c b/mm/pdflush.c index 118905e3d788..f2caf96993f8 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c | |||
@@ -58,6 +58,14 @@ static DEFINE_SPINLOCK(pdflush_lock); | |||
58 | int nr_pdflush_threads = 0; | 58 | int nr_pdflush_threads = 0; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * The max/min number of pdflush threads. R/W by sysctl at | ||
62 | * /proc/sys/vm/nr_pdflush_threads_max/min | ||
63 | */ | ||
64 | int nr_pdflush_threads_max __read_mostly = MAX_PDFLUSH_THREADS; | ||
65 | int nr_pdflush_threads_min __read_mostly = MIN_PDFLUSH_THREADS; | ||
66 | |||
67 | |||
68 | /* | ||
61 | * The time at which the pdflush thread pool last went empty | 69 | * The time at which the pdflush thread pool last went empty |
62 | */ | 70 | */ |
63 | static unsigned long last_empty_jifs; | 71 | static unsigned long last_empty_jifs; |
@@ -68,7 +76,7 @@ static unsigned long last_empty_jifs; | |||
68 | * Thread pool management algorithm: | 76 | * Thread pool management algorithm: |
69 | * | 77 | * |
70 | * - The minimum and maximum number of pdflush instances are bound | 78 | * - The minimum and maximum number of pdflush instances are bound |
71 | * by MIN_PDFLUSH_THREADS and MAX_PDFLUSH_THREADS. | 79 | * by nr_pdflush_threads_min and nr_pdflush_threads_max. |
72 | * | 80 | * |
73 | * - If there have been no idle pdflush instances for 1 second, create | 81 | * - If there have been no idle pdflush instances for 1 second, create |
74 | * a new one. | 82 | * a new one. |
@@ -98,7 +106,6 @@ static int __pdflush(struct pdflush_work *my_work) | |||
98 | INIT_LIST_HEAD(&my_work->list); | 106 | INIT_LIST_HEAD(&my_work->list); |
99 | 107 | ||
100 | spin_lock_irq(&pdflush_lock); | 108 | spin_lock_irq(&pdflush_lock); |
101 | nr_pdflush_threads++; | ||
102 | for ( ; ; ) { | 109 | for ( ; ; ) { |
103 | struct pdflush_work *pdf; | 110 | struct pdflush_work *pdf; |
104 | 111 | ||
@@ -126,20 +133,25 @@ static int __pdflush(struct pdflush_work *my_work) | |||
126 | 133 | ||
127 | (*my_work->fn)(my_work->arg0); | 134 | (*my_work->fn)(my_work->arg0); |
128 | 135 | ||
136 | spin_lock_irq(&pdflush_lock); | ||
137 | |||
129 | /* | 138 | /* |
130 | * Thread creation: For how long have there been zero | 139 | * Thread creation: For how long have there been zero |
131 | * available threads? | 140 | * available threads? |
141 | * | ||
142 | * To throttle creation, we reset last_empty_jifs. | ||
132 | */ | 143 | */ |
133 | if (time_after(jiffies, last_empty_jifs + 1 * HZ)) { | 144 | if (time_after(jiffies, last_empty_jifs + 1 * HZ)) { |
134 | /* unlocked list_empty() test is OK here */ | 145 | if (list_empty(&pdflush_list) && |
135 | if (list_empty(&pdflush_list)) { | 146 | nr_pdflush_threads < nr_pdflush_threads_max) { |
136 | /* unlocked test is OK here */ | 147 | last_empty_jifs = jiffies; |
137 | if (nr_pdflush_threads < MAX_PDFLUSH_THREADS) | 148 | nr_pdflush_threads++; |
138 | start_one_pdflush_thread(); | 149 | spin_unlock_irq(&pdflush_lock); |
150 | start_one_pdflush_thread(); | ||
151 | spin_lock_irq(&pdflush_lock); | ||
139 | } | 152 | } |
140 | } | 153 | } |
141 | 154 | ||
142 | spin_lock_irq(&pdflush_lock); | ||
143 | my_work->fn = NULL; | 155 | my_work->fn = NULL; |
144 | 156 | ||
145 | /* | 157 | /* |
@@ -148,7 +160,7 @@ static int __pdflush(struct pdflush_work *my_work) | |||
148 | */ | 160 | */ |
149 | if (list_empty(&pdflush_list)) | 161 | if (list_empty(&pdflush_list)) |
150 | continue; | 162 | continue; |
151 | if (nr_pdflush_threads <= MIN_PDFLUSH_THREADS) | 163 | if (nr_pdflush_threads <= nr_pdflush_threads_min) |
152 | continue; | 164 | continue; |
153 | pdf = list_entry(pdflush_list.prev, struct pdflush_work, list); | 165 | pdf = list_entry(pdflush_list.prev, struct pdflush_work, list); |
154 | if (time_after(jiffies, pdf->when_i_went_to_sleep + 1 * HZ)) { | 166 | if (time_after(jiffies, pdf->when_i_went_to_sleep + 1 * HZ)) { |
@@ -236,14 +248,27 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0) | |||
236 | 248 | ||
237 | static void start_one_pdflush_thread(void) | 249 | static void start_one_pdflush_thread(void) |
238 | { | 250 | { |
239 | kthread_run(pdflush, NULL, "pdflush"); | 251 | struct task_struct *k; |
252 | |||
253 | k = kthread_run(pdflush, NULL, "pdflush"); | ||
254 | if (unlikely(IS_ERR(k))) { | ||
255 | spin_lock_irq(&pdflush_lock); | ||
256 | nr_pdflush_threads--; | ||
257 | spin_unlock_irq(&pdflush_lock); | ||
258 | } | ||
240 | } | 259 | } |
241 | 260 | ||
242 | static int __init pdflush_init(void) | 261 | static int __init pdflush_init(void) |
243 | { | 262 | { |
244 | int i; | 263 | int i; |
245 | 264 | ||
246 | for (i = 0; i < MIN_PDFLUSH_THREADS; i++) | 265 | /* |
266 | * Pre-set nr_pdflush_threads... If we fail to create, | ||
267 | * the count will be decremented. | ||
268 | */ | ||
269 | nr_pdflush_threads = nr_pdflush_threads_min; | ||
270 | |||
271 | for (i = 0; i < nr_pdflush_threads_min; i++) | ||
247 | start_one_pdflush_thread(); | 272 | start_one_pdflush_thread(); |
248 | return 0; | 273 | return 0; |
249 | } | 274 | } |
diff --git a/mm/shmem.c b/mm/shmem.c index d94d2e9146bc..f9cb20ebb990 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/vfs.h> | 25 | #include <linux/vfs.h> |
26 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
27 | #include <linux/pagemap.h> | ||
27 | #include <linux/file.h> | 28 | #include <linux/file.h> |
28 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -43,7 +44,6 @@ static struct vfsmount *shm_mnt; | |||
43 | #include <linux/exportfs.h> | 44 | #include <linux/exportfs.h> |
44 | #include <linux/generic_acl.h> | 45 | #include <linux/generic_acl.h> |
45 | #include <linux/mman.h> | 46 | #include <linux/mman.h> |
46 | #include <linux/pagemap.h> | ||
47 | #include <linux/string.h> | 47 | #include <linux/string.h> |
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | #include <linux/backing-dev.h> | 49 | #include <linux/backing-dev.h> |
@@ -65,13 +65,28 @@ static struct vfsmount *shm_mnt; | |||
65 | #include <asm/div64.h> | 65 | #include <asm/div64.h> |
66 | #include <asm/pgtable.h> | 66 | #include <asm/pgtable.h> |
67 | 67 | ||
68 | /* | ||
69 | * The maximum size of a shmem/tmpfs file is limited by the maximum size of | ||
70 | * its triple-indirect swap vector - see illustration at shmem_swp_entry(). | ||
71 | * | ||
72 | * With 4kB page size, maximum file size is just over 2TB on a 32-bit kernel, | ||
73 | * but one eighth of that on a 64-bit kernel. With 8kB page size, maximum | ||
74 | * file size is just over 4TB on a 64-bit kernel, but 16TB on a 32-bit kernel, | ||
75 | * MAX_LFS_FILESIZE being then more restrictive than swap vector layout. | ||
76 | * | ||
77 | * We use / and * instead of shifts in the definitions below, so that the swap | ||
78 | * vector can be tested with small even values (e.g. 20) for ENTRIES_PER_PAGE. | ||
79 | */ | ||
68 | #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) | 80 | #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) |
69 | #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) | 81 | #define ENTRIES_PER_PAGEPAGE ((unsigned long long)ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) |
70 | #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) | ||
71 | 82 | ||
72 | #define SHMEM_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1)) | 83 | #define SHMSWP_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1)) |
73 | #define SHMEM_MAX_BYTES ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT) | 84 | #define SHMSWP_MAX_BYTES (SHMSWP_MAX_INDEX << PAGE_CACHE_SHIFT) |
74 | 85 | ||
86 | #define SHMEM_MAX_BYTES min_t(unsigned long long, SHMSWP_MAX_BYTES, MAX_LFS_FILESIZE) | ||
87 | #define SHMEM_MAX_INDEX ((unsigned long)((SHMEM_MAX_BYTES+1) >> PAGE_CACHE_SHIFT)) | ||
88 | |||
89 | #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) | ||
75 | #define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) | 90 | #define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) |
76 | 91 | ||
77 | /* info->flags needs VM_flags to handle pagein/truncate races efficiently */ | 92 | /* info->flags needs VM_flags to handle pagein/truncate races efficiently */ |
@@ -2581,7 +2596,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page) | |||
2581 | #define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) | 2596 | #define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) |
2582 | #define shmem_acct_size(flags, size) 0 | 2597 | #define shmem_acct_size(flags, size) 0 |
2583 | #define shmem_unacct_size(flags, size) do {} while (0) | 2598 | #define shmem_unacct_size(flags, size) do {} while (0) |
2584 | #define SHMEM_MAX_BYTES LLONG_MAX | 2599 | #define SHMEM_MAX_BYTES MAX_LFS_FILESIZE |
2585 | 2600 | ||
2586 | #endif /* CONFIG_SHMEM */ | 2601 | #endif /* CONFIG_SHMEM */ |
2587 | 2602 | ||
@@ -223,6 +223,22 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
223 | } | 223 | } |
224 | #endif | 224 | #endif |
225 | 225 | ||
226 | /** | ||
227 | * get_user_pages_fast() - pin user pages in memory | ||
228 | * @start: starting user address | ||
229 | * @nr_pages: number of pages from start to pin | ||
230 | * @write: whether pages will be written to | ||
231 | * @pages: array that receives pointers to the pages pinned. | ||
232 | * Should be at least nr_pages long. | ||
233 | * | ||
234 | * Attempt to pin user pages in memory without taking mm->mmap_sem. | ||
235 | * If not successful, it will fall back to taking the lock and | ||
236 | * calling get_user_pages(). | ||
237 | * | ||
238 | * Returns number of pages pinned. This may be fewer than the number | ||
239 | * requested. If nr_pages is 0 or negative, returns 0. If no pages | ||
240 | * were pinned, returns -errno. | ||
241 | */ | ||
226 | int __attribute__((weak)) get_user_pages_fast(unsigned long start, | 242 | int __attribute__((weak)) get_user_pages_fast(unsigned long start, |
227 | int nr_pages, int write, struct page **pages) | 243 | int nr_pages, int write, struct page **pages) |
228 | { | 244 | { |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 39fdfb14eeaa..eac9577941f9 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -63,6 +63,9 @@ struct scan_control { | |||
63 | /* Can mapped pages be reclaimed? */ | 63 | /* Can mapped pages be reclaimed? */ |
64 | int may_unmap; | 64 | int may_unmap; |
65 | 65 | ||
66 | /* Can pages be swapped as part of reclaim? */ | ||
67 | int may_swap; | ||
68 | |||
66 | /* This context's SWAP_CLUSTER_MAX. If freeing memory for | 69 | /* This context's SWAP_CLUSTER_MAX. If freeing memory for |
67 | * suspend, we effectively ignore SWAP_CLUSTER_MAX. | 70 | * suspend, we effectively ignore SWAP_CLUSTER_MAX. |
68 | * In this context, it doesn't matter that we scan the | 71 | * In this context, it doesn't matter that we scan the |
@@ -1380,7 +1383,7 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1380 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | 1383 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); |
1381 | 1384 | ||
1382 | /* If we have no swap space, do not bother scanning anon pages. */ | 1385 | /* If we have no swap space, do not bother scanning anon pages. */ |
1383 | if (nr_swap_pages <= 0) { | 1386 | if (!sc->may_swap || (nr_swap_pages <= 0)) { |
1384 | percent[0] = 0; | 1387 | percent[0] = 0; |
1385 | percent[1] = 100; | 1388 | percent[1] = 100; |
1386 | return; | 1389 | return; |
@@ -1697,6 +1700,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, | |||
1697 | .may_writepage = !laptop_mode, | 1700 | .may_writepage = !laptop_mode, |
1698 | .swap_cluster_max = SWAP_CLUSTER_MAX, | 1701 | .swap_cluster_max = SWAP_CLUSTER_MAX, |
1699 | .may_unmap = 1, | 1702 | .may_unmap = 1, |
1703 | .may_swap = 1, | ||
1700 | .swappiness = vm_swappiness, | 1704 | .swappiness = vm_swappiness, |
1701 | .order = order, | 1705 | .order = order, |
1702 | .mem_cgroup = NULL, | 1706 | .mem_cgroup = NULL, |
@@ -1717,6 +1721,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | |||
1717 | struct scan_control sc = { | 1721 | struct scan_control sc = { |
1718 | .may_writepage = !laptop_mode, | 1722 | .may_writepage = !laptop_mode, |
1719 | .may_unmap = 1, | 1723 | .may_unmap = 1, |
1724 | .may_swap = !noswap, | ||
1720 | .swap_cluster_max = SWAP_CLUSTER_MAX, | 1725 | .swap_cluster_max = SWAP_CLUSTER_MAX, |
1721 | .swappiness = swappiness, | 1726 | .swappiness = swappiness, |
1722 | .order = 0, | 1727 | .order = 0, |
@@ -1726,9 +1731,6 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | |||
1726 | }; | 1731 | }; |
1727 | struct zonelist *zonelist; | 1732 | struct zonelist *zonelist; |
1728 | 1733 | ||
1729 | if (noswap) | ||
1730 | sc.may_unmap = 0; | ||
1731 | |||
1732 | sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | | 1734 | sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | |
1733 | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); | 1735 | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); |
1734 | zonelist = NODE_DATA(numa_node_id())->node_zonelists; | 1736 | zonelist = NODE_DATA(numa_node_id())->node_zonelists; |
@@ -1767,6 +1769,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) | |||
1767 | struct scan_control sc = { | 1769 | struct scan_control sc = { |
1768 | .gfp_mask = GFP_KERNEL, | 1770 | .gfp_mask = GFP_KERNEL, |
1769 | .may_unmap = 1, | 1771 | .may_unmap = 1, |
1772 | .may_swap = 1, | ||
1770 | .swap_cluster_max = SWAP_CLUSTER_MAX, | 1773 | .swap_cluster_max = SWAP_CLUSTER_MAX, |
1771 | .swappiness = vm_swappiness, | 1774 | .swappiness = vm_swappiness, |
1772 | .order = order, | 1775 | .order = order, |
@@ -2088,13 +2091,13 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, | |||
2088 | nr_reclaimed += shrink_list(l, nr_to_scan, zone, | 2091 | nr_reclaimed += shrink_list(l, nr_to_scan, zone, |
2089 | sc, prio); | 2092 | sc, prio); |
2090 | if (nr_reclaimed >= nr_pages) { | 2093 | if (nr_reclaimed >= nr_pages) { |
2091 | sc->nr_reclaimed = nr_reclaimed; | 2094 | sc->nr_reclaimed += nr_reclaimed; |
2092 | return; | 2095 | return; |
2093 | } | 2096 | } |
2094 | } | 2097 | } |
2095 | } | 2098 | } |
2096 | } | 2099 | } |
2097 | sc->nr_reclaimed = nr_reclaimed; | 2100 | sc->nr_reclaimed += nr_reclaimed; |
2098 | } | 2101 | } |
2099 | 2102 | ||
2100 | /* | 2103 | /* |
@@ -2115,6 +2118,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
2115 | .may_unmap = 0, | 2118 | .may_unmap = 0, |
2116 | .may_writepage = 1, | 2119 | .may_writepage = 1, |
2117 | .isolate_pages = isolate_pages_global, | 2120 | .isolate_pages = isolate_pages_global, |
2121 | .nr_reclaimed = 0, | ||
2118 | }; | 2122 | }; |
2119 | 2123 | ||
2120 | current->reclaim_state = &reclaim_state; | 2124 | current->reclaim_state = &reclaim_state; |
@@ -2297,6 +2301,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
2297 | struct scan_control sc = { | 2301 | struct scan_control sc = { |
2298 | .may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE), | 2302 | .may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE), |
2299 | .may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP), | 2303 | .may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP), |
2304 | .may_swap = 1, | ||
2300 | .swap_cluster_max = max_t(unsigned long, nr_pages, | 2305 | .swap_cluster_max = max_t(unsigned long, nr_pages, |
2301 | SWAP_CLUSTER_MAX), | 2306 | SWAP_CLUSTER_MAX), |
2302 | .gfp_mask = gfp_mask, | 2307 | .gfp_mask = gfp_mask, |