diff for duplicates of <20160322021927.GA30070@bbox> diff --git a/a/1.txt b/N1/1.txt index db24418..c68b085 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -43,3 +43,565 @@ On Mon, Mar 21, 2016 at 04:29:55PM +0800, kbuild test robot wrote: Thanks, kbuild. Fixed. + +>From 7006a7ee62bb09273f96d8cb45c32e42453ab931 Mon Sep 17 00:00:00 2001 +From: Minchan Kim <minchan@kernel.org> +Date: Thu, 3 Mar 2016 14:28:45 +0900 +Subject: [PATCH] mm/balloon: use general movable page feature into balloon + +Now, VM has a feature to migrate non-lru movable pages so +balloon doesn't need custom migration hooks in migrate.c +and compact.c. Instead, this patch implements page->mapping +->{isolate|migrate|putback} functions. + +With that, we could remove hooks for ballooning in general +migration functions and make balloon compaction simple. + +Cc: virtualization@lists.linux-foundation.org +Cc: Rafael Aquini <aquini@redhat.com> +Cc: Konstantin Khlebnikov <koct9i@gmail.com> +Signed-off-by: Gioh Kim <gurugio@hanmail.net> +Signed-off-by: Minchan Kim <minchan@kernel.org> +--- + drivers/virtio/virtio_balloon.c | 53 ++++++++++++++++--- + include/linux/balloon_compaction.h | 47 ++++------------- + include/linux/page-flags.h | 52 +++++++++++-------- + include/uapi/linux/magic.h | 1 + + mm/balloon_compaction.c | 101 ++++++++----------------------------- + mm/compaction.c | 7 --- + mm/migrate.c | 22 ++------ + mm/vmscan.c | 2 +- + 8 files changed, 116 insertions(+), 169 deletions(-) + +diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c +index 7b6d74f0c72f..0c16192d2684 100644 +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -30,6 +30,7 @@ + #include <linux/oom.h> + #include <linux/wait.h> + #include <linux/mm.h> ++#include <linux/mount.h> + + /* + * Balloon device works in 4K page units. So each page is pointed to by +@@ -45,6 +46,10 @@ static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES; + module_param(oom_pages, int, S_IRUSR | S_IWUSR); + MODULE_PARM_DESC(oom_pages, "pages to free on OOM"); + ++#ifdef CONFIG_BALLOON_COMPACTION ++static struct vfsmount *balloon_mnt; ++#endif ++ + struct virtio_balloon { + struct virtio_device *vdev; + struct virtqueue *inflate_vq, *deflate_vq, *stats_vq; +@@ -482,10 +487,29 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, + + mutex_unlock(&vb->balloon_lock); + ++ ClearPageIsolated(page); + put_page(page); /* balloon reference */ + + return MIGRATEPAGE_SUCCESS; + } ++ ++static struct dentry *balloon_mount(struct file_system_type *fs_type, ++ int flags, const char *dev_name, void *data) ++{ ++ static const struct dentry_operations ops = { ++ .d_dname = simple_dname, ++ }; ++ ++ return mount_pseudo(fs_type, "balloon-kvm:", NULL, &ops, ++ BALLOON_KVM_MAGIC); ++} ++ ++static struct file_system_type balloon_fs = { ++ .name = "balloon-kvm", ++ .mount = balloon_mount, ++ .kill_sb = kill_anon_super, ++}; ++ + #endif /* CONFIG_BALLOON_COMPACTION */ + + static int virtballoon_probe(struct virtio_device *vdev) +@@ -515,10 +539,6 @@ static int virtballoon_probe(struct virtio_device *vdev) + vb->vdev = vdev; + + balloon_devinfo_init(&vb->vb_dev_info); +-#ifdef CONFIG_BALLOON_COMPACTION +- vb->vb_dev_info.migratepage = virtballoon_migratepage; +-#endif +- + err = init_vqs(vb); + if (err) + goto out_free_vb; +@@ -527,13 +547,32 @@ static int virtballoon_probe(struct virtio_device *vdev) + vb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY; + err = register_oom_notifier(&vb->nb); + if (err < 0) +- goto out_oom_notify; ++ goto out_del_vqs; ++ ++#ifdef CONFIG_BALLOON_COMPACTION ++ balloon_mnt = kern_mount(&balloon_fs); ++ if (IS_ERR(balloon_mnt)) { ++ err = PTR_ERR(balloon_mnt); ++ unregister_oom_notifier(&vb->nb); ++ goto out_del_vqs; ++ } + ++ vb->vb_dev_info.migratepage = virtballoon_migratepage; ++ vb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb); ++ if (IS_ERR(vb->vb_dev_info.inode)) { ++ err = PTR_ERR(vb->vb_dev_info.inode); ++ kern_unmount(balloon_mnt); ++ unregister_oom_notifier(&vb->nb); ++ vb->vb_dev_info.inode = NULL; ++ goto out_del_vqs; ++ } ++ vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops; ++#endif + virtio_device_ready(vdev); + + return 0; + +-out_oom_notify: ++out_del_vqs: + vdev->config->del_vqs(vdev); + out_free_vb: + kfree(vb); +@@ -567,6 +606,8 @@ static void virtballoon_remove(struct virtio_device *vdev) + cancel_work_sync(&vb->update_balloon_stats_work); + + remove_common(vb); ++ if (vb->vb_dev_info.inode) ++ iput(vb->vb_dev_info.inode); + kfree(vb); + } + +diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h +index 9b0a15d06a4f..43a858545844 100644 +--- a/include/linux/balloon_compaction.h ++++ b/include/linux/balloon_compaction.h +@@ -48,6 +48,7 @@ + #include <linux/migrate.h> + #include <linux/gfp.h> + #include <linux/err.h> ++#include <linux/fs.h> + + /* + * Balloon device information descriptor. +@@ -62,6 +63,7 @@ struct balloon_dev_info { + struct list_head pages; /* Pages enqueued & handled to Host */ + int (*migratepage)(struct balloon_dev_info *, struct page *newpage, + struct page *page, enum migrate_mode mode); ++ struct inode *inode; + }; + + extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info); +@@ -73,45 +75,19 @@ static inline void balloon_devinfo_init(struct balloon_dev_info *balloon) + spin_lock_init(&balloon->pages_lock); + INIT_LIST_HEAD(&balloon->pages); + balloon->migratepage = NULL; ++ balloon->inode = NULL; + } + + #ifdef CONFIG_BALLOON_COMPACTION +-extern bool balloon_page_isolate(struct page *page); ++extern const struct address_space_operations balloon_aops; ++extern bool balloon_page_isolate(struct page *page, ++ isolate_mode_t mode); + extern void balloon_page_putback(struct page *page); +-extern int balloon_page_migrate(struct page *newpage, ++extern int balloon_page_migrate(struct address_space *mapping, ++ struct page *newpage, + struct page *page, enum migrate_mode mode); + + /* +- * __is_movable_balloon_page - helper to perform @page PageBalloon tests +- */ +-static inline bool __is_movable_balloon_page(struct page *page) +-{ +- return PageBalloon(page); +-} +- +-/* +- * balloon_page_movable - test PageBalloon to identify balloon pages +- * and PagePrivate to check that the page is not +- * isolated and can be moved by compaction/migration. +- * +- * As we might return false positives in the case of a balloon page being just +- * released under us, this need to be re-tested later, under the page lock. +- */ +-static inline bool balloon_page_movable(struct page *page) +-{ +- return PageBalloon(page) && PagePrivate(page); +-} +- +-/* +- * isolated_balloon_page - identify an isolated balloon page on private +- * compaction/migration page lists. +- */ +-static inline bool isolated_balloon_page(struct page *page) +-{ +- return PageBalloon(page); +-} +- +-/* + * balloon_page_insert - insert a page into the balloon's page list and make + * the page->private assignment accordingly. + * @balloon : pointer to balloon device +@@ -123,8 +99,8 @@ static inline bool isolated_balloon_page(struct page *page) + static inline void balloon_page_insert(struct balloon_dev_info *balloon, + struct page *page) + { ++ page->mapping = balloon->inode->i_mapping; + __SetPageBalloon(page); +- SetPagePrivate(page); + set_page_private(page, (unsigned long)balloon); + list_add(&page->lru, &balloon->pages); + } +@@ -140,11 +116,10 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, + static inline void balloon_page_delete(struct page *page) + { + __ClearPageBalloon(page); ++ page->mapping = NULL; + set_page_private(page, 0); +- if (PagePrivate(page)) { +- ClearPagePrivate(page); ++ if (!PageIsolated(page)) + list_del(&page->lru); +- } + } + + /* +diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h +index 3885064641c4..4853e0487175 100644 +--- a/include/linux/page-flags.h ++++ b/include/linux/page-flags.h +@@ -599,50 +599,58 @@ static inline void __ClearPageBuddy(struct page *page) + + extern bool is_free_buddy_page(struct page *page); + +-#define PAGE_BALLOON_MAPCOUNT_VALUE (-256) ++#define PAGE_MOVABLE_MAPCOUNT_VALUE (-256) ++#define PAGE_BALLOON_MAPCOUNT_VALUE PAGE_MOVABLE_MAPCOUNT_VALUE + +-static inline int PageBalloon(struct page *page) ++static inline int PageMovable(struct page *page) + { +- return atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE; ++ return (test_bit(PG_movable, &(page)->flags) && ++ atomic_read(&page->_mapcount) == PAGE_MOVABLE_MAPCOUNT_VALUE); + } + +-static inline void __SetPageBalloon(struct page *page) ++/* Caller should hold a PG_lock */ ++static inline void __SetPageMovable(struct page *page) + { +- VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page); +- atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE); ++ __set_bit(PG_movable, &page->flags); ++ atomic_set(&page->_mapcount, PAGE_MOVABLE_MAPCOUNT_VALUE); + } + +-static inline void __ClearPageBalloon(struct page *page) ++static inline void __ClearPageMovable(struct page *page) + { +- VM_BUG_ON_PAGE(!PageBalloon(page), page); + atomic_set(&page->_mapcount, -1); ++ __clear_bit(PG_movable, &(page)->flags); + } + +-#define PAGE_MOVABLE_MAPCOUNT_VALUE (-255) ++PAGEFLAG(Isolated, isolated, PF_ANY); + +-static inline int PageMovable(struct page *page) ++static inline int PageBalloon(struct page *page) + { +- return ((test_bit(PG_movable, &(page)->flags) && +- atomic_read(&page->_mapcount) == PAGE_MOVABLE_MAPCOUNT_VALUE) +- || PageBalloon(page)); ++ return atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE ++ && PagePrivate2(page); + } + +-/* +- * Caller should hold a PG_lock */ +-static inline void __SetPageMovable(struct page *page) ++static inline void __SetPageBalloon(struct page *page) + { +- __set_bit(PG_movable, &page->flags); +- atomic_set(&page->_mapcount, PAGE_MOVABLE_MAPCOUNT_VALUE); ++ VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page); ++#ifdef CONFIG_BALLOON_COMPACTION ++ __SetPageMovable(page); ++#else ++ atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE); ++#endif ++ SetPagePrivate2(page); + } + +-static inline void __ClearPageMovable(struct page *page) ++static inline void __ClearPageBalloon(struct page *page) + { ++ VM_BUG_ON_PAGE(!PageBalloon(page), page); ++#ifdef CONFIG_BALLOON_COMPACTION ++ __ClearPageMovable(page); ++#else + atomic_set(&page->_mapcount, -1); +- __clear_bit(PG_movable, &(page)->flags); ++#endif ++ ClearPagePrivate2(page); + } + +-PAGEFLAG(Isolated, isolated, PF_ANY); +- + /* + * If network-based swap is enabled, sl*b must keep track of whether pages + * were allocated from pfmemalloc reserves. +diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h +index 0de181ad73d5..e1fbe72c39c0 100644 +--- a/include/uapi/linux/magic.h ++++ b/include/uapi/linux/magic.h +@@ -78,5 +78,6 @@ + #define BTRFS_TEST_MAGIC 0x73727279 + #define NSFS_MAGIC 0x6e736673 + #define BPF_FS_MAGIC 0xcafe4a11 ++#define BALLOON_KVM_MAGIC 0x13661366 + + #endif /* __LINUX_MAGIC_H__ */ +diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c +index 57b3e9bd6bc5..1fbc7fb387bb 100644 +--- a/mm/balloon_compaction.c ++++ b/mm/balloon_compaction.c +@@ -70,7 +70,7 @@ struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info) + */ + if (trylock_page(page)) { + #ifdef CONFIG_BALLOON_COMPACTION +- if (!PagePrivate(page)) { ++ if (PageIsolated(page)) { + /* raced with isolation */ + unlock_page(page); + continue; +@@ -106,110 +106,53 @@ EXPORT_SYMBOL_GPL(balloon_page_dequeue); + + #ifdef CONFIG_BALLOON_COMPACTION + +-static inline void __isolate_balloon_page(struct page *page) ++/* __isolate_lru_page() counterpart for a ballooned page */ ++bool balloon_page_isolate(struct page *page, isolate_mode_t mode) + { + struct balloon_dev_info *b_dev_info = balloon_page_device(page); + unsigned long flags; + + spin_lock_irqsave(&b_dev_info->pages_lock, flags); +- ClearPagePrivate(page); + list_del(&page->lru); + b_dev_info->isolated_pages++; + spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); ++ SetPageIsolated(page); ++ ++ return true; + } + +-static inline void __putback_balloon_page(struct page *page) ++/* putback_lru_page() counterpart for a ballooned page */ ++void balloon_page_putback(struct page *page) + { + struct balloon_dev_info *b_dev_info = balloon_page_device(page); + unsigned long flags; + ++ ClearPageIsolated(page); + spin_lock_irqsave(&b_dev_info->pages_lock, flags); +- SetPagePrivate(page); + list_add(&page->lru, &b_dev_info->pages); + b_dev_info->isolated_pages--; + spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); + } + +-/* __isolate_lru_page() counterpart for a ballooned page */ +-bool balloon_page_isolate(struct page *page) +-{ +- /* +- * 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 balloon 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 (likely(get_page_unless_zero(page))) { +- /* +- * As balloon pages are not isolated from LRU lists, concurrent +- * compaction threads can race against page migration functions +- * as well as race against the balloon driver releasing a page. +- * +- * In order to avoid having an already isolated balloon page +- * being (wrongly) re-isolated while it is under migration, +- * or to avoid attempting to isolate pages being released by +- * the balloon driver, lets be sure we have the page lock +- * before proceeding with the balloon page isolation steps. +- */ +- if (likely(trylock_page(page))) { +- /* +- * A ballooned page, by default, has PagePrivate set. +- * Prevent concurrent compaction threads from isolating +- * an already isolated balloon page by clearing it. +- */ +- if (balloon_page_movable(page)) { +- __isolate_balloon_page(page); +- unlock_page(page); +- return true; +- } +- unlock_page(page); +- } +- put_page(page); +- } +- return false; +-} +- +-/* putback_lru_page() counterpart for a ballooned page */ +-void balloon_page_putback(struct page *page) +-{ +- /* +- * 'lock_page()' stabilizes the page and prevents races against +- * concurrent isolation threads attempting to re-isolate it. +- */ +- lock_page(page); +- +- if (__is_movable_balloon_page(page)) { +- __putback_balloon_page(page); +- /* drop the extra ref count taken for page isolation */ +- put_page(page); +- } else { +- WARN_ON(1); +- dump_page(page, "not movable balloon page"); +- } +- unlock_page(page); +-} +- + /* move_to_new_page() counterpart for a ballooned page */ +-int balloon_page_migrate(struct page *newpage, +- struct page *page, enum migrate_mode mode) ++int balloon_page_migrate(struct address_space *mapping, ++ struct page *newpage, struct page *page, ++ enum migrate_mode mode) + { + struct balloon_dev_info *balloon = balloon_page_device(page); +- int rc = -EAGAIN; + + VM_BUG_ON_PAGE(!PageLocked(page), page); + VM_BUG_ON_PAGE(!PageLocked(newpage), newpage); ++ VM_BUG_ON_PAGE(!PageMovable(page), page); ++ VM_BUG_ON_PAGE(!PageIsolated(page), page); + +- if (WARN_ON(!__is_movable_balloon_page(page))) { +- dump_page(page, "not movable balloon page"); +- return rc; +- } +- +- if (balloon && balloon->migratepage) +- rc = balloon->migratepage(balloon, newpage, page, mode); +- +- return rc; ++ return balloon->migratepage(balloon, newpage, page, mode); + } ++ ++const struct address_space_operations balloon_aops = { ++ .migratepage = balloon_page_migrate, ++ .isolate_page = balloon_page_isolate, ++ .putback_page = balloon_page_putback, ++}; ++EXPORT_SYMBOL_GPL(balloon_aops); + #endif /* CONFIG_BALLOON_COMPACTION */ +diff --git a/mm/compaction.c b/mm/compaction.c +index 7557aedddaee..e336c620fd7b 100644 +--- a/mm/compaction.c ++++ b/mm/compaction.c +@@ -708,13 +708,6 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn, + */ + is_lru = PageLRU(page); + if (!is_lru) { +- if (unlikely(balloon_page_movable(page))) { +- if (balloon_page_isolate(page)) { +- /* Successfully isolated */ +- goto isolate_success; +- } +- } +- + if (unlikely(PageMovable(page)) && + !PageIsolated(page)) { + if (locked) { +diff --git a/mm/migrate.c b/mm/migrate.c +index ab87ef45a3b9..3234c14ed1cd 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -147,8 +147,8 @@ void putback_movable_page(struct page *page) + * from where they were once taken off for compaction/migration. + * + * 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(). ++ * built from lru, movable, hugetlbfs page. ++ * See isolate_migratepages_range() and isolate_huge_page(). + */ + void putback_movable_pages(struct list_head *l) + { +@@ -163,9 +163,7 @@ void putback_movable_pages(struct list_head *l) + list_del(&page->lru); + dec_zone_page_state(page, NR_ISOLATED_ANON + + page_is_file_cache(page)); +- if (unlikely(isolated_balloon_page(page))) +- balloon_page_putback(page); +- else if (unlikely(PageIsolated(page))) ++ if (unlikely(PageIsolated(page))) + putback_movable_page(page); + else + putback_lru_page(page); +@@ -959,18 +957,6 @@ static int __unmap_and_move(struct page *page, struct page *newpage, + if (unlikely(!trylock_page(newpage))) + goto out_unlock; + +- if (unlikely(isolated_balloon_page(page))) { +- /* +- * A ballooned page does not need any special attention from +- * physical to virtual reverse mapping procedures. +- * Skip any attempt to unmap PTEs or to remap swap cache, +- * in order to avoid burning cycles at rmap level, and perform +- * the page migration right away (proteced by page lock). +- */ +- rc = balloon_page_migrate(newpage, page, mode); +- goto out_unlock_both; +- } +- + /* + * Corner case handling: + * 1. When a new swap-cache page is read into, it is added to the LRU +@@ -1015,7 +1001,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, + out: + /* If migration is successful, move newpage to right list */ + if (rc == MIGRATEPAGE_SUCCESS) { +- if (unlikely(__is_movable_balloon_page(newpage))) ++ if (unlikely(PageMovable(newpage))) + put_page(newpage); + else + putback_lru_page(newpage); +diff --git a/mm/vmscan.c b/mm/vmscan.c +index c72032dbe8db..e5dfa0cf6fdc 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -1254,7 +1254,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone, + + list_for_each_entry_safe(page, next, page_list, lru) { + if (page_is_file_cache(page) && !PageDirty(page) && +- !isolated_balloon_page(page)) { ++ !PageIsolated(page)) { + ClearPageActive(page); + list_move(&page->lru, &clean_pages); + } +-- +1.9.1 diff --git a/a/content_digest b/N1/content_digest index 76d5a84..30cfbca 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -72,6 +72,568 @@ "\n" "\n" "Thanks, kbuild.\n" - Fixed. + "Fixed.\n" + "\n" + ">From 7006a7ee62bb09273f96d8cb45c32e42453ab931 Mon Sep 17 00:00:00 2001\n" + "From: Minchan Kim <minchan@kernel.org>\n" + "Date: Thu, 3 Mar 2016 14:28:45 +0900\n" + "Subject: [PATCH] mm/balloon: use general movable page feature into balloon\n" + "\n" + "Now, VM has a feature to migrate non-lru movable pages so\n" + "balloon doesn't need custom migration hooks in migrate.c\n" + "and compact.c. Instead, this patch implements page->mapping\n" + "->{isolate|migrate|putback} functions.\n" + "\n" + "With that, we could remove hooks for ballooning in general\n" + "migration functions and make balloon compaction simple.\n" + "\n" + "Cc: virtualization@lists.linux-foundation.org\n" + "Cc: Rafael Aquini <aquini@redhat.com>\n" + "Cc: Konstantin Khlebnikov <koct9i@gmail.com>\n" + "Signed-off-by: Gioh Kim <gurugio@hanmail.net>\n" + "Signed-off-by: Minchan Kim <minchan@kernel.org>\n" + "---\n" + " drivers/virtio/virtio_balloon.c | 53 ++++++++++++++++---\n" + " include/linux/balloon_compaction.h | 47 ++++-------------\n" + " include/linux/page-flags.h | 52 +++++++++++--------\n" + " include/uapi/linux/magic.h | 1 +\n" + " mm/balloon_compaction.c | 101 ++++++++-----------------------------\n" + " mm/compaction.c | 7 ---\n" + " mm/migrate.c | 22 ++------\n" + " mm/vmscan.c | 2 +-\n" + " 8 files changed, 116 insertions(+), 169 deletions(-)\n" + "\n" + "diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c\n" + "index 7b6d74f0c72f..0c16192d2684 100644\n" + "--- a/drivers/virtio/virtio_balloon.c\n" + "+++ b/drivers/virtio/virtio_balloon.c\n" + "@@ -30,6 +30,7 @@\n" + " #include <linux/oom.h>\n" + " #include <linux/wait.h>\n" + " #include <linux/mm.h>\n" + "+#include <linux/mount.h>\n" + " \n" + " /*\n" + " * Balloon device works in 4K page units. So each page is pointed to by\n" + "@@ -45,6 +46,10 @@ static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES;\n" + " module_param(oom_pages, int, S_IRUSR | S_IWUSR);\n" + " MODULE_PARM_DESC(oom_pages, \"pages to free on OOM\");\n" + " \n" + "+#ifdef CONFIG_BALLOON_COMPACTION\n" + "+static struct vfsmount *balloon_mnt;\n" + "+#endif\n" + "+\n" + " struct virtio_balloon {\n" + " \tstruct virtio_device *vdev;\n" + " \tstruct virtqueue *inflate_vq, *deflate_vq, *stats_vq;\n" + "@@ -482,10 +487,29 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,\n" + " \n" + " \tmutex_unlock(&vb->balloon_lock);\n" + " \n" + "+\tClearPageIsolated(page);\n" + " \tput_page(page); /* balloon reference */\n" + " \n" + " \treturn MIGRATEPAGE_SUCCESS;\n" + " }\n" + "+\n" + "+static struct dentry *balloon_mount(struct file_system_type *fs_type,\n" + "+\t\tint flags, const char *dev_name, void *data)\n" + "+{\n" + "+\tstatic const struct dentry_operations ops = {\n" + "+\t\t.d_dname = simple_dname,\n" + "+\t};\n" + "+\n" + "+\treturn mount_pseudo(fs_type, \"balloon-kvm:\", NULL, &ops,\n" + "+\t\t\t\tBALLOON_KVM_MAGIC);\n" + "+}\n" + "+\n" + "+static struct file_system_type balloon_fs = {\n" + "+\t.name = \"balloon-kvm\",\n" + "+\t.mount = balloon_mount,\n" + "+\t.kill_sb = kill_anon_super,\n" + "+};\n" + "+\n" + " #endif /* CONFIG_BALLOON_COMPACTION */\n" + " \n" + " static int virtballoon_probe(struct virtio_device *vdev)\n" + "@@ -515,10 +539,6 @@ static int virtballoon_probe(struct virtio_device *vdev)\n" + " \tvb->vdev = vdev;\n" + " \n" + " \tballoon_devinfo_init(&vb->vb_dev_info);\n" + "-#ifdef CONFIG_BALLOON_COMPACTION\n" + "-\tvb->vb_dev_info.migratepage = virtballoon_migratepage;\n" + "-#endif\n" + "-\n" + " \terr = init_vqs(vb);\n" + " \tif (err)\n" + " \t\tgoto out_free_vb;\n" + "@@ -527,13 +547,32 @@ static int virtballoon_probe(struct virtio_device *vdev)\n" + " \tvb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY;\n" + " \terr = register_oom_notifier(&vb->nb);\n" + " \tif (err < 0)\n" + "-\t\tgoto out_oom_notify;\n" + "+\t\tgoto out_del_vqs;\n" + "+\n" + "+#ifdef CONFIG_BALLOON_COMPACTION\n" + "+\tballoon_mnt = kern_mount(&balloon_fs);\n" + "+\tif (IS_ERR(balloon_mnt)) {\n" + "+\t\terr = PTR_ERR(balloon_mnt);\n" + "+\t\tunregister_oom_notifier(&vb->nb);\n" + "+\t\tgoto out_del_vqs;\n" + "+\t}\n" + " \n" + "+\tvb->vb_dev_info.migratepage = virtballoon_migratepage;\n" + "+\tvb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb);\n" + "+\tif (IS_ERR(vb->vb_dev_info.inode)) {\n" + "+\t\terr = PTR_ERR(vb->vb_dev_info.inode);\n" + "+\t\tkern_unmount(balloon_mnt);\n" + "+\t\tunregister_oom_notifier(&vb->nb);\n" + "+\t\tvb->vb_dev_info.inode = NULL;\n" + "+\t\tgoto out_del_vqs;\n" + "+\t}\n" + "+\tvb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops;\n" + "+#endif\n" + " \tvirtio_device_ready(vdev);\n" + " \n" + " \treturn 0;\n" + " \n" + "-out_oom_notify:\n" + "+out_del_vqs:\n" + " \tvdev->config->del_vqs(vdev);\n" + " out_free_vb:\n" + " \tkfree(vb);\n" + "@@ -567,6 +606,8 @@ static void virtballoon_remove(struct virtio_device *vdev)\n" + " \tcancel_work_sync(&vb->update_balloon_stats_work);\n" + " \n" + " \tremove_common(vb);\n" + "+\tif (vb->vb_dev_info.inode)\n" + "+\t\tiput(vb->vb_dev_info.inode);\n" + " \tkfree(vb);\n" + " }\n" + " \n" + "diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h\n" + "index 9b0a15d06a4f..43a858545844 100644\n" + "--- a/include/linux/balloon_compaction.h\n" + "+++ b/include/linux/balloon_compaction.h\n" + "@@ -48,6 +48,7 @@\n" + " #include <linux/migrate.h>\n" + " #include <linux/gfp.h>\n" + " #include <linux/err.h>\n" + "+#include <linux/fs.h>\n" + " \n" + " /*\n" + " * Balloon device information descriptor.\n" + "@@ -62,6 +63,7 @@ struct balloon_dev_info {\n" + " \tstruct list_head pages;\t\t/* Pages enqueued & handled to Host */\n" + " \tint (*migratepage)(struct balloon_dev_info *, struct page *newpage,\n" + " \t\t\tstruct page *page, enum migrate_mode mode);\n" + "+\tstruct inode *inode;\n" + " };\n" + " \n" + " extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);\n" + "@@ -73,45 +75,19 @@ static inline void balloon_devinfo_init(struct balloon_dev_info *balloon)\n" + " \tspin_lock_init(&balloon->pages_lock);\n" + " \tINIT_LIST_HEAD(&balloon->pages);\n" + " \tballoon->migratepage = NULL;\n" + "+\tballoon->inode = NULL;\n" + " }\n" + " \n" + " #ifdef CONFIG_BALLOON_COMPACTION\n" + "-extern bool balloon_page_isolate(struct page *page);\n" + "+extern const struct address_space_operations balloon_aops;\n" + "+extern bool balloon_page_isolate(struct page *page,\n" + "+\t\t\t\tisolate_mode_t mode);\n" + " extern void balloon_page_putback(struct page *page);\n" + "-extern int balloon_page_migrate(struct page *newpage,\n" + "+extern int balloon_page_migrate(struct address_space *mapping,\n" + "+\t\t\t\tstruct page *newpage,\n" + " \t\t\t\tstruct page *page, enum migrate_mode mode);\n" + " \n" + " /*\n" + "- * __is_movable_balloon_page - helper to perform @page PageBalloon tests\n" + "- */\n" + "-static inline bool __is_movable_balloon_page(struct page *page)\n" + "-{\n" + "-\treturn PageBalloon(page);\n" + "-}\n" + "-\n" + "-/*\n" + "- * balloon_page_movable - test PageBalloon to identify balloon pages\n" + "- *\t\t\t and PagePrivate to check that the page is not\n" + "- *\t\t\t isolated and can be moved by compaction/migration.\n" + "- *\n" + "- * As we might return false positives in the case of a balloon page being just\n" + "- * released under us, this need to be re-tested later, under the page lock.\n" + "- */\n" + "-static inline bool balloon_page_movable(struct page *page)\n" + "-{\n" + "-\treturn PageBalloon(page) && PagePrivate(page);\n" + "-}\n" + "-\n" + "-/*\n" + "- * isolated_balloon_page - identify an isolated balloon page on private\n" + "- *\t\t\t compaction/migration page lists.\n" + "- */\n" + "-static inline bool isolated_balloon_page(struct page *page)\n" + "-{\n" + "-\treturn PageBalloon(page);\n" + "-}\n" + "-\n" + "-/*\n" + " * balloon_page_insert - insert a page into the balloon's page list and make\n" + " *\t\t\t the page->private assignment accordingly.\n" + " * @balloon : pointer to balloon device\n" + "@@ -123,8 +99,8 @@ static inline bool isolated_balloon_page(struct page *page)\n" + " static inline void balloon_page_insert(struct balloon_dev_info *balloon,\n" + " \t\t\t\t struct page *page)\n" + " {\n" + "+\tpage->mapping = balloon->inode->i_mapping;\n" + " \t__SetPageBalloon(page);\n" + "-\tSetPagePrivate(page);\n" + " \tset_page_private(page, (unsigned long)balloon);\n" + " \tlist_add(&page->lru, &balloon->pages);\n" + " }\n" + "@@ -140,11 +116,10 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,\n" + " static inline void balloon_page_delete(struct page *page)\n" + " {\n" + " \t__ClearPageBalloon(page);\n" + "+\tpage->mapping = NULL;\n" + " \tset_page_private(page, 0);\n" + "-\tif (PagePrivate(page)) {\n" + "-\t\tClearPagePrivate(page);\n" + "+\tif (!PageIsolated(page))\n" + " \t\tlist_del(&page->lru);\n" + "-\t}\n" + " }\n" + " \n" + " /*\n" + "diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h\n" + "index 3885064641c4..4853e0487175 100644\n" + "--- a/include/linux/page-flags.h\n" + "+++ b/include/linux/page-flags.h\n" + "@@ -599,50 +599,58 @@ static inline void __ClearPageBuddy(struct page *page)\n" + " \n" + " extern bool is_free_buddy_page(struct page *page);\n" + " \n" + "-#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)\n" + "+#define PAGE_MOVABLE_MAPCOUNT_VALUE (-256)\n" + "+#define PAGE_BALLOON_MAPCOUNT_VALUE PAGE_MOVABLE_MAPCOUNT_VALUE\n" + " \n" + "-static inline int PageBalloon(struct page *page)\n" + "+static inline int PageMovable(struct page *page)\n" + " {\n" + "-\treturn atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE;\n" + "+\treturn (test_bit(PG_movable, &(page)->flags) &&\n" + "+\t\tatomic_read(&page->_mapcount) == PAGE_MOVABLE_MAPCOUNT_VALUE);\n" + " }\n" + " \n" + "-static inline void __SetPageBalloon(struct page *page)\n" + "+/* Caller should hold a PG_lock */\n" + "+static inline void __SetPageMovable(struct page *page)\n" + " {\n" + "-\tVM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);\n" + "-\tatomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE);\n" + "+\t__set_bit(PG_movable, &page->flags);\n" + "+\tatomic_set(&page->_mapcount, PAGE_MOVABLE_MAPCOUNT_VALUE);\n" + " }\n" + " \n" + "-static inline void __ClearPageBalloon(struct page *page)\n" + "+static inline void __ClearPageMovable(struct page *page)\n" + " {\n" + "-\tVM_BUG_ON_PAGE(!PageBalloon(page), page);\n" + " \tatomic_set(&page->_mapcount, -1);\n" + "+\t__clear_bit(PG_movable, &(page)->flags);\n" + " }\n" + " \n" + "-#define PAGE_MOVABLE_MAPCOUNT_VALUE (-255)\n" + "+PAGEFLAG(Isolated, isolated, PF_ANY);\n" + " \n" + "-static inline int PageMovable(struct page *page)\n" + "+static inline int PageBalloon(struct page *page)\n" + " {\n" + "-\treturn ((test_bit(PG_movable, &(page)->flags) &&\n" + "-\t\tatomic_read(&page->_mapcount) == PAGE_MOVABLE_MAPCOUNT_VALUE)\n" + "-\t\t|| PageBalloon(page));\n" + "+\treturn atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE\n" + "+\t\t&& PagePrivate2(page);\n" + " }\n" + " \n" + "-/*\n" + "- * Caller should hold a PG_lock */\n" + "-static inline void __SetPageMovable(struct page *page)\n" + "+static inline void __SetPageBalloon(struct page *page)\n" + " {\n" + "-\t__set_bit(PG_movable, &page->flags);\n" + "-\tatomic_set(&page->_mapcount, PAGE_MOVABLE_MAPCOUNT_VALUE);\n" + "+\tVM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);\n" + "+#ifdef CONFIG_BALLOON_COMPACTION\n" + "+\t__SetPageMovable(page);\n" + "+#else\n" + "+\tatomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE);\n" + "+#endif\n" + "+\tSetPagePrivate2(page);\n" + " }\n" + " \n" + "-static inline void __ClearPageMovable(struct page *page)\n" + "+static inline void __ClearPageBalloon(struct page *page)\n" + " {\n" + "+\tVM_BUG_ON_PAGE(!PageBalloon(page), page);\n" + "+#ifdef CONFIG_BALLOON_COMPACTION\n" + "+\t__ClearPageMovable(page);\n" + "+#else\n" + " \tatomic_set(&page->_mapcount, -1);\n" + "-\t__clear_bit(PG_movable, &(page)->flags);\n" + "+#endif\n" + "+\tClearPagePrivate2(page);\n" + " }\n" + " \n" + "-PAGEFLAG(Isolated, isolated, PF_ANY);\n" + "-\n" + " /*\n" + " * If network-based swap is enabled, sl*b must keep track of whether pages\n" + " * were allocated from pfmemalloc reserves.\n" + "diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h\n" + "index 0de181ad73d5..e1fbe72c39c0 100644\n" + "--- a/include/uapi/linux/magic.h\n" + "+++ b/include/uapi/linux/magic.h\n" + "@@ -78,5 +78,6 @@\n" + " #define BTRFS_TEST_MAGIC\t0x73727279\n" + " #define NSFS_MAGIC\t\t0x6e736673\n" + " #define BPF_FS_MAGIC\t\t0xcafe4a11\n" + "+#define BALLOON_KVM_MAGIC\t0x13661366\n" + " \n" + " #endif /* __LINUX_MAGIC_H__ */\n" + "diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c\n" + "index 57b3e9bd6bc5..1fbc7fb387bb 100644\n" + "--- a/mm/balloon_compaction.c\n" + "+++ b/mm/balloon_compaction.c\n" + "@@ -70,7 +70,7 @@ struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)\n" + " \t\t */\n" + " \t\tif (trylock_page(page)) {\n" + " #ifdef CONFIG_BALLOON_COMPACTION\n" + "-\t\t\tif (!PagePrivate(page)) {\n" + "+\t\t\tif (PageIsolated(page)) {\n" + " \t\t\t\t/* raced with isolation */\n" + " \t\t\t\tunlock_page(page);\n" + " \t\t\t\tcontinue;\n" + "@@ -106,110 +106,53 @@ EXPORT_SYMBOL_GPL(balloon_page_dequeue);\n" + " \n" + " #ifdef CONFIG_BALLOON_COMPACTION\n" + " \n" + "-static inline void __isolate_balloon_page(struct page *page)\n" + "+/* __isolate_lru_page() counterpart for a ballooned page */\n" + "+bool balloon_page_isolate(struct page *page, isolate_mode_t mode)\n" + " {\n" + " \tstruct balloon_dev_info *b_dev_info = balloon_page_device(page);\n" + " \tunsigned long flags;\n" + " \n" + " \tspin_lock_irqsave(&b_dev_info->pages_lock, flags);\n" + "-\tClearPagePrivate(page);\n" + " \tlist_del(&page->lru);\n" + " \tb_dev_info->isolated_pages++;\n" + " \tspin_unlock_irqrestore(&b_dev_info->pages_lock, flags);\n" + "+\tSetPageIsolated(page);\n" + "+\n" + "+\treturn true;\n" + " }\n" + " \n" + "-static inline void __putback_balloon_page(struct page *page)\n" + "+/* putback_lru_page() counterpart for a ballooned page */\n" + "+void balloon_page_putback(struct page *page)\n" + " {\n" + " \tstruct balloon_dev_info *b_dev_info = balloon_page_device(page);\n" + " \tunsigned long flags;\n" + " \n" + "+\tClearPageIsolated(page);\n" + " \tspin_lock_irqsave(&b_dev_info->pages_lock, flags);\n" + "-\tSetPagePrivate(page);\n" + " \tlist_add(&page->lru, &b_dev_info->pages);\n" + " \tb_dev_info->isolated_pages--;\n" + " \tspin_unlock_irqrestore(&b_dev_info->pages_lock, flags);\n" + " }\n" + " \n" + "-/* __isolate_lru_page() counterpart for a ballooned page */\n" + "-bool balloon_page_isolate(struct page *page)\n" + "-{\n" + "-\t/*\n" + "-\t * Avoid burning cycles with pages that are yet under __free_pages(),\n" + "-\t * or just got freed under us.\n" + "-\t *\n" + "-\t * In case we 'win' a race for a balloon page being freed under us and\n" + "-\t * raise its refcount preventing __free_pages() from doing its job\n" + "-\t * the put_page() at the end of this block will take care of\n" + "-\t * release this page, thus avoiding a nasty leakage.\n" + "-\t */\n" + "-\tif (likely(get_page_unless_zero(page))) {\n" + "-\t\t/*\n" + "-\t\t * As balloon pages are not isolated from LRU lists, concurrent\n" + "-\t\t * compaction threads can race against page migration functions\n" + "-\t\t * as well as race against the balloon driver releasing a page.\n" + "-\t\t *\n" + "-\t\t * In order to avoid having an already isolated balloon page\n" + "-\t\t * being (wrongly) re-isolated while it is under migration,\n" + "-\t\t * or to avoid attempting to isolate pages being released by\n" + "-\t\t * the balloon driver, lets be sure we have the page lock\n" + "-\t\t * before proceeding with the balloon page isolation steps.\n" + "-\t\t */\n" + "-\t\tif (likely(trylock_page(page))) {\n" + "-\t\t\t/*\n" + "-\t\t\t * A ballooned page, by default, has PagePrivate set.\n" + "-\t\t\t * Prevent concurrent compaction threads from isolating\n" + "-\t\t\t * an already isolated balloon page by clearing it.\n" + "-\t\t\t */\n" + "-\t\t\tif (balloon_page_movable(page)) {\n" + "-\t\t\t\t__isolate_balloon_page(page);\n" + "-\t\t\t\tunlock_page(page);\n" + "-\t\t\t\treturn true;\n" + "-\t\t\t}\n" + "-\t\t\tunlock_page(page);\n" + "-\t\t}\n" + "-\t\tput_page(page);\n" + "-\t}\n" + "-\treturn false;\n" + "-}\n" + "-\n" + "-/* putback_lru_page() counterpart for a ballooned page */\n" + "-void balloon_page_putback(struct page *page)\n" + "-{\n" + "-\t/*\n" + "-\t * 'lock_page()' stabilizes the page and prevents races against\n" + "-\t * concurrent isolation threads attempting to re-isolate it.\n" + "-\t */\n" + "-\tlock_page(page);\n" + "-\n" + "-\tif (__is_movable_balloon_page(page)) {\n" + "-\t\t__putback_balloon_page(page);\n" + "-\t\t/* drop the extra ref count taken for page isolation */\n" + "-\t\tput_page(page);\n" + "-\t} else {\n" + "-\t\tWARN_ON(1);\n" + "-\t\tdump_page(page, \"not movable balloon page\");\n" + "-\t}\n" + "-\tunlock_page(page);\n" + "-}\n" + "-\n" + " /* move_to_new_page() counterpart for a ballooned page */\n" + "-int balloon_page_migrate(struct page *newpage,\n" + "-\t\t\t struct page *page, enum migrate_mode mode)\n" + "+int balloon_page_migrate(struct address_space *mapping,\n" + "+\t\tstruct page *newpage, struct page *page,\n" + "+\t\tenum migrate_mode mode)\n" + " {\n" + " \tstruct balloon_dev_info *balloon = balloon_page_device(page);\n" + "-\tint rc = -EAGAIN;\n" + " \n" + " \tVM_BUG_ON_PAGE(!PageLocked(page), page);\n" + " \tVM_BUG_ON_PAGE(!PageLocked(newpage), newpage);\n" + "+\tVM_BUG_ON_PAGE(!PageMovable(page), page);\n" + "+\tVM_BUG_ON_PAGE(!PageIsolated(page), page);\n" + " \n" + "-\tif (WARN_ON(!__is_movable_balloon_page(page))) {\n" + "-\t\tdump_page(page, \"not movable balloon page\");\n" + "-\t\treturn rc;\n" + "-\t}\n" + "-\n" + "-\tif (balloon && balloon->migratepage)\n" + "-\t\trc = balloon->migratepage(balloon, newpage, page, mode);\n" + "-\n" + "-\treturn rc;\n" + "+\treturn balloon->migratepage(balloon, newpage, page, mode);\n" + " }\n" + "+\n" + "+const struct address_space_operations balloon_aops = {\n" + "+\t.migratepage = balloon_page_migrate,\n" + "+\t.isolate_page = balloon_page_isolate,\n" + "+\t.putback_page = balloon_page_putback,\n" + "+};\n" + "+EXPORT_SYMBOL_GPL(balloon_aops);\n" + " #endif /* CONFIG_BALLOON_COMPACTION */\n" + "diff --git a/mm/compaction.c b/mm/compaction.c\n" + "index 7557aedddaee..e336c620fd7b 100644\n" + "--- a/mm/compaction.c\n" + "+++ b/mm/compaction.c\n" + "@@ -708,13 +708,6 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,\n" + " \t\t */\n" + " \t\tis_lru = PageLRU(page);\n" + " \t\tif (!is_lru) {\n" + "-\t\t\tif (unlikely(balloon_page_movable(page))) {\n" + "-\t\t\t\tif (balloon_page_isolate(page)) {\n" + "-\t\t\t\t\t/* Successfully isolated */\n" + "-\t\t\t\t\tgoto isolate_success;\n" + "-\t\t\t\t}\n" + "-\t\t\t}\n" + "-\n" + " \t\t\tif (unlikely(PageMovable(page)) &&\n" + " \t\t\t\t\t!PageIsolated(page)) {\n" + " \t\t\t\tif (locked) {\n" + "diff --git a/mm/migrate.c b/mm/migrate.c\n" + "index ab87ef45a3b9..3234c14ed1cd 100644\n" + "--- a/mm/migrate.c\n" + "+++ b/mm/migrate.c\n" + "@@ -147,8 +147,8 @@ void putback_movable_page(struct page *page)\n" + " * from where they were once taken off for compaction/migration.\n" + " *\n" + " * This function shall be used whenever the isolated pageset has been\n" + "- * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range()\n" + "- * and isolate_huge_page().\n" + "+ * built from lru, movable, hugetlbfs page.\n" + "+ * See isolate_migratepages_range() and isolate_huge_page().\n" + " */\n" + " void putback_movable_pages(struct list_head *l)\n" + " {\n" + "@@ -163,9 +163,7 @@ void putback_movable_pages(struct list_head *l)\n" + " \t\tlist_del(&page->lru);\n" + " \t\tdec_zone_page_state(page, NR_ISOLATED_ANON +\n" + " \t\t\t\tpage_is_file_cache(page));\n" + "-\t\tif (unlikely(isolated_balloon_page(page)))\n" + "-\t\t\tballoon_page_putback(page);\n" + "-\t\telse if (unlikely(PageIsolated(page)))\n" + "+\t\tif (unlikely(PageIsolated(page)))\n" + " \t\t\tputback_movable_page(page);\n" + " \t\telse\n" + " \t\t\tputback_lru_page(page);\n" + "@@ -959,18 +957,6 @@ static int __unmap_and_move(struct page *page, struct page *newpage,\n" + " \tif (unlikely(!trylock_page(newpage)))\n" + " \t\tgoto out_unlock;\n" + " \n" + "-\tif (unlikely(isolated_balloon_page(page))) {\n" + "-\t\t/*\n" + "-\t\t * A ballooned page does not need any special attention from\n" + "-\t\t * physical to virtual reverse mapping procedures.\n" + "-\t\t * Skip any attempt to unmap PTEs or to remap swap cache,\n" + "-\t\t * in order to avoid burning cycles at rmap level, and perform\n" + "-\t\t * the page migration right away (proteced by page lock).\n" + "-\t\t */\n" + "-\t\trc = balloon_page_migrate(newpage, page, mode);\n" + "-\t\tgoto out_unlock_both;\n" + "-\t}\n" + "-\n" + " \t/*\n" + " \t * Corner case handling:\n" + " \t * 1. When a new swap-cache page is read into, it is added to the LRU\n" + "@@ -1015,7 +1001,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage,\n" + " out:\n" + " \t/* If migration is successful, move newpage to right list */\n" + " \tif (rc == MIGRATEPAGE_SUCCESS) {\n" + "-\t\tif (unlikely(__is_movable_balloon_page(newpage)))\n" + "+\t\tif (unlikely(PageMovable(newpage)))\n" + " \t\t\tput_page(newpage);\n" + " \t\telse\n" + " \t\t\tputback_lru_page(newpage);\n" + "diff --git a/mm/vmscan.c b/mm/vmscan.c\n" + "index c72032dbe8db..e5dfa0cf6fdc 100644\n" + "--- a/mm/vmscan.c\n" + "+++ b/mm/vmscan.c\n" + "@@ -1254,7 +1254,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,\n" + " \n" + " \tlist_for_each_entry_safe(page, next, page_list, lru) {\n" + " \t\tif (page_is_file_cache(page) && !PageDirty(page) &&\n" + "-\t\t !isolated_balloon_page(page)) {\n" + "+\t\t !PageIsolated(page)) {\n" + " \t\t\tClearPageActive(page);\n" + " \t\t\tlist_move(&page->lru, &clean_pages);\n" + " \t\t}\n" + "-- \n" + 1.9.1 -de7317a0182877d180f1820ef7c700a0978e56d1dfb3000863771ff665b28a47 +ea655028abc8ff0ea461a95bc0c47d5ecb135933cac55cdb7986faf1b9c5242b
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.