Blame view

mm/migrate.c 52.3 KB
b20a35035   Christoph Lameter   [PATCH] page migr...
1
  /*
14e0f9bcc   Hugh Dickins   mm: correct a cou...
2
   * Memory Migration functionality - linux/mm/migrate.c
b20a35035   Christoph Lameter   [PATCH] page migr...
3
4
5
6
7
8
9
10
11
   *
   * Copyright (C) 2006 Silicon Graphics, Inc., Christoph Lameter
   *
   * Page migration was first developed in the context of the memory hotplug
   * project. The main authors of the migration code are:
   *
   * IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
   * Hirokazu Takahashi <taka@valinux.co.jp>
   * Dave Hansen <haveblue@us.ibm.com>
cde535359   Christoph Lameter   Christoph has moved
12
   * Christoph Lameter
b20a35035   Christoph Lameter   [PATCH] page migr...
13
14
15
   */
  
  #include <linux/migrate.h>
b95f1b31b   Paul Gortmaker   mm: Map most file...
16
  #include <linux/export.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
17
  #include <linux/swap.h>
0697212a4   Christoph Lameter   [PATCH] Swapless ...
18
  #include <linux/swapops.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
19
  #include <linux/pagemap.h>
e23ca00bf   Christoph Lameter   [PATCH] Some page...
20
  #include <linux/buffer_head.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
21
  #include <linux/mm_inline.h>
b488893a3   Pavel Emelyanov   pid namespaces: c...
22
  #include <linux/nsproxy.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
23
  #include <linux/pagevec.h>
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
24
  #include <linux/ksm.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
25
26
27
28
  #include <linux/rmap.h>
  #include <linux/topology.h>
  #include <linux/cpu.h>
  #include <linux/cpuset.h>
04e62a29b   Christoph Lameter   [PATCH] More page...
29
  #include <linux/writeback.h>
742755a1d   Christoph Lameter   [PATCH] page migr...
30
31
  #include <linux/mempolicy.h>
  #include <linux/vmalloc.h>
86c3a7645   David Quigley   [PATCH] SELinux: ...
32
  #include <linux/security.h>
42cb14b11   Hugh Dickins   mm: migrate dirty...
33
  #include <linux/backing-dev.h>
bda807d44   Minchan Kim   mm: migrate: supp...
34
  #include <linux/compaction.h>
4f5ca2657   Adrian Bunk   mm/migrate.c shou...
35
  #include <linux/syscalls.h>
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
36
  #include <linux/hugetlb.h>
8e6ac7fab   Aneesh Kumar K.V   hugetlb/cgroup: m...
37
  #include <linux/hugetlb_cgroup.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
38
  #include <linux/gfp.h>
bf6bddf19   Rafael Aquini   mm: introduce com...
39
  #include <linux/balloon_compaction.h>
f714f4f20   Mel Gorman   mm: numa: call MM...
40
  #include <linux/mmu_notifier.h>
33c3fc71c   Vladimir Davydov   mm: introduce idl...
41
  #include <linux/page_idle.h>
d435edca9   Vlastimil Babka   mm, page_owner: c...
42
  #include <linux/page_owner.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
43

0d1836c36   Michal Nazarewicz   mm/migrate.c: fix...
44
  #include <asm/tlbflush.h>
7b2a2d4a1   Mel Gorman   mm: migrate: Add ...
45
46
  #define CREATE_TRACE_POINTS
  #include <trace/events/migrate.h>
b20a35035   Christoph Lameter   [PATCH] page migr...
47
  #include "internal.h"
b20a35035   Christoph Lameter   [PATCH] page migr...
48
  /*
742755a1d   Christoph Lameter   [PATCH] page migr...
49
   * migrate_prep() needs to be called before we start compiling a list of pages
748446bb6   Mel Gorman   mm: compaction: m...
50
51
   * to be migrated using isolate_lru_page(). If scheduling work on other CPUs is
   * undesirable, use migrate_prep_local()
b20a35035   Christoph Lameter   [PATCH] page migr...
52
53
54
   */
  int migrate_prep(void)
  {
b20a35035   Christoph Lameter   [PATCH] page migr...
55
56
57
58
59
60
61
62
63
64
  	/*
  	 * Clear the LRU lists so pages can be isolated.
  	 * Note that pages may be moved off the LRU after we have
  	 * drained them. Those pages will fail to migrate like other
  	 * pages that may be busy.
  	 */
  	lru_add_drain_all();
  
  	return 0;
  }
748446bb6   Mel Gorman   mm: compaction: m...
65
66
67
68
69
70
71
  /* Do the necessary work of migrate_prep but not if it involves other CPUs */
  int migrate_prep_local(void)
  {
  	lru_add_drain();
  
  	return 0;
  }
bda807d44   Minchan Kim   mm: migrate: supp...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  bool isolate_movable_page(struct page *page, isolate_mode_t mode)
  {
  	struct address_space *mapping;
  
  	/*
  	 * Avoid burning cycles with pages that are yet under __free_pages(),
  	 * or just got freed under us.
  	 *
  	 * In case we 'win' a race for a movable page being freed under us and
  	 * raise its refcount preventing __free_pages() from doing its job
  	 * the put_page() at the end of this block will take care of
  	 * release this page, thus avoiding a nasty leakage.
  	 */
  	if (unlikely(!get_page_unless_zero(page)))
  		goto out;
  
  	/*
  	 * Check PageMovable before holding a PG_lock because page's owner
  	 * assumes anybody doesn't touch PG_lock of newly allocated page
  	 * so unconditionally grapping the lock ruins page's owner side.
  	 */
  	if (unlikely(!__PageMovable(page)))
  		goto out_putpage;
  	/*
  	 * As movable pages are not isolated from LRU lists, concurrent
  	 * compaction threads can race against page migration functions
  	 * as well as race against the releasing a page.
  	 *
  	 * In order to avoid having an already isolated movable page
  	 * being (wrongly) re-isolated while it is under migration,
  	 * or to avoid attempting to isolate pages being released,
  	 * lets be sure we have the page lock
  	 * before proceeding with the movable page isolation steps.
  	 */
  	if (unlikely(!trylock_page(page)))
  		goto out_putpage;
  
  	if (!PageMovable(page) || PageIsolated(page))
  		goto out_no_isolated;
  
  	mapping = page_mapping(page);
  	VM_BUG_ON_PAGE(!mapping, page);
  
  	if (!mapping->a_ops->isolate_page(page, mode))
  		goto out_no_isolated;
  
  	/* Driver shouldn't use PG_isolated bit of page->flags */
  	WARN_ON_ONCE(PageIsolated(page));
  	__SetPageIsolated(page);
  	unlock_page(page);
  
  	return true;
  
  out_no_isolated:
  	unlock_page(page);
  out_putpage:
  	put_page(page);
  out:
  	return false;
  }
  
  /* It should be called on page which is PG_movable */
  void putback_movable_page(struct page *page)
  {
  	struct address_space *mapping;
  
  	VM_BUG_ON_PAGE(!PageLocked(page), page);
  	VM_BUG_ON_PAGE(!PageMovable(page), page);
  	VM_BUG_ON_PAGE(!PageIsolated(page), page);
  
  	mapping = page_mapping(page);
  	mapping->a_ops->putback_page(page);
  	__ClearPageIsolated(page);
  }
b20a35035   Christoph Lameter   [PATCH] page migr...
146
  /*
5733c7d11   Rafael Aquini   mm: introduce put...
147
148
149
   * Put previously isolated pages back onto the appropriate lists
   * from where they were once taken off for compaction/migration.
   *
59c82b70d   Joonsoo Kim   mm/migrate: remov...
150
151
152
   * This function shall be used whenever the isolated pageset has been
   * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range()
   * and isolate_huge_page().
5733c7d11   Rafael Aquini   mm: introduce put...
153
154
155
156
157
158
159
   */
  void putback_movable_pages(struct list_head *l)
  {
  	struct page *page;
  	struct page *page2;
  
  	list_for_each_entry_safe(page, page2, l, lru) {
31caf665e   Naoya Horiguchi   mm: migrate: make...
160
161
162
163
  		if (unlikely(PageHuge(page))) {
  			putback_active_hugepage(page);
  			continue;
  		}
5733c7d11   Rafael Aquini   mm: introduce put...
164
  		list_del(&page->lru);
bda807d44   Minchan Kim   mm: migrate: supp...
165
166
167
168
169
  		/*
  		 * We isolated non-lru movable page so here we can use
  		 * __PageMovable because LRU page's mapping cannot have
  		 * PAGE_MAPPING_MOVABLE.
  		 */
b1123ea6d   Minchan Kim   mm: balloon: use ...
170
  		if (unlikely(__PageMovable(page))) {
bda807d44   Minchan Kim   mm: migrate: supp...
171
172
173
174
175
176
177
178
179
  			VM_BUG_ON_PAGE(!PageIsolated(page), page);
  			lock_page(page);
  			if (PageMovable(page))
  				putback_movable_page(page);
  			else
  				__ClearPageIsolated(page);
  			unlock_page(page);
  			put_page(page);
  		} else {
bf6bddf19   Rafael Aquini   mm: introduce com...
180
  			putback_lru_page(page);
5d7d362ab   Ming Ling   mm, compaction: f...
181
182
  			dec_node_page_state(page, NR_ISOLATED_ANON +
  					page_is_file_cache(page));
bda807d44   Minchan Kim   mm: migrate: supp...
183
  		}
b20a35035   Christoph Lameter   [PATCH] page migr...
184
  	}
b20a35035   Christoph Lameter   [PATCH] page migr...
185
  }
0697212a4   Christoph Lameter   [PATCH] Swapless ...
186
187
188
  /*
   * Restore a potential migration pte to a working pte entry
   */
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
189
190
  static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
  				 unsigned long addr, void *old)
0697212a4   Christoph Lameter   [PATCH] Swapless ...
191
192
193
  {
  	struct mm_struct *mm = vma->vm_mm;
  	swp_entry_t entry;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
194
195
196
   	pmd_t *pmd;
  	pte_t *ptep, pte;
   	spinlock_t *ptl;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
197
198
199
200
  	if (unlikely(PageHuge(new))) {
  		ptep = huge_pte_offset(mm, addr);
  		if (!ptep)
  			goto out;
cb900f412   Kirill A. Shutemov   mm, hugetlb: conv...
201
  		ptl = huge_pte_lockptr(hstate_vma(vma), mm, ptep);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
202
  	} else {
6219049ae   Bob Liu   mm: introduce mm_...
203
204
  		pmd = mm_find_pmd(mm, addr);
  		if (!pmd)
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
205
  			goto out;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
206

290408d4a   Naoya Horiguchi   hugetlb: hugepage...
207
  		ptep = pte_offset_map(pmd, addr);
0697212a4   Christoph Lameter   [PATCH] Swapless ...
208

486cf46f3   Hugh Dickins   mm: fix race betw...
209
210
211
212
  		/*
  		 * Peek to check is_swap_pte() before taking ptlock?  No, we
  		 * can race mremap's move_ptes(), which skips anon_vma lock.
  		 */
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
213
214
215
  
  		ptl = pte_lockptr(mm, pmd);
  	}
0697212a4   Christoph Lameter   [PATCH] Swapless ...
216

0697212a4   Christoph Lameter   [PATCH] Swapless ...
217
218
219
   	spin_lock(ptl);
  	pte = *ptep;
  	if (!is_swap_pte(pte))
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
220
  		goto unlock;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
221
222
  
  	entry = pte_to_swp_entry(pte);
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
223
224
225
  	if (!is_migration_entry(entry) ||
  	    migration_entry_to_page(entry) != old)
  		goto unlock;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
226

0697212a4   Christoph Lameter   [PATCH] Swapless ...
227
  	get_page(new);
6d2329f88   Andrea Arcangeli   mm: vm_page_prot:...
228
  	pte = pte_mkold(mk_pte(new, READ_ONCE(vma->vm_page_prot)));
c3d16e165   Cyrill Gorcunov   mm: migration: do...
229
230
  	if (pte_swp_soft_dirty(*ptep))
  		pte = pte_mksoft_dirty(pte);
d3cb8bf60   Mel Gorman   mm: migrate: Clos...
231
232
  
  	/* Recheck VMA as permissions can change since migration started  */
0697212a4   Christoph Lameter   [PATCH] Swapless ...
233
  	if (is_write_migration_entry(entry))
d3cb8bf60   Mel Gorman   mm: migrate: Clos...
234
  		pte = maybe_mkwrite(pte, vma);
3ef8fd7f7   Andi Kleen   Fix migration.c c...
235
  #ifdef CONFIG_HUGETLB_PAGE
be7517d6a   Tony Lu   mm/hugetlb: set P...
236
  	if (PageHuge(new)) {
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
237
  		pte = pte_mkhuge(pte);
be7517d6a   Tony Lu   mm/hugetlb: set P...
238
239
  		pte = arch_make_huge_pte(pte, vma, new, 0);
  	}
3ef8fd7f7   Andi Kleen   Fix migration.c c...
240
  #endif
c2cc499c5   Leonid Yegoshin   mm compaction: fi...
241
  	flush_dcache_page(new);
0697212a4   Christoph Lameter   [PATCH] Swapless ...
242
  	set_pte_at(mm, addr, ptep, pte);
04e62a29b   Christoph Lameter   [PATCH] More page...
243

290408d4a   Naoya Horiguchi   hugetlb: hugepage...
244
245
246
247
  	if (PageHuge(new)) {
  		if (PageAnon(new))
  			hugepage_add_anon_rmap(new, vma, addr);
  		else
53f9263ba   Kirill A. Shutemov   mm: rework mapcou...
248
  			page_dup_rmap(new, true);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
249
  	} else if (PageAnon(new))
d281ee614   Kirill A. Shutemov   rmap: add argumen...
250
  		page_add_anon_rmap(new, vma, addr, false);
04e62a29b   Christoph Lameter   [PATCH] More page...
251
  	else
dd78fedde   Kirill A. Shutemov   rmap: support fil...
252
  		page_add_file_rmap(new, false);
04e62a29b   Christoph Lameter   [PATCH] More page...
253

e388466de   Kirill A. Shutemov   mm: make remove_m...
254
  	if (vma->vm_flags & VM_LOCKED && !PageTransCompound(new))
51afb12ba   Hugh Dickins   mm: page migratio...
255
  		mlock_vma_page(new);
04e62a29b   Christoph Lameter   [PATCH] More page...
256
  	/* No need to invalidate - it was non-present before */
4b3073e1c   Russell King   MM: Pass a PTE po...
257
  	update_mmu_cache(vma, addr, ptep);
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
258
  unlock:
0697212a4   Christoph Lameter   [PATCH] Swapless ...
259
  	pte_unmap_unlock(ptep, ptl);
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
260
261
  out:
  	return SWAP_AGAIN;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
262
263
264
  }
  
  /*
04e62a29b   Christoph Lameter   [PATCH] More page...
265
266
267
   * Get rid of all migration entries and replace them by
   * references to the indicated page.
   */
e388466de   Kirill A. Shutemov   mm: make remove_m...
268
  void remove_migration_ptes(struct page *old, struct page *new, bool locked)
04e62a29b   Christoph Lameter   [PATCH] More page...
269
  {
051ac83ad   Joonsoo Kim   mm/rmap: make rma...
270
271
272
273
  	struct rmap_walk_control rwc = {
  		.rmap_one = remove_migration_pte,
  		.arg = old,
  	};
e388466de   Kirill A. Shutemov   mm: make remove_m...
274
275
276
277
  	if (locked)
  		rmap_walk_locked(new, &rwc);
  	else
  		rmap_walk(new, &rwc);
04e62a29b   Christoph Lameter   [PATCH] More page...
278
279
280
  }
  
  /*
0697212a4   Christoph Lameter   [PATCH] Swapless ...
281
282
283
   * Something used the pte of a page under migration. We need to
   * get to the page and wait until migration is finished.
   * When we return from this function the fault will be retried.
0697212a4   Christoph Lameter   [PATCH] Swapless ...
284
   */
e66f17ff7   Naoya Horiguchi   mm/hugetlb: take ...
285
  void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
30dad3092   Naoya Horiguchi   mm: migration: ad...
286
  				spinlock_t *ptl)
0697212a4   Christoph Lameter   [PATCH] Swapless ...
287
  {
30dad3092   Naoya Horiguchi   mm: migration: ad...
288
  	pte_t pte;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
289
290
  	swp_entry_t entry;
  	struct page *page;
30dad3092   Naoya Horiguchi   mm: migration: ad...
291
  	spin_lock(ptl);
0697212a4   Christoph Lameter   [PATCH] Swapless ...
292
293
294
295
296
297
298
299
300
  	pte = *ptep;
  	if (!is_swap_pte(pte))
  		goto out;
  
  	entry = pte_to_swp_entry(pte);
  	if (!is_migration_entry(entry))
  		goto out;
  
  	page = migration_entry_to_page(entry);
e286781d5   Nick Piggin   mm: speculative p...
301
302
303
304
305
306
307
308
309
  	/*
  	 * Once radix-tree replacement of page migration started, page_count
  	 * *must* be zero. And, we don't want to call wait_on_page_locked()
  	 * against a page without get_page().
  	 * So, we use get_page_unless_zero(), here. Even failed, page fault
  	 * will occur again.
  	 */
  	if (!get_page_unless_zero(page))
  		goto out;
0697212a4   Christoph Lameter   [PATCH] Swapless ...
310
311
312
313
314
315
316
  	pte_unmap_unlock(ptep, ptl);
  	wait_on_page_locked(page);
  	put_page(page);
  	return;
  out:
  	pte_unmap_unlock(ptep, ptl);
  }
30dad3092   Naoya Horiguchi   mm: migration: ad...
317
318
319
320
321
322
323
  void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
  				unsigned long address)
  {
  	spinlock_t *ptl = pte_lockptr(mm, pmd);
  	pte_t *ptep = pte_offset_map(pmd, address);
  	__migration_entry_wait(mm, ptep, ptl);
  }
cb900f412   Kirill A. Shutemov   mm, hugetlb: conv...
324
325
  void migration_entry_wait_huge(struct vm_area_struct *vma,
  		struct mm_struct *mm, pte_t *pte)
30dad3092   Naoya Horiguchi   mm: migration: ad...
326
  {
cb900f412   Kirill A. Shutemov   mm, hugetlb: conv...
327
  	spinlock_t *ptl = huge_pte_lockptr(hstate_vma(vma), mm, pte);
30dad3092   Naoya Horiguchi   mm: migration: ad...
328
329
  	__migration_entry_wait(mm, pte, ptl);
  }
b969c4ab9   Mel Gorman   mm: compaction: d...
330
331
  #ifdef CONFIG_BLOCK
  /* Returns true if all buffers are successfully locked */
a6bc32b89   Mel Gorman   mm: compaction: i...
332
333
  static bool buffer_migrate_lock_buffers(struct buffer_head *head,
  							enum migrate_mode mode)
b969c4ab9   Mel Gorman   mm: compaction: d...
334
335
336
337
  {
  	struct buffer_head *bh = head;
  
  	/* Simple case, sync compaction */
a6bc32b89   Mel Gorman   mm: compaction: i...
338
  	if (mode != MIGRATE_ASYNC) {
b969c4ab9   Mel Gorman   mm: compaction: d...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  		do {
  			get_bh(bh);
  			lock_buffer(bh);
  			bh = bh->b_this_page;
  
  		} while (bh != head);
  
  		return true;
  	}
  
  	/* async case, we cannot block on lock_buffer so use trylock_buffer */
  	do {
  		get_bh(bh);
  		if (!trylock_buffer(bh)) {
  			/*
  			 * We failed to lock the buffer and cannot stall in
  			 * async migration. Release the taken locks
  			 */
  			struct buffer_head *failed_bh = bh;
  			put_bh(failed_bh);
  			bh = head;
  			while (bh != failed_bh) {
  				unlock_buffer(bh);
  				put_bh(bh);
  				bh = bh->b_this_page;
  			}
  			return false;
  		}
  
  		bh = bh->b_this_page;
  	} while (bh != head);
  	return true;
  }
  #else
  static inline bool buffer_migrate_lock_buffers(struct buffer_head *head,
a6bc32b89   Mel Gorman   mm: compaction: i...
374
  							enum migrate_mode mode)
b969c4ab9   Mel Gorman   mm: compaction: d...
375
376
377
378
  {
  	return true;
  }
  #endif /* CONFIG_BLOCK */
b20a35035   Christoph Lameter   [PATCH] page migr...
379
  /*
c3fcf8a5d   Christoph Lameter   [PATCH] page migr...
380
   * Replace the page in the mapping.
5b5c7120e   Christoph Lameter   [PATCH] page migr...
381
382
383
384
   *
   * The number of remaining references must be:
   * 1 for anonymous pages without a mapping
   * 2 for pages with a mapping
266cf658e   David Howells   FS-Cache: Recruit...
385
   * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
b20a35035   Christoph Lameter   [PATCH] page migr...
386
   */
36bc08cc0   Gu Zheng   fs/aio: Add suppo...
387
  int migrate_page_move_mapping(struct address_space *mapping,
b969c4ab9   Mel Gorman   mm: compaction: d...
388
  		struct page *newpage, struct page *page,
8e321fefb   Benjamin LaHaise   aio/migratepages:...
389
390
  		struct buffer_head *head, enum migrate_mode mode,
  		int extra_count)
b20a35035   Christoph Lameter   [PATCH] page migr...
391
  {
42cb14b11   Hugh Dickins   mm: migrate dirty...
392
393
  	struct zone *oldzone, *newzone;
  	int dirty;
8e321fefb   Benjamin LaHaise   aio/migratepages:...
394
  	int expected_count = 1 + extra_count;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
395
  	void **pslot;
b20a35035   Christoph Lameter   [PATCH] page migr...
396

6c5240ae7   Christoph Lameter   [PATCH] Swapless ...
397
  	if (!mapping) {
0e8c7d0fd   Christoph Lameter   page migration: f...
398
  		/* Anonymous page without mapping */
8e321fefb   Benjamin LaHaise   aio/migratepages:...
399
  		if (page_count(page) != expected_count)
6c5240ae7   Christoph Lameter   [PATCH] Swapless ...
400
  			return -EAGAIN;
cf4b769ab   Hugh Dickins   mm: page migratio...
401
402
  
  		/* No turning back from here */
cf4b769ab   Hugh Dickins   mm: page migratio...
403
404
405
  		newpage->index = page->index;
  		newpage->mapping = page->mapping;
  		if (PageSwapBacked(page))
fa9949da5   Hugh Dickins   mm: use __SetPage...
406
  			__SetPageSwapBacked(newpage);
cf4b769ab   Hugh Dickins   mm: page migratio...
407

78bd52097   Rafael Aquini   mm: adjust addres...
408
  		return MIGRATEPAGE_SUCCESS;
6c5240ae7   Christoph Lameter   [PATCH] Swapless ...
409
  	}
42cb14b11   Hugh Dickins   mm: migrate dirty...
410
411
  	oldzone = page_zone(page);
  	newzone = page_zone(newpage);
19fd62312   Nick Piggin   mm: spinlock tree...
412
  	spin_lock_irq(&mapping->tree_lock);
b20a35035   Christoph Lameter   [PATCH] page migr...
413

7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
414
415
  	pslot = radix_tree_lookup_slot(&mapping->page_tree,
   					page_index(page));
b20a35035   Christoph Lameter   [PATCH] page migr...
416

8e321fefb   Benjamin LaHaise   aio/migratepages:...
417
  	expected_count += 1 + page_has_private(page);
e286781d5   Nick Piggin   mm: speculative p...
418
  	if (page_count(page) != expected_count ||
29c1f677d   Mel Gorman   mm: migration: us...
419
  		radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) {
19fd62312   Nick Piggin   mm: spinlock tree...
420
  		spin_unlock_irq(&mapping->tree_lock);
e23ca00bf   Christoph Lameter   [PATCH] Some page...
421
  		return -EAGAIN;
b20a35035   Christoph Lameter   [PATCH] page migr...
422
  	}
fe896d187   Joonsoo Kim   mm: introduce pag...
423
  	if (!page_ref_freeze(page, expected_count)) {
19fd62312   Nick Piggin   mm: spinlock tree...
424
  		spin_unlock_irq(&mapping->tree_lock);
e286781d5   Nick Piggin   mm: speculative p...
425
426
  		return -EAGAIN;
  	}
b20a35035   Christoph Lameter   [PATCH] page migr...
427
  	/*
b969c4ab9   Mel Gorman   mm: compaction: d...
428
429
430
431
432
433
  	 * In the async migration case of moving a page with buffers, lock the
  	 * buffers using trylock before the mapping is moved. If the mapping
  	 * was moved, we later failed to lock the buffers and could not move
  	 * the mapping back due to an elevated page count, we would have to
  	 * block waiting on other references to be dropped.
  	 */
a6bc32b89   Mel Gorman   mm: compaction: i...
434
435
  	if (mode == MIGRATE_ASYNC && head &&
  			!buffer_migrate_lock_buffers(head, mode)) {
fe896d187   Joonsoo Kim   mm: introduce pag...
436
  		page_ref_unfreeze(page, expected_count);
b969c4ab9   Mel Gorman   mm: compaction: d...
437
438
439
440
441
  		spin_unlock_irq(&mapping->tree_lock);
  		return -EAGAIN;
  	}
  
  	/*
cf4b769ab   Hugh Dickins   mm: page migratio...
442
443
  	 * Now we know that no one else is looking at the page:
  	 * no turning back from here.
b20a35035   Christoph Lameter   [PATCH] page migr...
444
  	 */
cf4b769ab   Hugh Dickins   mm: page migratio...
445
446
447
  	newpage->index = page->index;
  	newpage->mapping = page->mapping;
  	if (PageSwapBacked(page))
fa9949da5   Hugh Dickins   mm: use __SetPage...
448
  		__SetPageSwapBacked(newpage);
cf4b769ab   Hugh Dickins   mm: page migratio...
449

7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
450
  	get_page(newpage);	/* add cache reference */
b20a35035   Christoph Lameter   [PATCH] page migr...
451
452
453
454
  	if (PageSwapCache(page)) {
  		SetPageSwapCache(newpage);
  		set_page_private(newpage, page_private(page));
  	}
42cb14b11   Hugh Dickins   mm: migrate dirty...
455
456
457
458
459
460
  	/* Move dirty while page refs frozen and newpage not yet exposed */
  	dirty = PageDirty(page);
  	if (dirty) {
  		ClearPageDirty(page);
  		SetPageDirty(newpage);
  	}
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
461
462
463
  	radix_tree_replace_slot(pslot, newpage);
  
  	/*
937a94c9d   Jacobo Giralt   mm: migrate: one ...
464
465
  	 * Drop cache reference from old page by unfreezing
  	 * to one less reference.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
466
467
  	 * We know this isn't the last reference.
  	 */
fe896d187   Joonsoo Kim   mm: introduce pag...
468
  	page_ref_unfreeze(page, expected_count - 1);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
469

42cb14b11   Hugh Dickins   mm: migrate dirty...
470
471
  	spin_unlock(&mapping->tree_lock);
  	/* Leave irq disabled to prevent preemption while updating stats */
0e8c7d0fd   Christoph Lameter   page migration: f...
472
473
474
475
476
477
478
  	/*
  	 * If moved to a different zone then also account
  	 * the page for that zone. Other VM counters will be
  	 * taken care of when we establish references to the
  	 * new page and drop references to the old page.
  	 *
  	 * Note that anonymous pages are accounted for
4b9d0fab7   Mel Gorman   mm: rename NR_ANO...
479
  	 * via NR_FILE_PAGES and NR_ANON_MAPPED if they
0e8c7d0fd   Christoph Lameter   page migration: f...
480
481
  	 * are mapped to swap space.
  	 */
42cb14b11   Hugh Dickins   mm: migrate dirty...
482
  	if (newzone != oldzone) {
11fb99898   Mel Gorman   mm: move most fil...
483
484
  		__dec_node_state(oldzone->zone_pgdat, NR_FILE_PAGES);
  		__inc_node_state(newzone->zone_pgdat, NR_FILE_PAGES);
42cb14b11   Hugh Dickins   mm: migrate dirty...
485
  		if (PageSwapBacked(page) && !PageSwapCache(page)) {
11fb99898   Mel Gorman   mm: move most fil...
486
487
  			__dec_node_state(oldzone->zone_pgdat, NR_SHMEM);
  			__inc_node_state(newzone->zone_pgdat, NR_SHMEM);
42cb14b11   Hugh Dickins   mm: migrate dirty...
488
489
  		}
  		if (dirty && mapping_cap_account_dirty(mapping)) {
11fb99898   Mel Gorman   mm: move most fil...
490
  			__dec_node_state(oldzone->zone_pgdat, NR_FILE_DIRTY);
5a1c84b40   Mel Gorman   mm: remove reclai...
491
  			__dec_zone_state(oldzone, NR_ZONE_WRITE_PENDING);
11fb99898   Mel Gorman   mm: move most fil...
492
  			__inc_node_state(newzone->zone_pgdat, NR_FILE_DIRTY);
5a1c84b40   Mel Gorman   mm: remove reclai...
493
  			__inc_zone_state(newzone, NR_ZONE_WRITE_PENDING);
42cb14b11   Hugh Dickins   mm: migrate dirty...
494
  		}
4b02108ac   KOSAKI Motohiro   mm: oom analysis:...
495
  	}
42cb14b11   Hugh Dickins   mm: migrate dirty...
496
  	local_irq_enable();
b20a35035   Christoph Lameter   [PATCH] page migr...
497

78bd52097   Rafael Aquini   mm: adjust addres...
498
  	return MIGRATEPAGE_SUCCESS;
b20a35035   Christoph Lameter   [PATCH] page migr...
499
  }
1118dce77   Richard Weinberger   mm: Export migrat...
500
  EXPORT_SYMBOL(migrate_page_move_mapping);
b20a35035   Christoph Lameter   [PATCH] page migr...
501
502
  
  /*
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
503
504
505
506
507
508
509
510
   * The expected number of remaining references is the same as that
   * of migrate_page_move_mapping().
   */
  int migrate_huge_page_move_mapping(struct address_space *mapping,
  				   struct page *newpage, struct page *page)
  {
  	int expected_count;
  	void **pslot;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
511
512
513
514
515
516
517
  	spin_lock_irq(&mapping->tree_lock);
  
  	pslot = radix_tree_lookup_slot(&mapping->page_tree,
  					page_index(page));
  
  	expected_count = 2 + page_has_private(page);
  	if (page_count(page) != expected_count ||
29c1f677d   Mel Gorman   mm: migration: us...
518
  		radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) {
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
519
520
521
  		spin_unlock_irq(&mapping->tree_lock);
  		return -EAGAIN;
  	}
fe896d187   Joonsoo Kim   mm: introduce pag...
522
  	if (!page_ref_freeze(page, expected_count)) {
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
523
524
525
  		spin_unlock_irq(&mapping->tree_lock);
  		return -EAGAIN;
  	}
cf4b769ab   Hugh Dickins   mm: page migratio...
526
527
  	newpage->index = page->index;
  	newpage->mapping = page->mapping;
6a93ca8fd   Johannes Weiner   mm: migrate: do n...
528

290408d4a   Naoya Horiguchi   hugetlb: hugepage...
529
530
531
  	get_page(newpage);
  
  	radix_tree_replace_slot(pslot, newpage);
fe896d187   Joonsoo Kim   mm: introduce pag...
532
  	page_ref_unfreeze(page, expected_count - 1);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
533
534
  
  	spin_unlock_irq(&mapping->tree_lock);
6a93ca8fd   Johannes Weiner   mm: migrate: do n...
535

78bd52097   Rafael Aquini   mm: adjust addres...
536
  	return MIGRATEPAGE_SUCCESS;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
537
538
539
  }
  
  /*
30b0a105d   Dave Hansen   mm: thp: give tra...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
   * Gigantic pages are so large that we do not guarantee that page++ pointer
   * arithmetic will work across the entire page.  We need something more
   * specialized.
   */
  static void __copy_gigantic_page(struct page *dst, struct page *src,
  				int nr_pages)
  {
  	int i;
  	struct page *dst_base = dst;
  	struct page *src_base = src;
  
  	for (i = 0; i < nr_pages; ) {
  		cond_resched();
  		copy_highpage(dst, src);
  
  		i++;
  		dst = mem_map_next(dst, dst_base, i);
  		src = mem_map_next(src, src_base, i);
  	}
  }
  
  static void copy_huge_page(struct page *dst, struct page *src)
  {
  	int i;
  	int nr_pages;
  
  	if (PageHuge(src)) {
  		/* hugetlbfs page */
  		struct hstate *h = page_hstate(src);
  		nr_pages = pages_per_huge_page(h);
  
  		if (unlikely(nr_pages > MAX_ORDER_NR_PAGES)) {
  			__copy_gigantic_page(dst, src, nr_pages);
  			return;
  		}
  	} else {
  		/* thp page */
  		BUG_ON(!PageTransHuge(src));
  		nr_pages = hpage_nr_pages(src);
  	}
  
  	for (i = 0; i < nr_pages; i++) {
  		cond_resched();
  		copy_highpage(dst + i, src + i);
  	}
  }
  
  /*
b20a35035   Christoph Lameter   [PATCH] page migr...
588
589
   * Copy the page to its new location
   */
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
590
  void migrate_page_copy(struct page *newpage, struct page *page)
b20a35035   Christoph Lameter   [PATCH] page migr...
591
  {
7851a45cd   Rik van Riel   mm: numa: Copy cp...
592
  	int cpupid;
b32967ff1   Mel Gorman   mm: numa: Add THP...
593
  	if (PageHuge(page) || PageTransHuge(page))
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
594
595
596
  		copy_huge_page(newpage, page);
  	else
  		copy_highpage(newpage, page);
b20a35035   Christoph Lameter   [PATCH] page migr...
597
598
599
600
601
602
603
  
  	if (PageError(page))
  		SetPageError(newpage);
  	if (PageReferenced(page))
  		SetPageReferenced(newpage);
  	if (PageUptodate(page))
  		SetPageUptodate(newpage);
894bc3104   Lee Schermerhorn   Unevictable LRU I...
604
  	if (TestClearPageActive(page)) {
309381fea   Sasha Levin   mm: dump page whe...
605
  		VM_BUG_ON_PAGE(PageUnevictable(page), page);
b20a35035   Christoph Lameter   [PATCH] page migr...
606
  		SetPageActive(newpage);
418b27ef5   Lee Schermerhorn   mm: remove unevic...
607
608
  	} else if (TestClearPageUnevictable(page))
  		SetPageUnevictable(newpage);
b20a35035   Christoph Lameter   [PATCH] page migr...
609
610
611
612
  	if (PageChecked(page))
  		SetPageChecked(newpage);
  	if (PageMappedToDisk(page))
  		SetPageMappedToDisk(newpage);
42cb14b11   Hugh Dickins   mm: migrate dirty...
613
614
615
  	/* Move dirty on pages not done by migrate_page_move_mapping() */
  	if (PageDirty(page))
  		SetPageDirty(newpage);
b20a35035   Christoph Lameter   [PATCH] page migr...
616

33c3fc71c   Vladimir Davydov   mm: introduce idl...
617
618
619
620
  	if (page_is_young(page))
  		set_page_young(newpage);
  	if (page_is_idle(page))
  		set_page_idle(newpage);
7851a45cd   Rik van Riel   mm: numa: Copy cp...
621
622
623
624
625
626
  	/*
  	 * Copy NUMA information to the new page, to prevent over-eager
  	 * future migrations of this same page.
  	 */
  	cpupid = page_cpupid_xchg_last(page, -1);
  	page_cpupid_xchg_last(newpage, cpupid);
e9995ef97   Hugh Dickins   ksm: rmap_walk to...
627
  	ksm_migrate_page(newpage, page);
c8d6553b9   Hugh Dickins   ksm: make KSM pag...
628
629
630
631
  	/*
  	 * Please do not reorder this without considering how mm/ksm.c's
  	 * get_ksm_page() depends upon ksm_migrate_page() and PageSwapCache().
  	 */
b3b3a99c5   Naoya Horiguchi   mm/migrate: check...
632
633
  	if (PageSwapCache(page))
  		ClearPageSwapCache(page);
b20a35035   Christoph Lameter   [PATCH] page migr...
634
635
  	ClearPagePrivate(page);
  	set_page_private(page, 0);
b20a35035   Christoph Lameter   [PATCH] page migr...
636
637
638
639
640
641
642
  
  	/*
  	 * If any waiters have accumulated on the new page then
  	 * wake them up.
  	 */
  	if (PageWriteback(newpage))
  		end_page_writeback(newpage);
d435edca9   Vlastimil Babka   mm, page_owner: c...
643
644
  
  	copy_page_owner(page, newpage);
74485cf2b   Johannes Weiner   mm: migrate: cons...
645
646
  
  	mem_cgroup_migrate(page, newpage);
b20a35035   Christoph Lameter   [PATCH] page migr...
647
  }
1118dce77   Richard Weinberger   mm: Export migrat...
648
  EXPORT_SYMBOL(migrate_page_copy);
b20a35035   Christoph Lameter   [PATCH] page migr...
649

1d8b85ccf   Christoph Lameter   [PATCH] page migr...
650
651
652
  /************************************************************
   *                    Migration functions
   ***********************************************************/
b20a35035   Christoph Lameter   [PATCH] page migr...
653
  /*
bda807d44   Minchan Kim   mm: migrate: supp...
654
   * Common logic to directly migrate a single LRU page suitable for
266cf658e   David Howells   FS-Cache: Recruit...
655
   * pages that do not use PagePrivate/PagePrivate2.
b20a35035   Christoph Lameter   [PATCH] page migr...
656
657
658
   *
   * Pages are locked upon entry and exit.
   */
2d1db3b11   Christoph Lameter   [PATCH] page migr...
659
  int migrate_page(struct address_space *mapping,
a6bc32b89   Mel Gorman   mm: compaction: i...
660
661
  		struct page *newpage, struct page *page,
  		enum migrate_mode mode)
b20a35035   Christoph Lameter   [PATCH] page migr...
662
663
664
665
  {
  	int rc;
  
  	BUG_ON(PageWriteback(page));	/* Writeback must be complete */
8e321fefb   Benjamin LaHaise   aio/migratepages:...
666
  	rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
b20a35035   Christoph Lameter   [PATCH] page migr...
667

78bd52097   Rafael Aquini   mm: adjust addres...
668
  	if (rc != MIGRATEPAGE_SUCCESS)
b20a35035   Christoph Lameter   [PATCH] page migr...
669
670
671
  		return rc;
  
  	migrate_page_copy(newpage, page);
78bd52097   Rafael Aquini   mm: adjust addres...
672
  	return MIGRATEPAGE_SUCCESS;
b20a35035   Christoph Lameter   [PATCH] page migr...
673
674
  }
  EXPORT_SYMBOL(migrate_page);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
675
  #ifdef CONFIG_BLOCK
b20a35035   Christoph Lameter   [PATCH] page migr...
676
  /*
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
677
678
679
680
   * Migration function for pages with buffers. This function can only be used
   * if the underlying filesystem guarantees that no other references to "page"
   * exist.
   */
2d1db3b11   Christoph Lameter   [PATCH] page migr...
681
  int buffer_migrate_page(struct address_space *mapping,
a6bc32b89   Mel Gorman   mm: compaction: i...
682
  		struct page *newpage, struct page *page, enum migrate_mode mode)
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
683
  {
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
684
685
  	struct buffer_head *bh, *head;
  	int rc;
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
686
  	if (!page_has_buffers(page))
a6bc32b89   Mel Gorman   mm: compaction: i...
687
  		return migrate_page(mapping, newpage, page, mode);
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
688
689
  
  	head = page_buffers(page);
8e321fefb   Benjamin LaHaise   aio/migratepages:...
690
  	rc = migrate_page_move_mapping(mapping, newpage, page, head, mode, 0);
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
691

78bd52097   Rafael Aquini   mm: adjust addres...
692
  	if (rc != MIGRATEPAGE_SUCCESS)
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
693
  		return rc;
b969c4ab9   Mel Gorman   mm: compaction: d...
694
695
696
697
698
  	/*
  	 * In the async case, migrate_page_move_mapping locked the buffers
  	 * with an IRQ-safe spinlock held. In the sync case, the buffers
  	 * need to be locked now
  	 */
a6bc32b89   Mel Gorman   mm: compaction: i...
699
700
  	if (mode != MIGRATE_ASYNC)
  		BUG_ON(!buffer_migrate_lock_buffers(head, mode));
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  
  	ClearPagePrivate(page);
  	set_page_private(newpage, page_private(page));
  	set_page_private(page, 0);
  	put_page(page);
  	get_page(newpage);
  
  	bh = head;
  	do {
  		set_bh_page(bh, newpage, bh_offset(bh));
  		bh = bh->b_this_page;
  
  	} while (bh != head);
  
  	SetPagePrivate(newpage);
  
  	migrate_page_copy(newpage, page);
  
  	bh = head;
  	do {
  		unlock_buffer(bh);
   		put_bh(bh);
  		bh = bh->b_this_page;
  
  	} while (bh != head);
78bd52097   Rafael Aquini   mm: adjust addres...
726
  	return MIGRATEPAGE_SUCCESS;
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
727
728
  }
  EXPORT_SYMBOL(buffer_migrate_page);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
729
  #endif
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
730

04e62a29b   Christoph Lameter   [PATCH] More page...
731
732
733
734
  /*
   * Writeback a page to clean the dirty state
   */
  static int writeout(struct address_space *mapping, struct page *page)
8351a6e47   Christoph Lameter   [PATCH] page migr...
735
  {
04e62a29b   Christoph Lameter   [PATCH] More page...
736
737
738
739
740
  	struct writeback_control wbc = {
  		.sync_mode = WB_SYNC_NONE,
  		.nr_to_write = 1,
  		.range_start = 0,
  		.range_end = LLONG_MAX,
04e62a29b   Christoph Lameter   [PATCH] More page...
741
742
743
744
745
746
747
748
749
750
751
  		.for_reclaim = 1
  	};
  	int rc;
  
  	if (!mapping->a_ops->writepage)
  		/* No write method for the address space */
  		return -EINVAL;
  
  	if (!clear_page_dirty_for_io(page))
  		/* Someone else already triggered a write */
  		return -EAGAIN;
8351a6e47   Christoph Lameter   [PATCH] page migr...
752
  	/*
04e62a29b   Christoph Lameter   [PATCH] More page...
753
754
755
756
757
758
  	 * A dirty page may imply that the underlying filesystem has
  	 * the page on some queue. So the page must be clean for
  	 * migration. Writeout may mean we loose the lock and the
  	 * page state is no longer what we checked for earlier.
  	 * At this point we know that the migration attempt cannot
  	 * be successful.
8351a6e47   Christoph Lameter   [PATCH] page migr...
759
  	 */
e388466de   Kirill A. Shutemov   mm: make remove_m...
760
  	remove_migration_ptes(page, page, false);
8351a6e47   Christoph Lameter   [PATCH] page migr...
761

04e62a29b   Christoph Lameter   [PATCH] More page...
762
  	rc = mapping->a_ops->writepage(page, &wbc);
8351a6e47   Christoph Lameter   [PATCH] page migr...
763

04e62a29b   Christoph Lameter   [PATCH] More page...
764
765
766
  	if (rc != AOP_WRITEPAGE_ACTIVATE)
  		/* unlocked. Relock */
  		lock_page(page);
bda8550de   Hugh Dickins   migration: fix wr...
767
  	return (rc < 0) ? -EIO : -EAGAIN;
04e62a29b   Christoph Lameter   [PATCH] More page...
768
769
770
771
772
773
  }
  
  /*
   * Default handling if a filesystem does not provide a migration function.
   */
  static int fallback_migrate_page(struct address_space *mapping,
a6bc32b89   Mel Gorman   mm: compaction: i...
774
  	struct page *newpage, struct page *page, enum migrate_mode mode)
04e62a29b   Christoph Lameter   [PATCH] More page...
775
  {
b969c4ab9   Mel Gorman   mm: compaction: d...
776
  	if (PageDirty(page)) {
a6bc32b89   Mel Gorman   mm: compaction: i...
777
778
  		/* Only writeback pages in full synchronous migration */
  		if (mode != MIGRATE_SYNC)
b969c4ab9   Mel Gorman   mm: compaction: d...
779
  			return -EBUSY;
04e62a29b   Christoph Lameter   [PATCH] More page...
780
  		return writeout(mapping, page);
b969c4ab9   Mel Gorman   mm: compaction: d...
781
  	}
8351a6e47   Christoph Lameter   [PATCH] page migr...
782
783
784
785
786
  
  	/*
  	 * Buffers may be managed in a filesystem specific way.
  	 * We must have no buffers or drop them.
  	 */
266cf658e   David Howells   FS-Cache: Recruit...
787
  	if (page_has_private(page) &&
8351a6e47   Christoph Lameter   [PATCH] page migr...
788
789
  	    !try_to_release_page(page, GFP_KERNEL))
  		return -EAGAIN;
a6bc32b89   Mel Gorman   mm: compaction: i...
790
  	return migrate_page(mapping, newpage, page, mode);
8351a6e47   Christoph Lameter   [PATCH] page migr...
791
  }
1d8b85ccf   Christoph Lameter   [PATCH] page migr...
792
  /*
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
793
794
795
796
797
   * Move a page to a newly allocated page
   * The page is locked and all ptes have been successfully removed.
   *
   * The new page will have replaced the old page if this function
   * is successful.
894bc3104   Lee Schermerhorn   Unevictable LRU I...
798
799
800
   *
   * Return value:
   *   < 0 - error code
78bd52097   Rafael Aquini   mm: adjust addres...
801
   *  MIGRATEPAGE_SUCCESS - success
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
802
   */
3fe2011ff   Mel Gorman   mm: migration: al...
803
  static int move_to_new_page(struct page *newpage, struct page *page,
5c3f9a673   Hugh Dickins   mm: page migratio...
804
  				enum migrate_mode mode)
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
805
806
  {
  	struct address_space *mapping;
bda807d44   Minchan Kim   mm: migrate: supp...
807
808
  	int rc = -EAGAIN;
  	bool is_lru = !__PageMovable(page);
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
809

7db7671f8   Hugh Dickins   mm: page migratio...
810
811
  	VM_BUG_ON_PAGE(!PageLocked(page), page);
  	VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
812

e24f0b8f7   Christoph Lameter   [PATCH] page migr...
813
  	mapping = page_mapping(page);
bda807d44   Minchan Kim   mm: migrate: supp...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
  
  	if (likely(is_lru)) {
  		if (!mapping)
  			rc = migrate_page(mapping, newpage, page, mode);
  		else if (mapping->a_ops->migratepage)
  			/*
  			 * Most pages have a mapping and most filesystems
  			 * provide a migratepage callback. Anonymous pages
  			 * are part of swap space which also has its own
  			 * migratepage callback. This is the most common path
  			 * for page migration.
  			 */
  			rc = mapping->a_ops->migratepage(mapping, newpage,
  							page, mode);
  		else
  			rc = fallback_migrate_page(mapping, newpage,
  							page, mode);
  	} else {
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
832
  		/*
bda807d44   Minchan Kim   mm: migrate: supp...
833
834
  		 * In case of non-lru page, it could be released after
  		 * isolation step. In that case, we shouldn't try migration.
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
835
  		 */
bda807d44   Minchan Kim   mm: migrate: supp...
836
837
838
839
840
841
842
843
844
845
846
847
  		VM_BUG_ON_PAGE(!PageIsolated(page), page);
  		if (!PageMovable(page)) {
  			rc = MIGRATEPAGE_SUCCESS;
  			__ClearPageIsolated(page);
  			goto out;
  		}
  
  		rc = mapping->a_ops->migratepage(mapping, newpage,
  						page, mode);
  		WARN_ON_ONCE(rc == MIGRATEPAGE_SUCCESS &&
  			!PageIsolated(page));
  	}
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
848

5c3f9a673   Hugh Dickins   mm: page migratio...
849
850
851
852
853
  	/*
  	 * When successful, old pagecache page->mapping must be cleared before
  	 * page is freed; but stats require that PageAnon be left as PageAnon.
  	 */
  	if (rc == MIGRATEPAGE_SUCCESS) {
bda807d44   Minchan Kim   mm: migrate: supp...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
  		if (__PageMovable(page)) {
  			VM_BUG_ON_PAGE(!PageIsolated(page), page);
  
  			/*
  			 * We clear PG_movable under page_lock so any compactor
  			 * cannot try to migrate this page.
  			 */
  			__ClearPageIsolated(page);
  		}
  
  		/*
  		 * Anonymous and movable page->mapping will be cleard by
  		 * free_pages_prepare so don't reset it here for keeping
  		 * the type to work PageAnon, for example.
  		 */
  		if (!PageMappingFlags(page))
5c3f9a673   Hugh Dickins   mm: page migratio...
870
  			page->mapping = NULL;
3fe2011ff   Mel Gorman   mm: migration: al...
871
  	}
bda807d44   Minchan Kim   mm: migrate: supp...
872
  out:
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
873
874
  	return rc;
  }
0dabec93d   Minchan Kim   mm: migration: cl...
875
  static int __unmap_and_move(struct page *page, struct page *newpage,
9c620e2bc   Hugh Dickins   mm: remove offlin...
876
  				int force, enum migrate_mode mode)
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
877
  {
0dabec93d   Minchan Kim   mm: migration: cl...
878
  	int rc = -EAGAIN;
2ebba6b7e   Hugh Dickins   mm: unmapped page...
879
  	int page_was_mapped = 0;
3f6c82728   Mel Gorman   mm: migration: ta...
880
  	struct anon_vma *anon_vma = NULL;
bda807d44   Minchan Kim   mm: migrate: supp...
881
  	bool is_lru = !__PageMovable(page);
95a402c38   Christoph Lameter   [PATCH] page migr...
882

529ae9aaa   Nick Piggin   mm: rename page t...
883
  	if (!trylock_page(page)) {
a6bc32b89   Mel Gorman   mm: compaction: i...
884
  		if (!force || mode == MIGRATE_ASYNC)
0dabec93d   Minchan Kim   mm: migration: cl...
885
  			goto out;
3e7d34497   Mel Gorman   mm: vmscan: recla...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
  
  		/*
  		 * It's not safe for direct compaction to call lock_page.
  		 * For example, during page readahead pages are added locked
  		 * to the LRU. Later, when the IO completes the pages are
  		 * marked uptodate and unlocked. However, the queueing
  		 * could be merging multiple pages for one bio (e.g.
  		 * mpage_readpages). If an allocation happens for the
  		 * second or third page, the process can end up locking
  		 * the same page twice and deadlocking. Rather than
  		 * trying to be clever about what pages can be locked,
  		 * avoid the use of lock_page for direct compaction
  		 * altogether.
  		 */
  		if (current->flags & PF_MEMALLOC)
0dabec93d   Minchan Kim   mm: migration: cl...
901
  			goto out;
3e7d34497   Mel Gorman   mm: vmscan: recla...
902

e24f0b8f7   Christoph Lameter   [PATCH] page migr...
903
904
905
906
  		lock_page(page);
  	}
  
  	if (PageWriteback(page)) {
11bc82d67   Andrea Arcangeli   mm: compaction: U...
907
  		/*
fed5b64a9   Jianguo Wu   mm/migrate: fix c...
908
  		 * Only in the case of a full synchronous migration is it
a6bc32b89   Mel Gorman   mm: compaction: i...
909
910
911
  		 * necessary to wait for PageWriteback. In the async case,
  		 * the retry loop is too short and in the sync-light case,
  		 * the overhead of stalling is too much
11bc82d67   Andrea Arcangeli   mm: compaction: U...
912
  		 */
a6bc32b89   Mel Gorman   mm: compaction: i...
913
  		if (mode != MIGRATE_SYNC) {
11bc82d67   Andrea Arcangeli   mm: compaction: U...
914
  			rc = -EBUSY;
0a31bc97c   Johannes Weiner   mm: memcontrol: r...
915
  			goto out_unlock;
11bc82d67   Andrea Arcangeli   mm: compaction: U...
916
917
  		}
  		if (!force)
0a31bc97c   Johannes Weiner   mm: memcontrol: r...
918
  			goto out_unlock;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
919
920
  		wait_on_page_writeback(page);
  	}
03f15c86c   Hugh Dickins   mm: simplify page...
921

e24f0b8f7   Christoph Lameter   [PATCH] page migr...
922
  	/*
dc386d4d1   KAMEZAWA Hiroyuki   memory unplug: mi...
923
924
  	 * By try_to_unmap(), page->mapcount goes down to 0 here. In this case,
  	 * we cannot notice that anon_vma is freed while we migrates a page.
1ce82b69e   Hugh Dickins   mm: fix migration...
925
  	 * This get_anon_vma() delays freeing anon_vma pointer until the end
dc386d4d1   KAMEZAWA Hiroyuki   memory unplug: mi...
926
  	 * of migration. File cache pages are no problem because of page_lock()
989f89c57   KAMEZAWA Hiroyuki   fix rcu_read_lock...
927
928
  	 * File Caches may use write_page() or lock_page() in migration, then,
  	 * just care Anon page here.
03f15c86c   Hugh Dickins   mm: simplify page...
929
930
931
932
933
934
  	 *
  	 * Only page_get_anon_vma() understands the subtleties of
  	 * getting a hold on an anon_vma from outside one of its mms.
  	 * But if we cannot get anon_vma, then we won't need it anyway,
  	 * because that implies that the anon page is no longer mapped
  	 * (and cannot be remapped so long as we hold the page lock).
dc386d4d1   KAMEZAWA Hiroyuki   memory unplug: mi...
935
  	 */
03f15c86c   Hugh Dickins   mm: simplify page...
936
  	if (PageAnon(page) && !PageKsm(page))
746b18d42   Peter Zijlstra   mm: use refcounts...
937
  		anon_vma = page_get_anon_vma(page);
62e1c5530   Shaohua Li   page migraton: ha...
938

7db7671f8   Hugh Dickins   mm: page migratio...
939
940
941
942
943
944
945
946
947
948
  	/*
  	 * Block others from accessing the new page when we get around to
  	 * establishing additional references. We are usually the only one
  	 * holding a reference to newpage at this point. We used to have a BUG
  	 * here if trylock_page(newpage) fails, but would like to allow for
  	 * cases where there might be a race with the previous use of newpage.
  	 * This is much like races on refcount of oldpage: just don't BUG().
  	 */
  	if (unlikely(!trylock_page(newpage)))
  		goto out_unlock;
bda807d44   Minchan Kim   mm: migrate: supp...
949
950
951
952
  	if (unlikely(!is_lru)) {
  		rc = move_to_new_page(newpage, page, mode);
  		goto out_unlock_both;
  	}
dc386d4d1   KAMEZAWA Hiroyuki   memory unplug: mi...
953
  	/*
62e1c5530   Shaohua Li   page migraton: ha...
954
955
956
957
958
959
960
961
962
963
  	 * Corner case handling:
  	 * 1. When a new swap-cache page is read into, it is added to the LRU
  	 * and treated as swapcache but it has no rmap yet.
  	 * Calling try_to_unmap() against a page->mapping==NULL page will
  	 * trigger a BUG.  So handle it here.
  	 * 2. An orphaned page (see truncate_complete_page) might have
  	 * fs-private metadata. The page can be picked up due to memory
  	 * offlining.  Everywhere else except page reclaim, the page is
  	 * invisible to the vm, so the page can not be migrated.  So try to
  	 * free the metadata, so the page can be freed.
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
964
  	 */
62e1c5530   Shaohua Li   page migraton: ha...
965
  	if (!page->mapping) {
309381fea   Sasha Levin   mm: dump page whe...
966
  		VM_BUG_ON_PAGE(PageAnon(page), page);
1ce82b69e   Hugh Dickins   mm: fix migration...
967
  		if (page_has_private(page)) {
62e1c5530   Shaohua Li   page migraton: ha...
968
  			try_to_free_buffers(page);
7db7671f8   Hugh Dickins   mm: page migratio...
969
  			goto out_unlock_both;
62e1c5530   Shaohua Li   page migraton: ha...
970
  		}
7db7671f8   Hugh Dickins   mm: page migratio...
971
972
  	} else if (page_mapped(page)) {
  		/* Establish migration ptes */
03f15c86c   Hugh Dickins   mm: simplify page...
973
974
  		VM_BUG_ON_PAGE(PageAnon(page) && !PageKsm(page) && !anon_vma,
  				page);
2ebba6b7e   Hugh Dickins   mm: unmapped page...
975
  		try_to_unmap(page,
da1b13ccf   Wanpeng Li   mm/hwpoison: fix ...
976
  			TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
2ebba6b7e   Hugh Dickins   mm: unmapped page...
977
978
  		page_was_mapped = 1;
  	}
dc386d4d1   KAMEZAWA Hiroyuki   memory unplug: mi...
979

e6a1530d6   Christoph Lameter   [PATCH] Allow mig...
980
  	if (!page_mapped(page))
5c3f9a673   Hugh Dickins   mm: page migratio...
981
  		rc = move_to_new_page(newpage, page, mode);
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
982

5c3f9a673   Hugh Dickins   mm: page migratio...
983
984
  	if (page_was_mapped)
  		remove_migration_ptes(page,
e388466de   Kirill A. Shutemov   mm: make remove_m...
985
  			rc == MIGRATEPAGE_SUCCESS ? newpage : page, false);
3f6c82728   Mel Gorman   mm: migration: ta...
986

7db7671f8   Hugh Dickins   mm: page migratio...
987
988
989
  out_unlock_both:
  	unlock_page(newpage);
  out_unlock:
3f6c82728   Mel Gorman   mm: migration: ta...
990
  	/* Drop an anon_vma reference if we took one */
76545066c   Rik van Riel   mm: extend KSM re...
991
  	if (anon_vma)
9e60109f1   Peter Zijlstra   mm: rename drop_a...
992
  		put_anon_vma(anon_vma);
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
993
  	unlock_page(page);
0dabec93d   Minchan Kim   mm: migration: cl...
994
  out:
c6c919eb9   Minchan Kim   mm: use put_page(...
995
996
997
998
999
1000
1001
  	/*
  	 * If migration is successful, decrease refcount of the newpage
  	 * which will not free the page because new page owner increased
  	 * refcounter. As well, if it is LRU page, add the page to LRU
  	 * list in here.
  	 */
  	if (rc == MIGRATEPAGE_SUCCESS) {
b1123ea6d   Minchan Kim   mm: balloon: use ...
1002
  		if (unlikely(__PageMovable(newpage)))
c6c919eb9   Minchan Kim   mm: use put_page(...
1003
1004
1005
1006
  			put_page(newpage);
  		else
  			putback_lru_page(newpage);
  	}
0dabec93d   Minchan Kim   mm: migration: cl...
1007
1008
  	return rc;
  }
95a402c38   Christoph Lameter   [PATCH] page migr...
1009

0dabec93d   Minchan Kim   mm: migration: cl...
1010
  /*
ef2a5153b   Geert Uytterhoeven   mm/migrate: mark ...
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
   * gcc 4.7 and 4.8 on arm get an ICEs when inlining unmap_and_move().  Work
   * around it.
   */
  #if (GCC_VERSION >= 40700 && GCC_VERSION < 40900) && defined(CONFIG_ARM)
  #define ICE_noinline noinline
  #else
  #define ICE_noinline
  #endif
  
  /*
0dabec93d   Minchan Kim   mm: migration: cl...
1021
1022
1023
   * Obtain the lock on page, remove all ptes and migrate the page
   * to the newly allocated page in newpage.
   */
ef2a5153b   Geert Uytterhoeven   mm/migrate: mark ...
1024
1025
1026
  static ICE_noinline int unmap_and_move(new_page_t get_new_page,
  				   free_page_t put_new_page,
  				   unsigned long private, struct page *page,
add05cece   Naoya Horiguchi   mm: soft-offline:...
1027
1028
  				   int force, enum migrate_mode mode,
  				   enum migrate_reason reason)
0dabec93d   Minchan Kim   mm: migration: cl...
1029
  {
2def7424c   Hugh Dickins   mm: page migratio...
1030
  	int rc = MIGRATEPAGE_SUCCESS;
0dabec93d   Minchan Kim   mm: migration: cl...
1031
  	int *result = NULL;
2def7424c   Hugh Dickins   mm: page migratio...
1032
  	struct page *newpage;
0dabec93d   Minchan Kim   mm: migration: cl...
1033

2def7424c   Hugh Dickins   mm: page migratio...
1034
  	newpage = get_new_page(page, private, &result);
0dabec93d   Minchan Kim   mm: migration: cl...
1035
1036
1037
1038
1039
  	if (!newpage)
  		return -ENOMEM;
  
  	if (page_count(page) == 1) {
  		/* page was freed from under us. So we are done. */
c6c919eb9   Minchan Kim   mm: use put_page(...
1040
1041
  		ClearPageActive(page);
  		ClearPageUnevictable(page);
bda807d44   Minchan Kim   mm: migrate: supp...
1042
1043
1044
1045
1046
1047
  		if (unlikely(__PageMovable(page))) {
  			lock_page(page);
  			if (!PageMovable(page))
  				__ClearPageIsolated(page);
  			unlock_page(page);
  		}
c6c919eb9   Minchan Kim   mm: use put_page(...
1048
1049
1050
1051
  		if (put_new_page)
  			put_new_page(newpage, private);
  		else
  			put_page(newpage);
0dabec93d   Minchan Kim   mm: migration: cl...
1052
1053
  		goto out;
  	}
4d2fa9654   Kirill A. Shutemov   thp, mm: split_hu...
1054
1055
1056
1057
1058
  	if (unlikely(PageTransHuge(page))) {
  		lock_page(page);
  		rc = split_huge_page(page);
  		unlock_page(page);
  		if (rc)
0dabec93d   Minchan Kim   mm: migration: cl...
1059
  			goto out;
4d2fa9654   Kirill A. Shutemov   thp, mm: split_hu...
1060
  	}
0dabec93d   Minchan Kim   mm: migration: cl...
1061

9c620e2bc   Hugh Dickins   mm: remove offlin...
1062
  	rc = __unmap_and_move(page, newpage, force, mode);
c6c919eb9   Minchan Kim   mm: use put_page(...
1063
  	if (rc == MIGRATEPAGE_SUCCESS)
7cd12b4ab   Vlastimil Babka   mm, page_owner: t...
1064
  		set_page_owner_migrate_reason(newpage, reason);
bf6bddf19   Rafael Aquini   mm: introduce com...
1065

0dabec93d   Minchan Kim   mm: migration: cl...
1066
  out:
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1067
  	if (rc != -EAGAIN) {
0dabec93d   Minchan Kim   mm: migration: cl...
1068
1069
1070
1071
1072
1073
1074
  		/*
  		 * A page that has been migrated has all references
  		 * removed and will be freed. A page that has not been
  		 * migrated will have kepts its references and be
  		 * restored.
  		 */
  		list_del(&page->lru);
5d7d362ab   Ming Ling   mm, compaction: f...
1075
1076
1077
1078
1079
1080
1081
1082
1083
  
  		/*
  		 * Compaction can migrate also non-LRU pages which are
  		 * not accounted to NR_ISOLATED_*. They can be recognized
  		 * as __PageMovable
  		 */
  		if (likely(!__PageMovable(page)))
  			dec_node_page_state(page, NR_ISOLATED_ANON +
  					page_is_file_cache(page));
c6c919eb9   Minchan Kim   mm: use put_page(...
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
  	}
  
  	/*
  	 * If migration is successful, releases reference grabbed during
  	 * isolation. Otherwise, restore the page to right list unless
  	 * we want to retry.
  	 */
  	if (rc == MIGRATEPAGE_SUCCESS) {
  		put_page(page);
  		if (reason == MR_MEMORY_FAILURE) {
d7e69488b   Minchan Kim   mm/hwpoison: fix ...
1094
  			/*
c6c919eb9   Minchan Kim   mm: use put_page(...
1095
1096
1097
  			 * Set PG_HWPoison on just freed page
  			 * intentionally. Although it's rather weird,
  			 * it's how HWPoison flag works at the moment.
d7e69488b   Minchan Kim   mm/hwpoison: fix ...
1098
  			 */
da1b13ccf   Wanpeng Li   mm/hwpoison: fix ...
1099
1100
  			if (!test_set_page_hwpoison(page))
  				num_poisoned_pages_inc();
c6c919eb9   Minchan Kim   mm: use put_page(...
1101
1102
  		}
  	} else {
bda807d44   Minchan Kim   mm: migrate: supp...
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
  		if (rc != -EAGAIN) {
  			if (likely(!__PageMovable(page))) {
  				putback_lru_page(page);
  				goto put_new;
  			}
  
  			lock_page(page);
  			if (PageMovable(page))
  				putback_movable_page(page);
  			else
  				__ClearPageIsolated(page);
  			unlock_page(page);
  			put_page(page);
  		}
  put_new:
c6c919eb9   Minchan Kim   mm: use put_page(...
1118
1119
1120
1121
  		if (put_new_page)
  			put_new_page(newpage, private);
  		else
  			put_page(newpage);
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1122
  	}
68711a746   David Rientjes   mm, migration: ad...
1123

742755a1d   Christoph Lameter   [PATCH] page migr...
1124
1125
1126
1127
1128
1129
  	if (result) {
  		if (rc)
  			*result = rc;
  		else
  			*result = page_to_nid(newpage);
  	}
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1130
1131
1132
1133
  	return rc;
  }
  
  /*
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
   * Counterpart of unmap_and_move_page() for hugepage migration.
   *
   * This function doesn't wait the completion of hugepage I/O
   * because there is no race between I/O and migration for hugepage.
   * Note that currently hugepage I/O occurs only in direct I/O
   * where no lock is held and PG_writeback is irrelevant,
   * and writeback status of all subpages are counted in the reference
   * count of the head page (i.e. if all subpages of a 2MB hugepage are
   * under direct I/O, the reference of the head page is 512 and a bit more.)
   * This means that when we try to migrate hugepage whose subpages are
   * doing direct I/O, some references remain after try_to_unmap() and
   * hugepage migration fails without data corruption.
   *
   * There is also no race when direct I/O is issued on the page under migration,
   * because then pte is replaced with migration swap entry and direct I/O code
   * will wait in the page fault for migration to complete.
   */
  static int unmap_and_move_huge_page(new_page_t get_new_page,
68711a746   David Rientjes   mm, migration: ad...
1152
1153
  				free_page_t put_new_page, unsigned long private,
  				struct page *hpage, int force,
7cd12b4ab   Vlastimil Babka   mm, page_owner: t...
1154
  				enum migrate_mode mode, int reason)
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1155
  {
2def7424c   Hugh Dickins   mm: page migratio...
1156
  	int rc = -EAGAIN;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1157
  	int *result = NULL;
2ebba6b7e   Hugh Dickins   mm: unmapped page...
1158
  	int page_was_mapped = 0;
32665f2bb   Joonsoo Kim   mm/migrate: corre...
1159
  	struct page *new_hpage;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1160
  	struct anon_vma *anon_vma = NULL;
83467efbd   Naoya Horiguchi   mm: migrate: chec...
1161
1162
1163
1164
1165
1166
1167
  	/*
  	 * Movability of hugepages depends on architectures and hugepage size.
  	 * This check is necessary because some callers of hugepage migration
  	 * like soft offline and memory hotremove don't walk through page
  	 * tables or check whether the hugepage is pmd-based or not before
  	 * kicking migration.
  	 */
100873d7a   Naoya Horiguchi   hugetlb: rename h...
1168
  	if (!hugepage_migration_supported(page_hstate(hpage))) {
32665f2bb   Joonsoo Kim   mm/migrate: corre...
1169
  		putback_active_hugepage(hpage);
83467efbd   Naoya Horiguchi   mm: migrate: chec...
1170
  		return -ENOSYS;
32665f2bb   Joonsoo Kim   mm/migrate: corre...
1171
  	}
83467efbd   Naoya Horiguchi   mm: migrate: chec...
1172

32665f2bb   Joonsoo Kim   mm/migrate: corre...
1173
  	new_hpage = get_new_page(hpage, private, &result);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1174
1175
  	if (!new_hpage)
  		return -ENOMEM;
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1176
  	if (!trylock_page(hpage)) {
a6bc32b89   Mel Gorman   mm: compaction: i...
1177
  		if (!force || mode != MIGRATE_SYNC)
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1178
1179
1180
  			goto out;
  		lock_page(hpage);
  	}
746b18d42   Peter Zijlstra   mm: use refcounts...
1181
1182
  	if (PageAnon(hpage))
  		anon_vma = page_get_anon_vma(hpage);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1183

7db7671f8   Hugh Dickins   mm: page migratio...
1184
1185
  	if (unlikely(!trylock_page(new_hpage)))
  		goto put_anon;
2ebba6b7e   Hugh Dickins   mm: unmapped page...
1186
1187
1188
1189
1190
  	if (page_mapped(hpage)) {
  		try_to_unmap(hpage,
  			TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
  		page_was_mapped = 1;
  	}
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1191
1192
  
  	if (!page_mapped(hpage))
5c3f9a673   Hugh Dickins   mm: page migratio...
1193
  		rc = move_to_new_page(new_hpage, hpage, mode);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1194

5c3f9a673   Hugh Dickins   mm: page migratio...
1195
1196
  	if (page_was_mapped)
  		remove_migration_ptes(hpage,
e388466de   Kirill A. Shutemov   mm: make remove_m...
1197
  			rc == MIGRATEPAGE_SUCCESS ? new_hpage : hpage, false);
290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1198

7db7671f8   Hugh Dickins   mm: page migratio...
1199
1200
1201
  	unlock_page(new_hpage);
  
  put_anon:
fd4a4663d   Hugh Dickins   mm: fix hugepage ...
1202
  	if (anon_vma)
9e60109f1   Peter Zijlstra   mm: rename drop_a...
1203
  		put_anon_vma(anon_vma);
8e6ac7fab   Aneesh Kumar K.V   hugetlb/cgroup: m...
1204

2def7424c   Hugh Dickins   mm: page migratio...
1205
  	if (rc == MIGRATEPAGE_SUCCESS) {
8e6ac7fab   Aneesh Kumar K.V   hugetlb/cgroup: m...
1206
  		hugetlb_cgroup_migrate(hpage, new_hpage);
2def7424c   Hugh Dickins   mm: page migratio...
1207
  		put_new_page = NULL;
7cd12b4ab   Vlastimil Babka   mm, page_owner: t...
1208
  		set_page_owner_migrate_reason(new_hpage, reason);
2def7424c   Hugh Dickins   mm: page migratio...
1209
  	}
8e6ac7fab   Aneesh Kumar K.V   hugetlb/cgroup: m...
1210

290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1211
  	unlock_page(hpage);
09761333e   Hillf Danton   mm/migrate.c: pai...
1212
  out:
b8ec1cee5   Naoya Horiguchi   mm: soft-offline:...
1213
1214
  	if (rc != -EAGAIN)
  		putback_active_hugepage(hpage);
68711a746   David Rientjes   mm, migration: ad...
1215
1216
1217
1218
1219
1220
  
  	/*
  	 * If migration was not successful and there's a freeing callback, use
  	 * it.  Otherwise, put_page() will drop the reference grabbed during
  	 * isolation.
  	 */
2def7424c   Hugh Dickins   mm: page migratio...
1221
  	if (put_new_page)
68711a746   David Rientjes   mm, migration: ad...
1222
1223
  		put_new_page(new_hpage, private);
  	else
3aaa76e12   Naoya Horiguchi   mm: migrate: huge...
1224
  		putback_active_hugepage(new_hpage);
68711a746   David Rientjes   mm, migration: ad...
1225

290408d4a   Naoya Horiguchi   hugetlb: hugepage...
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
  	if (result) {
  		if (rc)
  			*result = rc;
  		else
  			*result = page_to_nid(new_hpage);
  	}
  	return rc;
  }
  
  /*
c73e5c9c5   Srivatsa S. Bhat   mm: rewrite the c...
1236
1237
   * migrate_pages - migrate the pages specified in a list, to the free pages
   *		   supplied as the target for the page migration
b20a35035   Christoph Lameter   [PATCH] page migr...
1238
   *
c73e5c9c5   Srivatsa S. Bhat   mm: rewrite the c...
1239
1240
1241
   * @from:		The list of pages to be migrated.
   * @get_new_page:	The function used to allocate free pages to be used
   *			as the target of the page migration.
68711a746   David Rientjes   mm, migration: ad...
1242
1243
   * @put_new_page:	The function used to free target pages if migration
   *			fails, or NULL if no special handling is necessary.
c73e5c9c5   Srivatsa S. Bhat   mm: rewrite the c...
1244
1245
1246
1247
   * @private:		Private data to be passed on to get_new_page()
   * @mode:		The migration mode that specifies the constraints for
   *			page migration, if any.
   * @reason:		The reason for page migration.
b20a35035   Christoph Lameter   [PATCH] page migr...
1248
   *
c73e5c9c5   Srivatsa S. Bhat   mm: rewrite the c...
1249
1250
   * The function returns after 10 attempts or if no pages are movable any more
   * because the list has become empty or no retryable pages exist any more.
14e0f9bcc   Hugh Dickins   mm: correct a cou...
1251
   * The caller should call putback_movable_pages() to return pages to the LRU
28bd65781   Minchan Kim   mm: migration: cl...
1252
   * or free list only if ret != 0.
b20a35035   Christoph Lameter   [PATCH] page migr...
1253
   *
c73e5c9c5   Srivatsa S. Bhat   mm: rewrite the c...
1254
   * Returns the number of pages that were not migrated, or an error code.
b20a35035   Christoph Lameter   [PATCH] page migr...
1255
   */
9c620e2bc   Hugh Dickins   mm: remove offlin...
1256
  int migrate_pages(struct list_head *from, new_page_t get_new_page,
68711a746   David Rientjes   mm, migration: ad...
1257
1258
  		free_page_t put_new_page, unsigned long private,
  		enum migrate_mode mode, int reason)
b20a35035   Christoph Lameter   [PATCH] page migr...
1259
  {
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1260
  	int retry = 1;
b20a35035   Christoph Lameter   [PATCH] page migr...
1261
  	int nr_failed = 0;
5647bc293   Mel Gorman   mm: compaction: M...
1262
  	int nr_succeeded = 0;
b20a35035   Christoph Lameter   [PATCH] page migr...
1263
1264
1265
1266
1267
1268
1269
1270
  	int pass = 0;
  	struct page *page;
  	struct page *page2;
  	int swapwrite = current->flags & PF_SWAPWRITE;
  	int rc;
  
  	if (!swapwrite)
  		current->flags |= PF_SWAPWRITE;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1271
1272
  	for(pass = 0; pass < 10 && retry; pass++) {
  		retry = 0;
b20a35035   Christoph Lameter   [PATCH] page migr...
1273

e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1274
  		list_for_each_entry_safe(page, page2, from, lru) {
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1275
  			cond_resched();
2d1db3b11   Christoph Lameter   [PATCH] page migr...
1276

31caf665e   Naoya Horiguchi   mm: migrate: make...
1277
1278
  			if (PageHuge(page))
  				rc = unmap_and_move_huge_page(get_new_page,
68711a746   David Rientjes   mm, migration: ad...
1279
  						put_new_page, private, page,
7cd12b4ab   Vlastimil Babka   mm, page_owner: t...
1280
  						pass > 2, mode, reason);
31caf665e   Naoya Horiguchi   mm: migrate: make...
1281
  			else
68711a746   David Rientjes   mm, migration: ad...
1282
  				rc = unmap_and_move(get_new_page, put_new_page,
add05cece   Naoya Horiguchi   mm: soft-offline:...
1283
1284
  						private, page, pass > 2, mode,
  						reason);
2d1db3b11   Christoph Lameter   [PATCH] page migr...
1285

e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1286
  			switch(rc) {
95a402c38   Christoph Lameter   [PATCH] page migr...
1287
  			case -ENOMEM:
dfef2ef40   David Rientjes   mm, migrate: incr...
1288
  				nr_failed++;
95a402c38   Christoph Lameter   [PATCH] page migr...
1289
  				goto out;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1290
  			case -EAGAIN:
2d1db3b11   Christoph Lameter   [PATCH] page migr...
1291
  				retry++;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1292
  				break;
78bd52097   Rafael Aquini   mm: adjust addres...
1293
  			case MIGRATEPAGE_SUCCESS:
5647bc293   Mel Gorman   mm: compaction: M...
1294
  				nr_succeeded++;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1295
1296
  				break;
  			default:
354a33633   Naoya Horiguchi   mm/migrate: add c...
1297
1298
1299
1300
1301
1302
  				/*
  				 * Permanent failure (-EBUSY, -ENOSYS, etc.):
  				 * unlike -EAGAIN case, the failed page is
  				 * removed from migration page list and not
  				 * retried in the next outer loop.
  				 */
2d1db3b11   Christoph Lameter   [PATCH] page migr...
1303
  				nr_failed++;
e24f0b8f7   Christoph Lameter   [PATCH] page migr...
1304
  				break;
2d1db3b11   Christoph Lameter   [PATCH] page migr...
1305
  			}
b20a35035   Christoph Lameter   [PATCH] page migr...
1306
1307
  		}
  	}
f2f81fb2b   Vlastimil Babka   mm, migrate: coun...
1308
1309
  	nr_failed += retry;
  	rc = nr_failed;
95a402c38   Christoph Lameter   [PATCH] page migr...
1310
  out:
5647bc293   Mel Gorman   mm: compaction: M...
1311
1312
1313
1314
  	if (nr_succeeded)
  		count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded);
  	if (nr_failed)
  		count_vm_events(PGMIGRATE_FAIL, nr_failed);
7b2a2d4a1   Mel Gorman   mm: migrate: Add ...
1315
  	trace_mm_migrate_pages(nr_succeeded, nr_failed, mode, reason);
b20a35035   Christoph Lameter   [PATCH] page migr...
1316
1317
  	if (!swapwrite)
  		current->flags &= ~PF_SWAPWRITE;
78bd52097   Rafael Aquini   mm: adjust addres...
1318
  	return rc;
b20a35035   Christoph Lameter   [PATCH] page migr...
1319
  }
95a402c38   Christoph Lameter   [PATCH] page migr...
1320

742755a1d   Christoph Lameter   [PATCH] page migr...
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  #ifdef CONFIG_NUMA
  /*
   * Move a list of individual pages
   */
  struct page_to_node {
  	unsigned long addr;
  	struct page *page;
  	int node;
  	int status;
  };
  
  static struct page *new_page_node(struct page *p, unsigned long private,
  		int **result)
  {
  	struct page_to_node *pm = (struct page_to_node *)private;
  
  	while (pm->node != MAX_NUMNODES && pm->page != p)
  		pm++;
  
  	if (pm->node == MAX_NUMNODES)
  		return NULL;
  
  	*result = &pm->status;
e632a938d   Naoya Horiguchi   mm: migrate: add ...
1344
1345
1346
1347
  	if (PageHuge(p))
  		return alloc_huge_page_node(page_hstate(compound_head(p)),
  					pm->node);
  	else
96db800f5   Vlastimil Babka   mm: rename alloc_...
1348
  		return __alloc_pages_node(pm->node,
e97ca8e5b   Johannes Weiner   mm: fix GFP_THISN...
1349
  				GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0);
742755a1d   Christoph Lameter   [PATCH] page migr...
1350
1351
1352
1353
1354
1355
  }
  
  /*
   * Move a set of pages as indicated in the pm array. The addr
   * field must be set to the virtual address of the page to be moved
   * and the node number must contain a valid target node.
5e9a0f023   Brice Goglin   mm: extract do_pa...
1356
   * The pm array ends with node = MAX_NUMNODES.
742755a1d   Christoph Lameter   [PATCH] page migr...
1357
   */
5e9a0f023   Brice Goglin   mm: extract do_pa...
1358
1359
1360
  static int do_move_page_to_node_array(struct mm_struct *mm,
  				      struct page_to_node *pm,
  				      int migrate_all)
742755a1d   Christoph Lameter   [PATCH] page migr...
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
  {
  	int err;
  	struct page_to_node *pp;
  	LIST_HEAD(pagelist);
  
  	down_read(&mm->mmap_sem);
  
  	/*
  	 * Build a list of pages to migrate
  	 */
742755a1d   Christoph Lameter   [PATCH] page migr...
1371
1372
1373
  	for (pp = pm; pp->node != MAX_NUMNODES; pp++) {
  		struct vm_area_struct *vma;
  		struct page *page;
742755a1d   Christoph Lameter   [PATCH] page migr...
1374
1375
  		err = -EFAULT;
  		vma = find_vma(mm, pp->addr);
70384dc6d   Gleb Natapov   mm: fix error rep...
1376
  		if (!vma || pp->addr < vma->vm_start || !vma_migratable(vma))
742755a1d   Christoph Lameter   [PATCH] page migr...
1377
  			goto set_status;
d899844e9   Kirill A. Shutemov   mm: fix status co...
1378
1379
1380
  		/* FOLL_DUMP to ignore special (like zero) pages */
  		page = follow_page(vma, pp->addr,
  				FOLL_GET | FOLL_SPLIT | FOLL_DUMP);
89f5b7da2   Linus Torvalds   Reinstate ZERO_PA...
1381
1382
1383
1384
  
  		err = PTR_ERR(page);
  		if (IS_ERR(page))
  			goto set_status;
742755a1d   Christoph Lameter   [PATCH] page migr...
1385
1386
1387
  		err = -ENOENT;
  		if (!page)
  			goto set_status;
742755a1d   Christoph Lameter   [PATCH] page migr...
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  		pp->page = page;
  		err = page_to_nid(page);
  
  		if (err == pp->node)
  			/*
  			 * Node already in the right place
  			 */
  			goto put_and_set;
  
  		err = -EACCES;
  		if (page_mapcount(page) > 1 &&
  				!migrate_all)
  			goto put_and_set;
e632a938d   Naoya Horiguchi   mm: migrate: add ...
1401
  		if (PageHuge(page)) {
e66f17ff7   Naoya Horiguchi   mm/hugetlb: take ...
1402
1403
  			if (PageHead(page))
  				isolate_huge_page(page, &pagelist);
e632a938d   Naoya Horiguchi   mm: migrate: add ...
1404
1405
  			goto put_and_set;
  		}
62695a84e   Nick Piggin   vmscan: move isol...
1406
  		err = isolate_lru_page(page);
6d9c285a6   KOSAKI Motohiro   mm: move inc_zone...
1407
  		if (!err) {
62695a84e   Nick Piggin   vmscan: move isol...
1408
  			list_add_tail(&page->lru, &pagelist);
599d0c954   Mel Gorman   mm, vmscan: move ...
1409
  			inc_node_page_state(page, NR_ISOLATED_ANON +
6d9c285a6   KOSAKI Motohiro   mm: move inc_zone...
1410
1411
  					    page_is_file_cache(page));
  		}
742755a1d   Christoph Lameter   [PATCH] page migr...
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
  put_and_set:
  		/*
  		 * Either remove the duplicate refcount from
  		 * isolate_lru_page() or drop the page ref if it was
  		 * not isolated.
  		 */
  		put_page(page);
  set_status:
  		pp->status = err;
  	}
e78bbfa82   Brice Goglin   mm: stop returnin...
1422
  	err = 0;
cf608ac19   Minchan Kim   mm: compaction: f...
1423
  	if (!list_empty(&pagelist)) {
68711a746   David Rientjes   mm, migration: ad...
1424
  		err = migrate_pages(&pagelist, new_page_node, NULL,
9c620e2bc   Hugh Dickins   mm: remove offlin...
1425
  				(unsigned long)pm, MIGRATE_SYNC, MR_SYSCALL);
cf608ac19   Minchan Kim   mm: compaction: f...
1426
  		if (err)
e632a938d   Naoya Horiguchi   mm: migrate: add ...
1427
  			putback_movable_pages(&pagelist);
cf608ac19   Minchan Kim   mm: compaction: f...
1428
  	}
742755a1d   Christoph Lameter   [PATCH] page migr...
1429
1430
1431
1432
1433
1434
  
  	up_read(&mm->mmap_sem);
  	return err;
  }
  
  /*
5e9a0f023   Brice Goglin   mm: extract do_pa...
1435
1436
1437
   * Migrate an array of page address onto an array of nodes and fill
   * the corresponding array of status.
   */
3268c63ed   Christoph Lameter   mm: fix move/migr...
1438
  static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
5e9a0f023   Brice Goglin   mm: extract do_pa...
1439
1440
1441
1442
1443
  			 unsigned long nr_pages,
  			 const void __user * __user *pages,
  			 const int __user *nodes,
  			 int __user *status, int flags)
  {
3140a2273   Brice Goglin   mm: rework do_pag...
1444
  	struct page_to_node *pm;
3140a2273   Brice Goglin   mm: rework do_pag...
1445
1446
1447
  	unsigned long chunk_nr_pages;
  	unsigned long chunk_start;
  	int err;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1448

3140a2273   Brice Goglin   mm: rework do_pag...
1449
1450
1451
  	err = -ENOMEM;
  	pm = (struct page_to_node *)__get_free_page(GFP_KERNEL);
  	if (!pm)
5e9a0f023   Brice Goglin   mm: extract do_pa...
1452
  		goto out;
35282a2de   Brice Goglin   migration: only m...
1453
1454
  
  	migrate_prep();
5e9a0f023   Brice Goglin   mm: extract do_pa...
1455
  	/*
3140a2273   Brice Goglin   mm: rework do_pag...
1456
1457
  	 * Store a chunk of page_to_node array in a page,
  	 * but keep the last one as a marker
5e9a0f023   Brice Goglin   mm: extract do_pa...
1458
  	 */
3140a2273   Brice Goglin   mm: rework do_pag...
1459
  	chunk_nr_pages = (PAGE_SIZE / sizeof(struct page_to_node)) - 1;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1460

3140a2273   Brice Goglin   mm: rework do_pag...
1461
1462
1463
1464
  	for (chunk_start = 0;
  	     chunk_start < nr_pages;
  	     chunk_start += chunk_nr_pages) {
  		int j;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1465

3140a2273   Brice Goglin   mm: rework do_pag...
1466
1467
1468
1469
1470
1471
  		if (chunk_start + chunk_nr_pages > nr_pages)
  			chunk_nr_pages = nr_pages - chunk_start;
  
  		/* fill the chunk pm with addrs and nodes from user-space */
  		for (j = 0; j < chunk_nr_pages; j++) {
  			const void __user *p;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1472
  			int node;
3140a2273   Brice Goglin   mm: rework do_pag...
1473
1474
1475
1476
1477
1478
  			err = -EFAULT;
  			if (get_user(p, pages + j + chunk_start))
  				goto out_pm;
  			pm[j].addr = (unsigned long) p;
  
  			if (get_user(node, nodes + j + chunk_start))
5e9a0f023   Brice Goglin   mm: extract do_pa...
1479
1480
1481
  				goto out_pm;
  
  			err = -ENODEV;
6f5a55f1a   Linus Torvalds   Fix potential cra...
1482
1483
  			if (node < 0 || node >= MAX_NUMNODES)
  				goto out_pm;
389162c22   Lai Jiangshan   mm,migrate: use N...
1484
  			if (!node_state(node, N_MEMORY))
5e9a0f023   Brice Goglin   mm: extract do_pa...
1485
1486
1487
1488
1489
  				goto out_pm;
  
  			err = -EACCES;
  			if (!node_isset(node, task_nodes))
  				goto out_pm;
3140a2273   Brice Goglin   mm: rework do_pag...
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
  			pm[j].node = node;
  		}
  
  		/* End marker for this chunk */
  		pm[chunk_nr_pages].node = MAX_NUMNODES;
  
  		/* Migrate this chunk */
  		err = do_move_page_to_node_array(mm, pm,
  						 flags & MPOL_MF_MOVE_ALL);
  		if (err < 0)
  			goto out_pm;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1501

5e9a0f023   Brice Goglin   mm: extract do_pa...
1502
  		/* Return status information */
3140a2273   Brice Goglin   mm: rework do_pag...
1503
1504
  		for (j = 0; j < chunk_nr_pages; j++)
  			if (put_user(pm[j].status, status + j + chunk_start)) {
5e9a0f023   Brice Goglin   mm: extract do_pa...
1505
  				err = -EFAULT;
3140a2273   Brice Goglin   mm: rework do_pag...
1506
1507
1508
1509
  				goto out_pm;
  			}
  	}
  	err = 0;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1510
1511
  
  out_pm:
3140a2273   Brice Goglin   mm: rework do_pag...
1512
  	free_page((unsigned long)pm);
5e9a0f023   Brice Goglin   mm: extract do_pa...
1513
1514
1515
1516
1517
  out:
  	return err;
  }
  
  /*
2f007e74b   Brice Goglin   mm: don't vmalloc...
1518
   * Determine the nodes of an array of pages and store it in an array of status.
742755a1d   Christoph Lameter   [PATCH] page migr...
1519
   */
80bba1290   Brice Goglin   mm: no get_user/p...
1520
1521
  static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages,
  				const void __user **pages, int *status)
742755a1d   Christoph Lameter   [PATCH] page migr...
1522
  {
2f007e74b   Brice Goglin   mm: don't vmalloc...
1523
  	unsigned long i;
2f007e74b   Brice Goglin   mm: don't vmalloc...
1524

742755a1d   Christoph Lameter   [PATCH] page migr...
1525
  	down_read(&mm->mmap_sem);
2f007e74b   Brice Goglin   mm: don't vmalloc...
1526
  	for (i = 0; i < nr_pages; i++) {
80bba1290   Brice Goglin   mm: no get_user/p...
1527
  		unsigned long addr = (unsigned long)(*pages);
742755a1d   Christoph Lameter   [PATCH] page migr...
1528
1529
  		struct vm_area_struct *vma;
  		struct page *page;
c095adbc2   KOSAKI Motohiro   mm: Don't touch u...
1530
  		int err = -EFAULT;
2f007e74b   Brice Goglin   mm: don't vmalloc...
1531
1532
  
  		vma = find_vma(mm, addr);
70384dc6d   Gleb Natapov   mm: fix error rep...
1533
  		if (!vma || addr < vma->vm_start)
742755a1d   Christoph Lameter   [PATCH] page migr...
1534
  			goto set_status;
d899844e9   Kirill A. Shutemov   mm: fix status co...
1535
1536
  		/* FOLL_DUMP to ignore special (like zero) pages */
  		page = follow_page(vma, addr, FOLL_DUMP);
89f5b7da2   Linus Torvalds   Reinstate ZERO_PA...
1537
1538
1539
1540
  
  		err = PTR_ERR(page);
  		if (IS_ERR(page))
  			goto set_status;
d899844e9   Kirill A. Shutemov   mm: fix status co...
1541
  		err = page ? page_to_nid(page) : -ENOENT;
742755a1d   Christoph Lameter   [PATCH] page migr...
1542
  set_status:
80bba1290   Brice Goglin   mm: no get_user/p...
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  		*status = err;
  
  		pages++;
  		status++;
  	}
  
  	up_read(&mm->mmap_sem);
  }
  
  /*
   * Determine the nodes of a user array of pages and store it in
   * a user array of status.
   */
  static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
  			 const void __user * __user *pages,
  			 int __user *status)
  {
  #define DO_PAGES_STAT_CHUNK_NR 16
  	const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR];
  	int chunk_status[DO_PAGES_STAT_CHUNK_NR];
80bba1290   Brice Goglin   mm: no get_user/p...
1563

87b8d1ade   H. Peter Anvin   mm: Make copy_fro...
1564
1565
  	while (nr_pages) {
  		unsigned long chunk_nr;
80bba1290   Brice Goglin   mm: no get_user/p...
1566

87b8d1ade   H. Peter Anvin   mm: Make copy_fro...
1567
1568
1569
1570
1571
1572
  		chunk_nr = nr_pages;
  		if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
  			chunk_nr = DO_PAGES_STAT_CHUNK_NR;
  
  		if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages)))
  			break;
80bba1290   Brice Goglin   mm: no get_user/p...
1573
1574
  
  		do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
87b8d1ade   H. Peter Anvin   mm: Make copy_fro...
1575
1576
  		if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status)))
  			break;
742755a1d   Christoph Lameter   [PATCH] page migr...
1577

87b8d1ade   H. Peter Anvin   mm: Make copy_fro...
1578
1579
1580
1581
1582
  		pages += chunk_nr;
  		status += chunk_nr;
  		nr_pages -= chunk_nr;
  	}
  	return nr_pages ? -EFAULT : 0;
742755a1d   Christoph Lameter   [PATCH] page migr...
1583
1584
1585
1586
1587
1588
  }
  
  /*
   * Move a list of pages in the address space of the currently executing
   * process.
   */
938bb9f5e   Heiko Carstens   [CVE-2009-0029] S...
1589
1590
1591
1592
  SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
  		const void __user * __user *, pages,
  		const int __user *, nodes,
  		int __user *, status, int, flags)
742755a1d   Christoph Lameter   [PATCH] page migr...
1593
  {
c69e8d9c0   David Howells   CRED: Use RCU to ...
1594
  	const struct cred *cred = current_cred(), *tcred;
742755a1d   Christoph Lameter   [PATCH] page migr...
1595
  	struct task_struct *task;
742755a1d   Christoph Lameter   [PATCH] page migr...
1596
  	struct mm_struct *mm;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1597
  	int err;
3268c63ed   Christoph Lameter   mm: fix move/migr...
1598
  	nodemask_t task_nodes;
742755a1d   Christoph Lameter   [PATCH] page migr...
1599
1600
1601
1602
1603
1604
1605
1606
1607
  
  	/* Check flags */
  	if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
  		return -EINVAL;
  
  	if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_NICE))
  		return -EPERM;
  
  	/* Find the mm_struct */
a879bf582   Greg Thelen   mm: grab rcu read...
1608
  	rcu_read_lock();
228ebcbe6   Pavel Emelyanov   Uninline find_tas...
1609
  	task = pid ? find_task_by_vpid(pid) : current;
742755a1d   Christoph Lameter   [PATCH] page migr...
1610
  	if (!task) {
a879bf582   Greg Thelen   mm: grab rcu read...
1611
  		rcu_read_unlock();
742755a1d   Christoph Lameter   [PATCH] page migr...
1612
1613
  		return -ESRCH;
  	}
3268c63ed   Christoph Lameter   mm: fix move/migr...
1614
  	get_task_struct(task);
742755a1d   Christoph Lameter   [PATCH] page migr...
1615
1616
1617
1618
1619
1620
1621
  
  	/*
  	 * Check if this process has the right to modify the specified
  	 * process. The right exists if the process has administrative
  	 * capabilities, superuser privileges or the same
  	 * userid as the target process.
  	 */
c69e8d9c0   David Howells   CRED: Use RCU to ...
1622
  	tcred = __task_cred(task);
b38a86eb1   Eric W. Biederman   userns: Convert t...
1623
1624
  	if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) &&
  	    !uid_eq(cred->uid,  tcred->suid) && !uid_eq(cred->uid,  tcred->uid) &&
742755a1d   Christoph Lameter   [PATCH] page migr...
1625
  	    !capable(CAP_SYS_NICE)) {
c69e8d9c0   David Howells   CRED: Use RCU to ...
1626
  		rcu_read_unlock();
742755a1d   Christoph Lameter   [PATCH] page migr...
1627
  		err = -EPERM;
5e9a0f023   Brice Goglin   mm: extract do_pa...
1628
  		goto out;
742755a1d   Christoph Lameter   [PATCH] page migr...
1629
  	}
c69e8d9c0   David Howells   CRED: Use RCU to ...
1630
  	rcu_read_unlock();
742755a1d   Christoph Lameter   [PATCH] page migr...
1631

86c3a7645   David Quigley   [PATCH] SELinux: ...
1632
1633
   	err = security_task_movememory(task);
   	if (err)
5e9a0f023   Brice Goglin   mm: extract do_pa...
1634
  		goto out;
86c3a7645   David Quigley   [PATCH] SELinux: ...
1635

3268c63ed   Christoph Lameter   mm: fix move/migr...
1636
1637
1638
  	task_nodes = cpuset_mems_allowed(task);
  	mm = get_task_mm(task);
  	put_task_struct(task);
6e8b09eaf   Sasha Levin   mm: fix NULL ptr ...
1639
1640
1641
1642
1643
1644
1645
1646
  	if (!mm)
  		return -EINVAL;
  
  	if (nodes)
  		err = do_pages_move(mm, task_nodes, nr_pages, pages,
  				    nodes, status, flags);
  	else
  		err = do_pages_stat(mm, nr_pages, pages, status);
742755a1d   Christoph Lameter   [PATCH] page migr...
1647

742755a1d   Christoph Lameter   [PATCH] page migr...
1648
1649
  	mmput(mm);
  	return err;
3268c63ed   Christoph Lameter   mm: fix move/migr...
1650
1651
1652
1653
  
  out:
  	put_task_struct(task);
  	return err;
742755a1d   Christoph Lameter   [PATCH] page migr...
1654
  }
742755a1d   Christoph Lameter   [PATCH] page migr...
1655

7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1656
1657
1658
1659
1660
1661
  #ifdef CONFIG_NUMA_BALANCING
  /*
   * Returns true if this is a safe migration target node for misplaced NUMA
   * pages. Currently it only checks the watermarks which crude
   */
  static bool migrate_balanced_pgdat(struct pglist_data *pgdat,
3abef4e6c   Mel Gorman   mm: numa: take TH...
1662
  				   unsigned long nr_migrate_pages)
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1663
1664
  {
  	int z;
599d0c954   Mel Gorman   mm, vmscan: move ...
1665
1666
1667
  
  	if (!pgdat_reclaimable(pgdat))
  		return false;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1668
1669
1670
1671
1672
  	for (z = pgdat->nr_zones - 1; z >= 0; z--) {
  		struct zone *zone = pgdat->node_zones + z;
  
  		if (!populated_zone(zone))
  			continue;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
  		/* Avoid waking kswapd by allocating pages_to_migrate pages. */
  		if (!zone_watermark_ok(zone, 0,
  				       high_wmark_pages(zone) +
  				       nr_migrate_pages,
  				       0, 0))
  			continue;
  		return true;
  	}
  	return false;
  }
  
  static struct page *alloc_misplaced_dst_page(struct page *page,
  					   unsigned long data,
  					   int **result)
  {
  	int nid = (int) data;
  	struct page *newpage;
96db800f5   Vlastimil Babka   mm: rename alloc_...
1690
  	newpage = __alloc_pages_node(nid,
e97ca8e5b   Johannes Weiner   mm: fix GFP_THISN...
1691
1692
1693
  					 (GFP_HIGHUSER_MOVABLE |
  					  __GFP_THISNODE | __GFP_NOMEMALLOC |
  					  __GFP_NORETRY | __GFP_NOWARN) &
8479eba77   Mel Gorman   mm: numa: quickly...
1694
  					 ~__GFP_RECLAIM, 0);
bac0382c6   Hillf Danton   mm: numa: migrate...
1695

7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1696
1697
1698
1699
  	return newpage;
  }
  
  /*
a8f607721   Mel Gorman   mm: numa: Rate li...
1700
1701
1702
1703
1704
1705
   * page migration rate limiting control.
   * Do not migrate more than @pages_to_migrate in a @migrate_interval_millisecs
   * window of time. Default here says do not migrate more than 1280M per second.
   */
  static unsigned int migrate_interval_millisecs __read_mostly = 100;
  static unsigned int ratelimit_pages __read_mostly = 128 << (20 - PAGE_SHIFT);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1706
  /* Returns true if the node is migrate rate-limited after the update */
1c30e0177   Mel Gorman   mm: numa: make NU...
1707
1708
  static bool numamigrate_update_ratelimit(pg_data_t *pgdat,
  					unsigned long nr_pages)
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1709
  {
a8f607721   Mel Gorman   mm: numa: Rate li...
1710
1711
1712
1713
1714
  	/*
  	 * Rate-limit the amount of data that is being migrated to a node.
  	 * Optimal placement is no good if the memory bus is saturated and
  	 * all the time is being spent migrating!
  	 */
a8f607721   Mel Gorman   mm: numa: Rate li...
1715
  	if (time_after(jiffies, pgdat->numabalancing_migrate_next_window)) {
1c5e9c27c   Mel Gorman   mm: numa: limit s...
1716
  		spin_lock(&pgdat->numabalancing_migrate_lock);
a8f607721   Mel Gorman   mm: numa: Rate li...
1717
1718
1719
  		pgdat->numabalancing_migrate_nr_pages = 0;
  		pgdat->numabalancing_migrate_next_window = jiffies +
  			msecs_to_jiffies(migrate_interval_millisecs);
1c5e9c27c   Mel Gorman   mm: numa: limit s...
1720
  		spin_unlock(&pgdat->numabalancing_migrate_lock);
a8f607721   Mel Gorman   mm: numa: Rate li...
1721
  	}
af1839d72   Mel Gorman   mm: numa: trace t...
1722
1723
1724
  	if (pgdat->numabalancing_migrate_nr_pages > ratelimit_pages) {
  		trace_mm_numa_migrate_ratelimit(current, pgdat->node_id,
  								nr_pages);
1c5e9c27c   Mel Gorman   mm: numa: limit s...
1725
  		return true;
af1839d72   Mel Gorman   mm: numa: trace t...
1726
  	}
1c5e9c27c   Mel Gorman   mm: numa: limit s...
1727
1728
1729
1730
1731
1732
1733
1734
1735
  
  	/*
  	 * This is an unlocked non-atomic update so errors are possible.
  	 * The consequences are failing to migrate when we potentiall should
  	 * have which is not severe enough to warrant locking. If it is ever
  	 * a problem, it can be converted to a per-cpu counter.
  	 */
  	pgdat->numabalancing_migrate_nr_pages += nr_pages;
  	return false;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1736
  }
1c30e0177   Mel Gorman   mm: numa: make NU...
1737
  static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
b32967ff1   Mel Gorman   mm: numa: Add THP...
1738
  {
340ef3902   Hugh Dickins   mm: numa: cleanup...
1739
  	int page_lru;
a8f607721   Mel Gorman   mm: numa: Rate li...
1740

309381fea   Sasha Levin   mm: dump page whe...
1741
  	VM_BUG_ON_PAGE(compound_order(page) && !PageTransHuge(page), page);
3abef4e6c   Mel Gorman   mm: numa: take TH...
1742

7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1743
  	/* Avoid migrating to a node that is nearly full */
340ef3902   Hugh Dickins   mm: numa: cleanup...
1744
1745
  	if (!migrate_balanced_pgdat(pgdat, 1UL << compound_order(page)))
  		return 0;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1746

340ef3902   Hugh Dickins   mm: numa: cleanup...
1747
1748
  	if (isolate_lru_page(page))
  		return 0;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1749

340ef3902   Hugh Dickins   mm: numa: cleanup...
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
  	/*
  	 * migrate_misplaced_transhuge_page() skips page migration's usual
  	 * check on page_count(), so we must do it here, now that the page
  	 * has been isolated: a GUP pin, or any other pin, prevents migration.
  	 * The expected page count is 3: 1 for page's mapcount and 1 for the
  	 * caller's pin and 1 for the reference taken by isolate_lru_page().
  	 */
  	if (PageTransHuge(page) && page_count(page) != 3) {
  		putback_lru_page(page);
  		return 0;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1760
  	}
340ef3902   Hugh Dickins   mm: numa: cleanup...
1761
  	page_lru = page_is_file_cache(page);
599d0c954   Mel Gorman   mm, vmscan: move ...
1762
  	mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + page_lru,
340ef3902   Hugh Dickins   mm: numa: cleanup...
1763
  				hpage_nr_pages(page));
149c33e1c   Mel Gorman   mm: migrate: Drop...
1764
  	/*
340ef3902   Hugh Dickins   mm: numa: cleanup...
1765
1766
1767
  	 * Isolating the page has taken another reference, so the
  	 * caller's reference can be safely dropped without the page
  	 * disappearing underneath us during migration.
149c33e1c   Mel Gorman   mm: migrate: Drop...
1768
1769
  	 */
  	put_page(page);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1770
  	return 1;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1771
  }
de466bd62   Mel Gorman   mm: numa: avoid u...
1772
1773
1774
1775
1776
  bool pmd_trans_migrating(pmd_t pmd)
  {
  	struct page *page = pmd_page(pmd);
  	return PageLocked(page);
  }
b32967ff1   Mel Gorman   mm: numa: Add THP...
1777
1778
1779
1780
1781
  /*
   * Attempt to migrate a misplaced page to the specified destination
   * node. Caller is expected to have an elevated reference count on
   * the page that will be dropped by this function before returning.
   */
1bc115d87   Mel Gorman   mm: numa: Scan pa...
1782
1783
  int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
  			   int node)
b32967ff1   Mel Gorman   mm: numa: Add THP...
1784
1785
  {
  	pg_data_t *pgdat = NODE_DATA(node);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1786
  	int isolated;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1787
1788
1789
1790
  	int nr_remaining;
  	LIST_HEAD(migratepages);
  
  	/*
1bc115d87   Mel Gorman   mm: numa: Scan pa...
1791
1792
  	 * Don't migrate file pages that are mapped in multiple processes
  	 * with execute permissions as they are probably shared libraries.
b32967ff1   Mel Gorman   mm: numa: Add THP...
1793
  	 */
1bc115d87   Mel Gorman   mm: numa: Scan pa...
1794
1795
  	if (page_mapcount(page) != 1 && page_is_file_cache(page) &&
  	    (vma->vm_flags & VM_EXEC))
b32967ff1   Mel Gorman   mm: numa: Add THP...
1796
  		goto out;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1797
1798
1799
1800
1801
1802
  
  	/*
  	 * Rate-limit the amount of data that is being migrated to a node.
  	 * Optimal placement is no good if the memory bus is saturated and
  	 * all the time is being spent migrating!
  	 */
340ef3902   Hugh Dickins   mm: numa: cleanup...
1803
  	if (numamigrate_update_ratelimit(pgdat, 1))
b32967ff1   Mel Gorman   mm: numa: Add THP...
1804
  		goto out;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1805
1806
1807
1808
1809
1810
  
  	isolated = numamigrate_isolate_page(pgdat, page);
  	if (!isolated)
  		goto out;
  
  	list_add(&page->lru, &migratepages);
9c620e2bc   Hugh Dickins   mm: remove offlin...
1811
  	nr_remaining = migrate_pages(&migratepages, alloc_misplaced_dst_page,
68711a746   David Rientjes   mm, migration: ad...
1812
1813
  				     NULL, node, MIGRATE_ASYNC,
  				     MR_NUMA_MISPLACED);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1814
  	if (nr_remaining) {
59c82b70d   Joonsoo Kim   mm/migrate: remov...
1815
1816
  		if (!list_empty(&migratepages)) {
  			list_del(&page->lru);
599d0c954   Mel Gorman   mm, vmscan: move ...
1817
  			dec_node_page_state(page, NR_ISOLATED_ANON +
59c82b70d   Joonsoo Kim   mm/migrate: remov...
1818
1819
1820
  					page_is_file_cache(page));
  			putback_lru_page(page);
  		}
b32967ff1   Mel Gorman   mm: numa: Add THP...
1821
1822
1823
  		isolated = 0;
  	} else
  		count_vm_numa_event(NUMA_PAGE_MIGRATE);
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1824
  	BUG_ON(!list_empty(&migratepages));
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1825
  	return isolated;
340ef3902   Hugh Dickins   mm: numa: cleanup...
1826
1827
1828
1829
  
  out:
  	put_page(page);
  	return 0;
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1830
  }
220018d38   Mel Gorman   mm: numa: Add THP...
1831
  #endif /* CONFIG_NUMA_BALANCING */
b32967ff1   Mel Gorman   mm: numa: Add THP...
1832

220018d38   Mel Gorman   mm: numa: Add THP...
1833
  #if defined(CONFIG_NUMA_BALANCING) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
340ef3902   Hugh Dickins   mm: numa: cleanup...
1834
1835
1836
1837
  /*
   * Migrates a THP to a given target node. page must be locked and is unlocked
   * before returning.
   */
b32967ff1   Mel Gorman   mm: numa: Add THP...
1838
1839
1840
1841
1842
1843
  int migrate_misplaced_transhuge_page(struct mm_struct *mm,
  				struct vm_area_struct *vma,
  				pmd_t *pmd, pmd_t entry,
  				unsigned long address,
  				struct page *page, int node)
  {
c4088ebdc   Kirill A. Shutemov   mm: convert the r...
1844
  	spinlock_t *ptl;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1845
1846
1847
  	pg_data_t *pgdat = NODE_DATA(node);
  	int isolated = 0;
  	struct page *new_page = NULL;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1848
  	int page_lru = page_is_file_cache(page);
f714f4f20   Mel Gorman   mm: numa: call MM...
1849
1850
  	unsigned long mmun_start = address & HPAGE_PMD_MASK;
  	unsigned long mmun_end = mmun_start + HPAGE_PMD_SIZE;
2b4847e73   Mel Gorman   mm: numa: seriali...
1851
  	pmd_t orig_entry;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1852
1853
  
  	/*
b32967ff1   Mel Gorman   mm: numa: Add THP...
1854
1855
1856
1857
  	 * Rate-limit the amount of data that is being migrated to a node.
  	 * Optimal placement is no good if the memory bus is saturated and
  	 * all the time is being spent migrating!
  	 */
d28d43351   Mel Gorman   mm: migrate: Acco...
1858
  	if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR))
b32967ff1   Mel Gorman   mm: numa: Add THP...
1859
1860
1861
  		goto out_dropref;
  
  	new_page = alloc_pages_node(node,
251603549   Vlastimil Babka   mm, thp: remove _...
1862
  		(GFP_TRANSHUGE_LIGHT | __GFP_THISNODE),
e97ca8e5b   Johannes Weiner   mm: fix GFP_THISN...
1863
  		HPAGE_PMD_ORDER);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1864
1865
  	if (!new_page)
  		goto out_fail;
9a982250f   Kirill A. Shutemov   thp: introduce de...
1866
  	prep_transhuge_page(new_page);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1867

b32967ff1   Mel Gorman   mm: numa: Add THP...
1868
  	isolated = numamigrate_isolate_page(pgdat, page);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1869
  	if (!isolated) {
b32967ff1   Mel Gorman   mm: numa: Add THP...
1870
  		put_page(new_page);
340ef3902   Hugh Dickins   mm: numa: cleanup...
1871
  		goto out_fail;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1872
  	}
458aa76d1   Aneesh Kumar K.V   mm/thp/migration:...
1873
1874
1875
1876
  	/*
  	 * We are not sure a pending tlb flush here is for a huge page
  	 * mapping or not. Hence use the tlb range variant
  	 */
b0943d61b   Mel Gorman   mm: numa: defer T...
1877
1878
  	if (mm_tlb_flush_pending(mm))
  		flush_tlb_range(vma, mmun_start, mmun_end);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1879
  	/* Prepare a page as a migration target */
48c935ad8   Kirill A. Shutemov   page-flags: defin...
1880
  	__SetPageLocked(new_page);
fa9949da5   Hugh Dickins   mm: use __SetPage...
1881
  	__SetPageSwapBacked(new_page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1882
1883
1884
1885
1886
1887
1888
1889
  
  	/* anon mapping, we can simply copy page->mapping to the new page: */
  	new_page->mapping = page->mapping;
  	new_page->index = page->index;
  	migrate_page_copy(new_page, page);
  	WARN_ON(PageLRU(new_page));
  
  	/* Recheck the target PMD */
f714f4f20   Mel Gorman   mm: numa: call MM...
1890
  	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
c4088ebdc   Kirill A. Shutemov   mm: convert the r...
1891
  	ptl = pmd_lock(mm, pmd);
2b4847e73   Mel Gorman   mm: numa: seriali...
1892
1893
  	if (unlikely(!pmd_same(*pmd, entry) || page_count(page) != 2)) {
  fail_putback:
c4088ebdc   Kirill A. Shutemov   mm: convert the r...
1894
  		spin_unlock(ptl);
f714f4f20   Mel Gorman   mm: numa: call MM...
1895
  		mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1896
1897
1898
1899
1900
1901
  
  		/* Reverse changes made by migrate_page_copy() */
  		if (TestClearPageActive(new_page))
  			SetPageActive(page);
  		if (TestClearPageUnevictable(new_page))
  			SetPageUnevictable(page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1902
1903
1904
  
  		unlock_page(new_page);
  		put_page(new_page);		/* Free it */
a54a407fb   Mel Gorman   mm: Close races b...
1905
1906
  		/* Retake the callers reference and putback on LRU */
  		get_page(page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1907
  		putback_lru_page(page);
599d0c954   Mel Gorman   mm, vmscan: move ...
1908
  		mod_node_page_state(page_pgdat(page),
a54a407fb   Mel Gorman   mm: Close races b...
1909
  			 NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR);
eb4489f69   Mel Gorman   mm: numa: avoid u...
1910
1911
  
  		goto out_unlock;
b32967ff1   Mel Gorman   mm: numa: Add THP...
1912
  	}
2b4847e73   Mel Gorman   mm: numa: seriali...
1913
  	orig_entry = *pmd;
101024596   Kirill A. Shutemov   mm: introduce do_...
1914
  	entry = mk_huge_pmd(new_page, vma->vm_page_prot);
2b4847e73   Mel Gorman   mm: numa: seriali...
1915
  	entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1916

2b4847e73   Mel Gorman   mm: numa: seriali...
1917
1918
1919
1920
1921
1922
1923
  	/*
  	 * Clear the old entry under pagetable lock and establish the new PTE.
  	 * Any parallel GUP will either observe the old page blocking on the
  	 * page lock, block on the page table lock or observe the new page.
  	 * The SetPageUptodate on the new page and page_add_new_anon_rmap
  	 * guarantee the copy is visible before the pagetable update.
  	 */
f714f4f20   Mel Gorman   mm: numa: call MM...
1924
  	flush_cache_range(vma, mmun_start, mmun_end);
d281ee614   Kirill A. Shutemov   rmap: add argumen...
1925
  	page_add_anon_rmap(new_page, vma, mmun_start, true);
8809aa2d2   Aneesh Kumar K.V   mm: clarify that ...
1926
  	pmdp_huge_clear_flush_notify(vma, mmun_start, pmd);
f714f4f20   Mel Gorman   mm: numa: call MM...
1927
  	set_pmd_at(mm, mmun_start, pmd, entry);
ce4a9cc57   Stephen Rothwell   mm,numa: fix upda...
1928
  	update_mmu_cache_pmd(vma, address, &entry);
2b4847e73   Mel Gorman   mm: numa: seriali...
1929
1930
  
  	if (page_count(page) != 2) {
f714f4f20   Mel Gorman   mm: numa: call MM...
1931
  		set_pmd_at(mm, mmun_start, pmd, orig_entry);
458aa76d1   Aneesh Kumar K.V   mm/thp/migration:...
1932
  		flush_pmd_tlb_range(vma, mmun_start, mmun_end);
34ee645e8   Joerg Roedel   mmu_notifier: cal...
1933
  		mmu_notifier_invalidate_range(mm, mmun_start, mmun_end);
2b4847e73   Mel Gorman   mm: numa: seriali...
1934
  		update_mmu_cache_pmd(vma, address, &entry);
d281ee614   Kirill A. Shutemov   rmap: add argumen...
1935
  		page_remove_rmap(new_page, true);
2b4847e73   Mel Gorman   mm: numa: seriali...
1936
1937
  		goto fail_putback;
  	}
51afb12ba   Hugh Dickins   mm: page migratio...
1938
  	mlock_migrate_page(new_page, page);
d281ee614   Kirill A. Shutemov   rmap: add argumen...
1939
  	page_remove_rmap(page, true);
7cd12b4ab   Vlastimil Babka   mm, page_owner: t...
1940
  	set_page_owner_migrate_reason(new_page, MR_NUMA_MISPLACED);
2b4847e73   Mel Gorman   mm: numa: seriali...
1941

c4088ebdc   Kirill A. Shutemov   mm: convert the r...
1942
  	spin_unlock(ptl);
f714f4f20   Mel Gorman   mm: numa: call MM...
1943
  	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1944

11de9927f   Mel Gorman   mm: numa: add mig...
1945
1946
1947
  	/* Take an "isolate" reference and put new page on the LRU. */
  	get_page(new_page);
  	putback_lru_page(new_page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1948
1949
1950
1951
1952
1953
1954
  	unlock_page(new_page);
  	unlock_page(page);
  	put_page(page);			/* Drop the rmap reference */
  	put_page(page);			/* Drop the LRU isolation reference */
  
  	count_vm_events(PGMIGRATE_SUCCESS, HPAGE_PMD_NR);
  	count_vm_numa_events(NUMA_PAGE_MIGRATE, HPAGE_PMD_NR);
599d0c954   Mel Gorman   mm, vmscan: move ...
1955
  	mod_node_page_state(page_pgdat(page),
b32967ff1   Mel Gorman   mm: numa: Add THP...
1956
1957
1958
  			NR_ISOLATED_ANON + page_lru,
  			-HPAGE_PMD_NR);
  	return isolated;
340ef3902   Hugh Dickins   mm: numa: cleanup...
1959
1960
  out_fail:
  	count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1961
  out_dropref:
2b4847e73   Mel Gorman   mm: numa: seriali...
1962
1963
  	ptl = pmd_lock(mm, pmd);
  	if (pmd_same(*pmd, entry)) {
4d9424669   Mel Gorman   mm: convert p[te|...
1964
  		entry = pmd_modify(entry, vma->vm_page_prot);
f714f4f20   Mel Gorman   mm: numa: call MM...
1965
  		set_pmd_at(mm, mmun_start, pmd, entry);
2b4847e73   Mel Gorman   mm: numa: seriali...
1966
1967
1968
  		update_mmu_cache_pmd(vma, address, &entry);
  	}
  	spin_unlock(ptl);
a54a407fb   Mel Gorman   mm: Close races b...
1969

eb4489f69   Mel Gorman   mm: numa: avoid u...
1970
  out_unlock:
340ef3902   Hugh Dickins   mm: numa: cleanup...
1971
  	unlock_page(page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1972
  	put_page(page);
b32967ff1   Mel Gorman   mm: numa: Add THP...
1973
1974
  	return 0;
  }
7039e1dbe   Peter Zijlstra   mm: migrate: Intr...
1975
1976
1977
  #endif /* CONFIG_NUMA_BALANCING */
  
  #endif /* CONFIG_NUMA */