Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6bc32b8 authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds
Browse files

mm: compaction: introduce sync-light migration for use by compaction



This patch adds a lightweight sync migrate operation MIGRATE_SYNC_LIGHT
mode that avoids writing back pages to backing storage.  Async compaction
maps to MIGRATE_ASYNC while sync compaction maps to MIGRATE_SYNC_LIGHT.
For other migrate_pages users such as memory hotplug, MIGRATE_SYNC is
used.

This avoids sync compaction stalling for an excessive length of time,
particularly when copying files to a USB stick where there might be a
large number of dirty pages backed by a filesystem that does not support
->writepages.

[aarcange@redhat.com: This patch is heavily based on Andrea's work]
[akpm@linux-foundation.org: fix fs/nfs/write.c build]
[akpm@linux-foundation.org: fix fs/btrfs/disk-io.c build]
Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
Reviewed-by: default avatarRik 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 66199712
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -872,7 +872,8 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,

#ifdef CONFIG_MIGRATION
static int btree_migratepage(struct address_space *mapping,
			struct page *newpage, struct page *page, bool sync)
			struct page *newpage, struct page *page,
			enum migrate_mode mode)
{
	/*
	 * we can't safely write a btree page from here,
@@ -887,7 +888,7 @@ static int btree_migratepage(struct address_space *mapping,
	if (page_has_private(page) &&
	    !try_to_release_page(page, GFP_KERNEL))
		return -EAGAIN;
	return migrate_page(mapping, newpage, page, sync);
	return migrate_page(mapping, newpage, page, mode);
}
#endif

+1 −1
Original line number Diff line number Diff line
@@ -584,7 +584,7 @@ static int hugetlbfs_set_page_dirty(struct page *page)

static int hugetlbfs_migrate_page(struct address_space *mapping,
				struct page *newpage, struct page *page,
				bool sync)
				enum migrate_mode mode)
{
	int rc;

+1 −1
Original line number Diff line number Diff line
@@ -332,7 +332,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data);

#ifdef CONFIG_MIGRATION
extern int nfs_migrate_page(struct address_space *,
		struct page *, struct page *, bool);
		struct page *, struct page *, enum migrate_mode);
#else
#define nfs_migrate_page NULL
#endif
+2 −2
Original line number Diff line number Diff line
@@ -1688,7 +1688,7 @@ int nfs_wb_page(struct inode *inode, struct page *page)

#ifdef CONFIG_MIGRATION
int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
		struct page *page, bool sync)
		struct page *page, enum migrate_mode mode)
{
	/*
	 * 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,

	nfs_fscache_release_page(page, GFP_KERNEL);

	return migrate_page(mapping, newpage, page, sync);
	return migrate_page(mapping, newpage, page, mode);
}
#endif

+4 −2
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ enum positive_aop_returns {
struct page;
struct address_space;
struct writeback_control;
enum migrate_mode;

struct iov_iter {
	const struct iovec *iov;
@@ -614,7 +615,7 @@ struct address_space_operations {
	 * is false, it must not block.
	 */
	int (*migratepage) (struct address_space *,
			struct page *, struct page *, bool);
			struct page *, struct page *, enum migrate_mode);
	int (*launder_page) (struct page *);
	int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
					unsigned long);
@@ -2540,7 +2541,8 @@ extern int generic_check_addressable(unsigned, u64);

#ifdef CONFIG_MIGRATION
extern int buffer_migrate_page(struct address_space *,
				struct page *, struct page *, bool);
				struct page *, struct page *,
				enum migrate_mode);
#else
#define buffer_migrate_page NULL
#endif
Loading