aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-01-12 20:19:34 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-01 15:27:17 -0400
commit397d9c507ff1c9c5afc80c80ee245c2455d6a1db (patch)
tree7dd25dcfbda01ac207f42941f7386f74ac213470 /fs
parentec46a9e8767b9fa37c5d18b18b24ea96a5d2695d (diff)
mm: compaction: determine if dirty pages can be migrated without blocking within ->migratepage
commit b969c4ab9f182a6e1b2a0848be349f99714947b0 upstream. Stable note: Not tracked in Bugzilla. A fix aimed at preserving page aging information by reducing LRU list churning had the side-effect of reducing THP allocation success rates. This was part of a series to restore the success rates while preserving the reclaim fix. Asynchronous compaction is used when allocating transparent hugepages to avoid blocking for long periods of time. Due to reports of stalling, there was a debate on disabling synchronous compaction but this severely impacted allocation success rates. Part of the reason was that many dirty pages are skipped in asynchronous compaction by the following check; if (PageDirty(page) && !sync && mapping->a_ops->migratepage != migrate_page) rc = -EBUSY; This skips over all mapping aops using buffer_migrate_page() even though it is possible to migrate some of these pages without blocking. This patch updates the ->migratepage callback with a "sync" parameter. It is the responsibility of the callback to fail gracefully if migration would block. Signed-off-by: Mel Gorman <mgorman@suse.de> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Dave Jones <davej@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Andy Isaacson <adi@hexapodia.org> Cc: Nai Xia <nai.xia@gmail.com> Cc: Johannes Weiner <jweiner@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Mel Gorman <mgorman@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-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
4 files changed, 7 insertions, 6 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1ac8db5dc0a..522cb2a6cb1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -801,7 +801,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
801 801
802#ifdef CONFIG_MIGRATION 802#ifdef CONFIG_MIGRATION
803static int btree_migratepage(struct address_space *mapping, 803static int btree_migratepage(struct address_space *mapping,
804 struct page *newpage, struct page *page) 804 struct page *newpage, struct page *page, bool sync)
805{ 805{
806 /* 806 /*
807 * we can't safely write a btree page from here, 807 * we can't safely write a btree page from here,
@@ -816,7 +816,7 @@ static int btree_migratepage(struct address_space *mapping,
816 if (page_has_private(page) && 816 if (page_has_private(page) &&
817 !try_to_release_page(page, GFP_KERNEL)) 817 !try_to_release_page(page, GFP_KERNEL))
818 return -EAGAIN; 818 return -EAGAIN;
819 return migrate_page(mapping, newpage, page); 819 return migrate_page(mapping, newpage, page, sync);
820} 820}
821#endif 821#endif
822 822
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8b0c87530b0..6ca608bbc8b 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -568,7 +568,8 @@ static int hugetlbfs_set_page_dirty(struct page *page)
568} 568}
569 569
570static int hugetlbfs_migrate_page(struct address_space *mapping, 570static int hugetlbfs_migrate_page(struct address_space *mapping,
571 struct page *newpage, struct page *page) 571 struct page *newpage, struct page *page,
572 bool sync)
572{ 573{
573 int rc; 574 int rc;
574 575
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2a55347a2da..a74442ae688 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -315,7 +315,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data);
315 315
316#ifdef CONFIG_MIGRATION 316#ifdef CONFIG_MIGRATION
317extern int nfs_migrate_page(struct address_space *, 317extern int nfs_migrate_page(struct address_space *,
318 struct page *, struct page *); 318 struct page *, struct page *, bool);
319#else 319#else
320#define nfs_migrate_page NULL 320#define nfs_migrate_page NULL
321#endif 321#endif
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f2f80c005c0..22a48fdee3c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1662,7 +1662,7 @@ out_error:
1662 1662
1663#ifdef CONFIG_MIGRATION 1663#ifdef CONFIG_MIGRATION
1664int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1664int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1665 struct page *page) 1665 struct page *page, bool sync)
1666{ 1666{
1667 /* 1667 /*
1668 * If PagePrivate is set, then the page is currently associated with 1668 * If PagePrivate is set, then the page is currently associated with
@@ -1677,7 +1677,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1677 1677
1678 nfs_fscache_release_page(page, GFP_KERNEL); 1678 nfs_fscache_release_page(page, GFP_KERNEL);
1679 1679
1680 return migrate_page(mapping, newpage, page); 1680 return migrate_page(mapping, newpage, page, sync);
1681} 1681}
1682#endif 1682#endif
1683 1683