aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c4
-rw-r--r--fs/hugetlbfs/inode.c3
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/write.c4
-rw-r--r--include/linux/fs.h9
-rw-r--r--include/linux/migrate.h2
-rw-r--r--mm/migrate.c129
7 files changed, 106 insertions, 47 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f99a099a7747..1375494c8cb6 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -872,7 +872,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
872 872
873#ifdef CONFIG_MIGRATION 873#ifdef CONFIG_MIGRATION
874static int btree_migratepage(struct address_space *mapping, 874static int btree_migratepage(struct address_space *mapping,
875 struct page *newpage, struct page *page) 875 struct page *newpage, struct page *page, bool sync)
876{ 876{
877 /* 877 /*
878 * we can't safely write a btree page from here, 878 * we can't safely write a btree page from here,
@@ -887,7 +887,7 @@ static int btree_migratepage(struct address_space *mapping,
887 if (page_has_private(page) && 887 if (page_has_private(page) &&
888 !try_to_release_page(page, GFP_KERNEL)) 888 !try_to_release_page(page, GFP_KERNEL))
889 return -EAGAIN; 889 return -EAGAIN;
890 return migrate_page(mapping, newpage, page); 890 return migrate_page(mapping, newpage, page, sync);
891} 891}
892#endif 892#endif
893 893
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e425ad9d0490..06fd4608a990 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -583,7 +583,8 @@ static int hugetlbfs_set_page_dirty(struct page *page)
583} 583}
584 584
585static int hugetlbfs_migrate_page(struct address_space *mapping, 585static int hugetlbfs_migrate_page(struct address_space *mapping,
586 struct page *newpage, struct page *page) 586 struct page *newpage, struct page *page,
587 bool sync)
587{ 588{
588 int rc; 589 int rc;
589 590
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 5ee92538b063..114398a15830 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -332,7 +332,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data);
332 332
333#ifdef CONFIG_MIGRATION 333#ifdef CONFIG_MIGRATION
334extern int nfs_migrate_page(struct address_space *, 334extern int nfs_migrate_page(struct address_space *,
335 struct page *, struct page *); 335 struct page *, struct page *, bool);
336#else 336#else
337#define nfs_migrate_page NULL 337#define nfs_migrate_page NULL
338#endif 338#endif
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0c3885255f97..889e98bc5a21 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1688,7 +1688,7 @@ out_error:
1688 1688
1689#ifdef CONFIG_MIGRATION 1689#ifdef CONFIG_MIGRATION
1690int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1690int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1691 struct page *page) 1691 struct page *page, bool sync)
1692{ 1692{
1693 /* 1693 /*
1694 * If PagePrivate is set, then the page is currently associated with 1694 * If PagePrivate is set, then the page is currently associated with
@@ -1703,7 +1703,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1703 1703
1704 nfs_fscache_release_page(page, GFP_KERNEL); 1704 nfs_fscache_release_page(page, GFP_KERNEL);
1705 1705
1706 return migrate_page(mapping, newpage, page); 1706 return migrate_page(mapping, newpage, page, sync);
1707} 1707}
1708#endif 1708#endif
1709 1709
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a7409bc157e0..b92b73d0b2b9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -609,9 +609,12 @@ struct address_space_operations {
609 loff_t offset, unsigned long nr_segs); 609 loff_t offset, unsigned long nr_segs);
610 int (*get_xip_mem)(struct address_space *, pgoff_t, int, 610 int (*get_xip_mem)(struct address_space *, pgoff_t, int,
611 void **, unsigned long *); 611 void **, unsigned long *);
612 /* migrate the contents of a page to the specified target */ 612 /*
613 * migrate the contents of a page to the specified target. If sync
614 * is false, it must not block.
615 */
613 int (*migratepage) (struct address_space *, 616 int (*migratepage) (struct address_space *,
614 struct page *, struct page *); 617 struct page *, struct page *, bool);
615 int (*launder_page) (struct page *); 618 int (*launder_page) (struct page *);
616 int (*is_partially_uptodate) (struct page *, read_descriptor_t *, 619 int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
617 unsigned long); 620 unsigned long);
@@ -2537,7 +2540,7 @@ extern int generic_check_addressable(unsigned, u64);
2537 2540
2538#ifdef CONFIG_MIGRATION 2541#ifdef CONFIG_MIGRATION
2539extern int buffer_migrate_page(struct address_space *, 2542extern int buffer_migrate_page(struct address_space *,
2540 struct page *, struct page *); 2543 struct page *, struct page *, bool);
2541#else 2544#else
2542#define buffer_migrate_page NULL 2545#define buffer_migrate_page NULL
2543#endif 2546#endif
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index e39aeecfe9a2..14e6d2a88475 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -11,7 +11,7 @@ typedef struct page *new_page_t(struct page *, unsigned long private, int **);
11 11
12extern void putback_lru_pages(struct list_head *l); 12extern void putback_lru_pages(struct list_head *l);
13extern int migrate_page(struct address_space *, 13extern int migrate_page(struct address_space *,
14 struct page *, struct page *); 14 struct page *, struct page *, bool);
15extern int migrate_pages(struct list_head *l, new_page_t x, 15extern int migrate_pages(struct list_head *l, new_page_t x,
16 unsigned long private, bool offlining, 16 unsigned long private, bool offlining,
17 bool sync); 17 bool sync);
diff --git a/mm/migrate.c b/mm/migrate.c
index fc391985899f..4e86f3bacb85 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -216,6 +216,55 @@ out:
216 pte_unmap_unlock(ptep, ptl); 216 pte_unmap_unlock(ptep, ptl);
217} 217}
218 218
219#ifdef CONFIG_BLOCK
220/* Returns true if all buffers are successfully locked */
221static bool buffer_migrate_lock_buffers(struct buffer_head *head, bool sync)
222{
223 struct buffer_head *bh = head;
224
225 /* Simple case, sync compaction */
226 if (sync) {
227 do {
228 get_bh(bh);
229 lock_buffer(bh);
230 bh = bh->b_this_page;
231
232 } while (bh != head);
233
234 return true;
235 }
236
237 /* async case, we cannot block on lock_buffer so use trylock_buffer */
238 do {
239 get_bh(bh);
240 if (!trylock_buffer(bh)) {
241 /*
242 * We failed to lock the buffer and cannot stall in
243 * async migration. Release the taken locks
244 */
245 struct buffer_head *failed_bh = bh;
246 put_bh(failed_bh);
247 bh = head;
248 while (bh != failed_bh) {
249 unlock_buffer(bh);
250 put_bh(bh);
251 bh = bh->b_this_page;
252 }
253 return false;
254 }
255
256 bh = bh->b_this_page;
257 } while (bh != head);
258 return true;
259}
260#else
261static inline bool buffer_migrate_lock_buffers(struct buffer_head *head,
262 bool sync)
263{
264 return true;
265}
266#endif /* CONFIG_BLOCK */
267
219/* 268/*
220 * Replace the page in the mapping. 269 * Replace the page in the mapping.
221 * 270 *
@@ -225,7 +274,8 @@ out:
225 * 3 for pages with a mapping and PagePrivate/PagePrivate2 set. 274 * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
226 */ 275 */
227static int migrate_page_move_mapping(struct address_space *mapping, 276static int migrate_page_move_mapping(struct address_space *mapping,
228 struct page *newpage, struct page *page) 277 struct page *newpage, struct page *page,
278 struct buffer_head *head, bool sync)
229{ 279{
230 int expected_count; 280 int expected_count;
231 void **pslot; 281 void **pslot;
@@ -255,6 +305,19 @@ static int migrate_page_move_mapping(struct address_space *mapping,
255 } 305 }
256 306
257 /* 307 /*
308 * In the async migration case of moving a page with buffers, lock the
309 * buffers using trylock before the mapping is moved. If the mapping
310 * was moved, we later failed to lock the buffers and could not move
311 * the mapping back due to an elevated page count, we would have to
312 * block waiting on other references to be dropped.
313 */
314 if (!sync && head && !buffer_migrate_lock_buffers(head, sync)) {
315 page_unfreeze_refs(page, expected_count);
316 spin_unlock_irq(&mapping->tree_lock);
317 return -EAGAIN;
318 }
319
320 /*
258 * Now we know that no one else is looking at the page. 321 * Now we know that no one else is looking at the page.
259 */ 322 */
260 get_page(newpage); /* add cache reference */ 323 get_page(newpage); /* add cache reference */
@@ -409,13 +472,13 @@ EXPORT_SYMBOL(fail_migrate_page);
409 * Pages are locked upon entry and exit. 472 * Pages are locked upon entry and exit.
410 */ 473 */
411int migrate_page(struct address_space *mapping, 474int migrate_page(struct address_space *mapping,
412 struct page *newpage, struct page *page) 475 struct page *newpage, struct page *page, bool sync)
413{ 476{
414 int rc; 477 int rc;
415 478
416 BUG_ON(PageWriteback(page)); /* Writeback must be complete */ 479 BUG_ON(PageWriteback(page)); /* Writeback must be complete */
417 480
418 rc = migrate_page_move_mapping(mapping, newpage, page); 481 rc = migrate_page_move_mapping(mapping, newpage, page, NULL, sync);
419 482
420 if (rc) 483 if (rc)
421 return rc; 484 return rc;
@@ -432,28 +495,28 @@ EXPORT_SYMBOL(migrate_page);
432 * exist. 495 * exist.
433 */ 496 */
434int buffer_migrate_page(struct address_space *mapping, 497int buffer_migrate_page(struct address_space *mapping,
435 struct page *newpage, struct page *page) 498 struct page *newpage, struct page *page, bool sync)
436{ 499{
437 struct buffer_head *bh, *head; 500 struct buffer_head *bh, *head;
438 int rc; 501 int rc;
439 502
440 if (!page_has_buffers(page)) 503 if (!page_has_buffers(page))
441 return migrate_page(mapping, newpage, page); 504 return migrate_page(mapping, newpage, page, sync);
442 505
443 head = page_buffers(page); 506 head = page_buffers(page);
444 507
445 rc = migrate_page_move_mapping(mapping, newpage, page); 508 rc = migrate_page_move_mapping(mapping, newpage, page, head, sync);
446 509
447 if (rc) 510 if (rc)
448 return rc; 511 return rc;
449 512
450 bh = head; 513 /*
451 do { 514 * In the async case, migrate_page_move_mapping locked the buffers
452 get_bh(bh); 515 * with an IRQ-safe spinlock held. In the sync case, the buffers
453 lock_buffer(bh); 516 * need to be locked now
454 bh = bh->b_this_page; 517 */
455 518 if (sync)
456 } while (bh != head); 519 BUG_ON(!buffer_migrate_lock_buffers(head, sync));
457 520
458 ClearPagePrivate(page); 521 ClearPagePrivate(page);
459 set_page_private(newpage, page_private(page)); 522 set_page_private(newpage, page_private(page));
@@ -530,10 +593,13 @@ static int writeout(struct address_space *mapping, struct page *page)
530 * Default handling if a filesystem does not provide a migration function. 593 * Default handling if a filesystem does not provide a migration function.
531 */ 594 */
532static int fallback_migrate_page(struct address_space *mapping, 595static int fallback_migrate_page(struct address_space *mapping,
533 struct page *newpage, struct page *page) 596 struct page *newpage, struct page *page, bool sync)
534{ 597{
535 if (PageDirty(page)) 598 if (PageDirty(page)) {
599 if (!sync)
600 return -EBUSY;
536 return writeout(mapping, page); 601 return writeout(mapping, page);
602 }
537 603
538 /* 604 /*
539 * Buffers may be managed in a filesystem specific way. 605 * Buffers may be managed in a filesystem specific way.
@@ -543,7 +609,7 @@ static int fallback_migrate_page(struct address_space *mapping,
543 !try_to_release_page(page, GFP_KERNEL)) 609 !try_to_release_page(page, GFP_KERNEL))
544 return -EAGAIN; 610 return -EAGAIN;
545 611
546 return migrate_page(mapping, newpage, page); 612 return migrate_page(mapping, newpage, page, sync);
547} 613}
548 614
549/* 615/*
@@ -579,29 +645,18 @@ static int move_to_new_page(struct page *newpage, struct page *page,
579 645
580 mapping = page_mapping(page); 646 mapping = page_mapping(page);
581 if (!mapping) 647 if (!mapping)
582 rc = migrate_page(mapping, newpage, page); 648 rc = migrate_page(mapping, newpage, page, sync);
583 else { 649 else if (mapping->a_ops->migratepage)
584 /* 650 /*
585 * Do not writeback pages if !sync and migratepage is 651 * Most pages have a mapping and most filesystems provide a
586 * not pointing to migrate_page() which is nonblocking 652 * migratepage callback. Anonymous pages are part of swap
587 * (swapcache/tmpfs uses migratepage = migrate_page). 653 * space which also has its own migratepage callback. This
654 * is the most common path for page migration.
588 */ 655 */
589 if (PageDirty(page) && !sync && 656 rc = mapping->a_ops->migratepage(mapping,
590 mapping->a_ops->migratepage != migrate_page) 657 newpage, page, sync);
591 rc = -EBUSY; 658 else
592 else if (mapping->a_ops->migratepage) 659 rc = fallback_migrate_page(mapping, newpage, page, sync);
593 /*
594 * Most pages have a mapping and most filesystems
595 * should provide a migration function. Anonymous
596 * pages are part of swap space which also has its
597 * own migration function. This is the most common
598 * path for page migration.
599 */
600 rc = mapping->a_ops->migratepage(mapping,
601 newpage, page);
602 else
603 rc = fallback_migrate_page(mapping, newpage, page);
604 }
605 660
606 if (rc) { 661 if (rc) {
607 newpage->mapping = NULL; 662 newpage->mapping = NULL;