mm/balloon_compaction: ignore anonymous pages
Subsystems (17)
PATCH 1/7 mm/balloon_compaction: ignore anonymous pages
Sasha Levin reported KASAN splash inside isolate_migratepages_range(). Problem is in function __is_movable_balloon_page() which tests AS_BALLOON_MAP in page->mapping->flags. This function has no protection against anonymous pages. As result it tried to check address space flags in inside anon-vma.
--- include/linux/balloon_compaction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/balloon_compaction.h +1 -1
@@ -128,7 +128,7 @@ static inline bool page_flags_cleared(struct page *page)static inline bool __is_movable_balloon_page (struct page *page) {struct address_space *mapping = page->mapping; -return mapping_balloon (mapping); +return !PageAnon (page) &&mapping_balloon (mapping); }/*
PATCH 2/7 mm/balloon_compaction: keep ballooned pages away from normal migration path
Proper testing shows yet another problem in balloon migration: it works only once for each page. balloon_page_movable() check page flags and page_count. In __unmap_and_move page is locked, reference counter is elevated, so balloon_page_movable() _always_ fails here. As result in __unmap_and_move() migration goes to the normal migration path.
Balloon ->migratepage() is so special, it returns MIGRATEPAGE_BALLOON_SUCCESS instead of MIGRATEPAGE_SUCCESS. After that in move_to_new_page() successfully migrated page got NULL into its mapping pointer and loses connectivity with balloon and ability for further migration.
It's safe to use __is_movable_balloon_page here: page is isolated and pinned.
--- mm/migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
@@ -873,7 +873,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, } } -if (unlikely (balloon_page_movable (page))) { +if (unlikely (__is_movable_balloon_page (page))) {/* * A ballooned page does not need any special attention from * physical to virtual reverse mapping procedures.
Re: [PATCH 2/7] mm/balloon_compaction: keep ballooned pages away from normal migration path
Quoted 25 lines · Konstantin Khlebnikov
Proper testing shows yet another problem in balloon migration: it works only once for each page.
balloon_page_movable()check page flags andpage_count. In__unmap_and_movepage is locked, reference counter is elevated, soballoon_page_movable()_always_ fails here. As result in__unmap_and_move()migration goes to the normal migration path.Balloon ->migratepage() is so special, it returns
MIGRATEPAGE_BALLOON_SUCCESSinstead ofMIGRATEPAGE_SUCCESS. After that inmove_to_new_page()successfully migrated page got NULL into its mapping pointer and loses connectivity with balloon and ability for further migration.It's safe to use
__is_movable_balloon_pagehere: page is isolated and pinned.Signed-off-by Konstantin Khlebnikov <[email protected]>Cc stable <[email protected]> # v3.8--- mm/migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)mm/migrate.c +0
-0
mm/migrate.c static int __unmap_and_move(struct page *page, struct page *newpage, · line 879
Quoted 8 lines
mm/migrate.c +1
-1@@ -873,7 +873,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, } } -if (unlikely (balloon_page_movable (page))) { +if (unlikely (__is_movable_balloon_page (page))) {/* * A ballooned page does not need any special attention from * physical to virtual reverse mapping procedures.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/7 mm/balloon_compaction: isolate balloon pages without lru_lock
In reply to Konstantin KhlebnikovLRU-lock isn't required for balloon page isolation. This check makes migration of some ballooned pages mostly impossible because isolate_migratepages_range() drops LRU lock periodically.
--- mm/compaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/compaction.c +1 -1
@@ -597,7 +597,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,*/ if (!PageLRU (page)) {if (unlikely (balloon_page_movable (page))) { -if (locked &&balloon_page_isolate (page)) { +if (balloon_page_isolate (page)) {/* Successfully isolated */ goto isolate_success; }
Re: [PATCH 3/7] mm/balloon_compaction: isolate balloon pages without lru_lock
Quoted 4 lines · Konstantin Khlebnikov
LRU-lock isn't required for balloon page isolation. This check makes migration of some ballooned pages mostly impossible because
isolate_migratepages_range()drops LRU lock periodically.
just for historical/explanatory purposes: https://lkml.org/lkml/2013/12/6/183
Quoted 12 lines
Signed-off-by Konstantin Khlebnikov <[email protected]>Cc stable <[email protected]> # v3.8--- mm/compaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)mm/compaction.c +0
-0
mm/compaction.c isolate_migratepages_range(struct zone *zone, struct compact_control *cc, · line 603
Quoted 8 lines
mm/compaction.c +1
-1@@ -597,7 +597,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,*/ if (!PageLRU (page)) {if (unlikely (balloon_page_movable (page))) { -if (locked &&balloon_page_isolate (page)) { +if (balloon_page_isolate (page)) {/* Successfully isolated */ goto isolate_success; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/7 selftests/vm/transhuge-stress: stress test for memory compaction
In reply to Konstantin KhlebnikovFrom: Konstantin Khlebnikov <[email protected]>
This tool induces memory fragmentation via sequential allocation of transparent huge pages and splitting off everything except their last sub-pages.
--- tools/testing/selftests/vm/Makefile | 1 tools/testing/selftests/vm/transhuge-stress.c | 144 +++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 tools/testing/selftests/vm/transhuge-stress.c
tools/testing/selftests/vm/Makefile +1 -0
@@ -3,6 +3,7 @@ CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest +BINARIES += transhuge-stress all: $(BINARIES) %: %.c
tools/testing/selftests/vm/transhuge-stress.c new file +144 -0
144 lines not on this page · raw message
PATCH 5/7 mm: introduce common page state for ballooned memory
In reply to Konstantin KhlebnikovThis patch adds page state PageBallon() and functions __Set/ClearPageBalloon. Like PageBuddy() PageBalloon() looks like page-flag but actually this is special state of page->_mapcount counter. There is no conflict because ballooned pages cannot be mapped and cannot be in buddy allocator.
Ballooned pages are counted in vmstat counter NR_BALLOON_PAGES, it's shown them in /proc/meminfo and /proc/meminfo. Also this patch it exports PageBallon into userspace via /proc/kpageflags as KPF_BALLOON.
All this code including mm/balloon_compaction.o is under CONFIG_MEMORY_BALLOON, it should be selected by ballooning driver which want use this feature.
--- Documentation/filesystems/proc.txt | 2 ++ drivers/base/node.c | 16 ++++++++++------ drivers/virtio/Kconfig | 1 + fs/proc/meminfo.c | 6 ++++++ fs/proc/page.c | 3 +++ include/linux/mm.h | 10 ++++++++++ include/linux/mmzone.h | 3 +++ include/uapi/linux/kernel-page-flags.h | 1 + mm/Kconfig | 5 +++++ mm/Makefile | 3 ++- mm/balloon_compaction.c | 14 ++++++++++++++ mm/vmstat.c | 8 +++++++- tools/vm/page-types.c | 1 + 13 files changed, 65 insertions(+), 8 deletions(-)
Documentation/filesystems/proc.txt +2 -0
@@ -796,6 +796,7 @@ VmallocTotal: 112216 kB VmallocUsed: 428 kB VmallocChunk: 111088 kB AnonHugePages: 49152 kB +BalloonPages: 0 kB MemTotal: Total usable ram (i.e. physical ram minus a few reserved bits and the kernel binary code)
@@ -838,6 +839,7 @@ MemAvailable: An estimate of how much memory is available for starting new Writeback: Memory which is actively being written back to the disk AnonPages: Non-file backed pages mapped into userspace page tables AnonHugePages: Non-file backed huge pages mapped into userspace page tables +BalloonPages: Memory which was ballooned, not included into MemTotal Mapped: files which have been mmaped, such as libraries Slab: in-kernel data structures cache SReclaimable: Part of Slab, that might be reclaimed, such as caches
drivers/base/node.c +10 -6
@@ -120,6 +120,9 @@ static ssize_t node_read_meminfo(struct device *dev,#ifdef CONFIG_TRANSPARENT_HUGEPAGE "Node %d AnonHugePages: %8lu kB\n"#endif +#ifdef CONFIG_MEMORY_BALLOON +"Node %d BalloonPages: %8lu kB\n" +#endif , nid,K (node_page_state (nid,NR_FILE_DIRTY )), nid, K(node_page_state(nid, NR_WRITEBACK)),
@@ -136,14 +139,15 @@ static ssize_t node_read_meminfo(struct device *dev, nid,K (node_page_state (nid,NR_SLAB_RECLAIMABLE ) +node_page_state (nid,NR_SLAB_UNRECLAIMABLE )), nid,K (node_page_state (nid,NR_SLAB_RECLAIMABLE )), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid,K (node_page_state (nid,NR_SLAB_UNRECLAIMABLE )) - , nid, -K (node_page_state (nid,NR_ANON_TRANSPARENT_HUGEPAGES ) * - HPAGE_PMD_NR)); -#else - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + ,nid,K (node_page_state (nid, +NR_ANON_TRANSPARENT_HUGEPAGES ) *HPAGE_PMD_NR ) +#endif +#ifdef CONFIG_MEMORY_BALLOON + ,nid,K (node_page_state (nid,NR_BALLOON_PAGES )) #endif + ); n +=hugetlb_report_node_meminfo (nid, buf + n);return n; }
drivers/virtio/Kconfig +1 -0
@@ -25,6 +25,7 @@ config VIRTIO_PCI config VIRTIO_BALLOON tristate "Virtio balloon driver" depends on VIRTIO + select MEMORY_BALLOON ---help--- This driver supports increasing and decreasing the amount of memory within a KVM guest.
fs/proc/meminfo.c +6 -0
@@ -138,6 +138,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)#ifdef CONFIG_TRANSPARENT_HUGEPAGE "AnonHugePages: %8lu kB\n"#endif +#ifdef CONFIG_MEMORY_BALLOON +"BalloonPages: %8lu kB\n" +#endif ,K (i.totalram), K(i.freeram),
@@ -193,6 +196,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * HPAGE_PMD_NR)#endif +#ifdef CONFIG_MEMORY_BALLOON + ,K(global_page_state(NR_BALLOON_PAGES)) +#endif );hugetlb_report_meminfo (m);
fs/proc/page.c +3 -0
@@ -133,6 +133,9 @@ u64 stable_page_flags(struct page *page)if (PageBuddy (page)) u |=1 <<KPF_BUDDY ; +if (PageBalloon (page)) + u |=1 <<KPF_BALLOON ; + u |=kpf_copy_bit (k,KPF_LOCKED , PG_locked); u |=kpf_copy_bit (k,KPF_SLAB , PG_slab);
include/linux/mm.h +10 -0
@@ -553,6 +553,16 @@ static inline void __ClearPageBuddy(struct page *page)atomic_set (&page->_mapcount,-1 ); } +#define PAGE_BALLOON_MAPCOUNT_VALUE (-256) + +static inline int PageBalloon (struct page *page) +{ +return IS_ENABLED (CONFIG_MEMORY_BALLOON ) && +atomic_read (&page->_mapcount) ==PAGE_BALLOON_MAPCOUNT_VALUE ; +} +void __SetPageBalloon (struct page *page); +void __ClearPageBalloon (struct page *page); +void put_page (struct page *page);void put_pages_list (struct list_head *pages);
include/linux/mmzone.h +3 -0
@@ -157,6 +157,9 @@ enum zone_stat_item {WORKINGSET_NODERECLAIM ,NR_ANON_TRANSPARENT_HUGEPAGES ,NR_FREE_CMA_PAGES , +#ifdef CONFIG_MEMORY_BALLOON +NR_BALLOON_PAGES , +#endif NR_VM_ZONE_STAT_ITEMS };/*
include/uapi/linux/kernel-page-flags.h +1 -0
@@ -31,6 +31,7 @@#define KPF_KSM 21#define KPF_THP 22 +#define KPF_BALLOON 23#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
mm/Kconfig +5 -0
@@ -228,6 +228,11 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK boolean # +# support for memory ballooning +config MEMORY_BALLOON + boolean + +# # support for memory balloon compaction config BALLOON_COMPACTION bool "Allow for balloon memory compaction/migration"
mm/Makefile +2 -1
@@ -16,7 +16,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ readahead.o swap.o truncate.o vmscan.o shmem.o \ util.o mmzone.o vmstat.o backing-dev.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o balloon_compaction.o vmacache.o \ + compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ iov_iter.o $(mmu-y)
@@ -64,3 +64,4 @@ obj-$(CONFIG_ZBUD) += zbud.o obj-$(CONFIG_ZSMALLOC) += zsmalloc.o obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o obj-$(CONFIG_CMA) += cma.o +obj-$(CONFIG_MEMORY_BALLOON) += balloon_compaction.o
mm/balloon_compaction.c +14 -0
@@ -10,6 +10,20 @@#include <linux/export.h> #include <linux/balloon_compaction.h> +void __SetPageBalloon (struct page *page) +{ +VM_BUG_ON_PAGE (atomic_read (&page->_mapcount) !=-1 , page); +atomic_set (&page->_mapcount,PAGE_BALLOON_MAPCOUNT_VALUE ); +inc_zone_page_state (page,NR_BALLOON_PAGES ); +} + +void __ClearPageBalloon (struct page *page) +{ +VM_BUG_ON_PAGE (!PageBalloon (page), page); +atomic_set (&page->_mapcount,-1 ); +dec_zone_page_state (page,NR_BALLOON_PAGES ); +} +/* * balloon_devinfo_alloc - allocates a balloon device information descriptor. * @balloon_dev_descriptor: pointer to reference the balloon device which
mm/vmstat.c +7 -1
@@ -735,7 +735,7 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat, TEXT_FOR_HIGHMEM(xx) xx "_movable",const char *const vmstat_text[] = { -/* Zoned VM counters */ +/* enum zone_stat_item countes */ "nr_free_pages" ,"nr_alloc_batch" ,"nr_inactive_anon" ,
@@ -778,10 +778,16 @@ const char * const vmstat_text[] = {"workingset_nodereclaim" ,"nr_anon_transparent_hugepages" ,"nr_free_cma" , +#ifdef CONFIG_MEMORY_BALLOON +"nr_balloon_pages" , +#endif + +/* enum writeback_stat_item counters */ "nr_dirty_threshold" ,"nr_dirty_background_threshold" , #ifdef CONFIG_VM_EVENT_COUNTERS +/* enum vm_event_item counters */ "pgpgin" ,"pgpgout" , "pswpin",
tools/vm/page-types.c +1 -0
@@ -132,6 +132,7 @@ static const char * const page_flag_names[] = { [KPF_NOPAGE] = "n:nopage", [KPF_KSM] = "x:ksm", [KPF_THP] = "t:thp", + [KPF_BALLOON] = "o:balloon", [KPF_RESERVED] = "r:reserved", [KPF_MLOCKED] = "m:mlocked",
Re: [PATCH 5/7] mm: introduce common page state for ballooned memory
Quoted 5 lines · Konstantin Khlebnikov
This patch adds page state
PageBallon()and functions __Set/ClearPageBalloon. LikePageBuddy()PageBalloon()looks like page-flag but actually this is special state ofpage->_mapcountcounter. There is no conflict because ballooned pages cannot be mapped and cannot be in buddy allocator.
Quoted 7 lines
Ballooned pages are counted in vmstat counter
NR_BALLOON_PAGES, it's shown them in/proc/meminfoand/proc/meminfo. Also this patch it exports PageBallon into userspace via/proc/kpageflagsasKPF_BALLOON.All this code including
mm/balloon_compaction.ois underCONFIG_MEMORY_BALLOON, it should be selected by ballooning driver which want use this feature.
Very nice overhaul Konstantin!
Please, consider the nits I have below:
Quoted 131 lines
Signed-off-by Konstantin Khlebnikov <[email protected]>--- Documentation/filesystems/proc.txt | 2 ++ drivers/base/node.c | 16 ++++++++++------ drivers/virtio/Kconfig | 1 + fs/proc/meminfo.c | 6 ++++++ fs/proc/page.c | 3 +++ include/linux/mm.h | 10 ++++++++++ include/linux/mmzone.h | 3 +++ include/uapi/linux/kernel-page-flags.h | 1 + mm/Kconfig | 5 +++++ mm/Makefile | 3 ++- mm/balloon_compaction.c | 14 ++++++++++++++ mm/vmstat.c | 8 +++++++- tools/vm/page-types.c | 1 + 13 files changed, 65 insertions(+), 8 deletions(-)Documentation/filesystems/proc.txt +2
-0@@ -796,6 +796,7 @@ VmallocTotal: 112216 kB VmallocUsed: 428 kB VmallocChunk: 111088 kB AnonHugePages: 49152 kB +BalloonPages: 0 kB MemTotal: Total usable ram (i.e. physical ram minus a few reserved bits and the kernel binary code)@@ -838,6 +839,7 @@ MemAvailable: An estimate of how much memory is available for starting new Writeback: Memory which is actively being written back to the disk AnonPages: Non-file backed pages mapped into userspace page tables AnonHugePages: Non-file backed huge pages mapped into userspace page tables +BalloonPages: Memory which was ballooned, not included into MemTotal Mapped: files which have been mmaped, such as libraries Slab: in-kernel data structures cache SReclaimable: Part of Slab, that might be reclaimed, such as cachesdrivers/base/node.c +10
-6@@ -120,6 +120,9 @@ static ssize_t node_read_meminfo(struct device *dev,#ifdef CONFIG_TRANSPARENT_HUGEPAGE "Node %d AnonHugePages: %8lu kB\n"#endif +#ifdef CONFIG_MEMORY_BALLOON +"Node %d BalloonPages: %8lu kB\n" +#endif , nid,K (node_page_state (nid,NR_FILE_DIRTY )), nid, K(node_page_state(nid, NR_WRITEBACK)),@@ -136,14 +139,15 @@ static ssize_t node_read_meminfo(struct device *dev, nid,K (node_page_state (nid,NR_SLAB_RECLAIMABLE ) +node_page_state (nid,NR_SLAB_UNRECLAIMABLE )), nid,K (node_page_state (nid,NR_SLAB_RECLAIMABLE )), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid,K (node_page_state (nid,NR_SLAB_UNRECLAIMABLE )) - , nid, -K (node_page_state (nid,NR_ANON_TRANSPARENT_HUGEPAGES ) * - HPAGE_PMD_NR)); -#else - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + ,nid,K (node_page_state (nid, +NR_ANON_TRANSPARENT_HUGEPAGES ) *HPAGE_PMD_NR ) +#endif +#ifdef CONFIG_MEMORY_BALLOON + ,nid,K (node_page_state (nid,NR_BALLOON_PAGES )) #endif + ); n +=hugetlb_report_node_meminfo (nid, buf + n);return n; }drivers/virtio/Kconfig +1
-0@@ -25,6 +25,7 @@ config VIRTIO_PCI config VIRTIO_BALLOON tristate "Virtio balloon driver" depends on VIRTIO + select MEMORY_BALLOON ---help--- This driver supports increasing and decreasing the amount of memory within a KVM guest.fs/proc/meminfo.c +6
-0@@ -138,6 +138,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)#ifdef CONFIG_TRANSPARENT_HUGEPAGE "AnonHugePages: %8lu kB\n"#endif +#ifdef CONFIG_MEMORY_BALLOON +"BalloonPages: %8lu kB\n" +#endif ,K (i.totalram), K(i.freeram),@@ -193,6 +196,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * HPAGE_PMD_NR)#endif +#ifdef CONFIG_MEMORY_BALLOON + ,K(global_page_state(NR_BALLOON_PAGES)) +#endif );hugetlb_report_meminfo (m);fs/proc/page.c +3
-0@@ -133,6 +133,9 @@ u64 stable_page_flags(struct page *page)if (PageBuddy (page)) u |=1 <<KPF_BUDDY ; +if (PageBalloon (page)) + u |=1 <<KPF_BALLOON ; + u |=kpf_copy_bit (k,KPF_LOCKED , PG_locked); u |=kpf_copy_bit (k,KPF_SLAB , PG_slab);include/linux/mm.h +0
-0@@ -553,6 +553,16 @@ static inline void __ClearPageBuddy(struct page *page)atomic_set (&page->_mapcount,-1 ); }
include/linux/mm.h static inline void __ClearPageBuddy(struct page *page) · line 565
Quoted 10 lines
include/linux/mm.h +10
-0+#define PAGE_BALLOON_MAPCOUNT_VALUE (-256) + +static inline int PageBalloon (struct page *page) +{ +return IS_ENABLED (CONFIG_MEMORY_BALLOON ) && +atomic_read (&page->_mapcount) ==PAGE_BALLOON_MAPCOUNT_VALUE ; +} +void __SetPageBalloon (struct page *page); +void __ClearPageBalloon (struct page *page); +
1) I think you should consider the following here:
-void __SetPageBalloon(struct page *page);
-void __ClearPageBalloon(struct page *page);
+
+static inline void __SetPageBalloon(struct page *page) +{
+#ifdef CONFIG_MEMORY_BALLOON
+ VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);
+ atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE);
+#endif
+}
+
+static inline void __ClearPageBalloon(struct page *page) +{
+#ifdef CONFIG_MEMORY_BALLOON
+ VM_BUG_ON_PAGE(!PageBalloon(page), page);
+ atomic_set(&page->_mapcount, -1);
+#endif
+}
Quoted 75 lines
include/linux/mm.h +0
-0void put_page (struct page *page);void put_pages_list (struct list_head *pages);include/linux/mmzone.h +3
-0@@ -157,6 +157,9 @@ enum zone_stat_item {WORKINGSET_NODERECLAIM ,NR_ANON_TRANSPARENT_HUGEPAGES ,NR_FREE_CMA_PAGES , +#ifdef CONFIG_MEMORY_BALLOON +NR_BALLOON_PAGES , +#endif NR_VM_ZONE_STAT_ITEMS };/* include/uapi/linux/kernel-page-flags.h +1
-0@@ -31,6 +31,7 @@#define KPF_KSM 21#define KPF_THP 22 +#define KPF_BALLOON 23#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */ mm/Kconfig +5
-0@@ -228,6 +228,11 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK boolean # +# support for memory ballooning +config MEMORY_BALLOON + boolean + +# # support for memory balloon compaction config BALLOON_COMPACTION bool "Allow for balloon memory compaction/migration"mm/Makefile +2
-1@@ -16,7 +16,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ readahead.o swap.o truncate.o vmscan.o shmem.o \ util.o mmzone.o vmstat.o backing-dev.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o balloon_compaction.o vmacache.o \ + compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ iov_iter.o $(mmu-y)@@ -64,3 +64,4 @@ obj-$(CONFIG_ZBUD) += zbud.o obj-$(CONFIG_ZSMALLOC) += zsmalloc.o obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o obj-$(CONFIG_CMA) += cma.o +obj-$(CONFIG_MEMORY_BALLOON) += balloon_compaction.omm/balloon_compaction.c +4
-0@@ -10,6 +10,20 @@#include <linux/export.h> #include <linux/balloon_compaction.h> +void __SetPageBalloon (struct page *page) +{ +VM_BUG_ON_PAGE (atomic_read (&page->_mapcount) !=-1 , page); +atomic_set (&page->_mapcount,PAGE_BALLOON_MAPCOUNT_VALUE );
mm/balloon_compaction.c line 26
Quoted 10 lines
mm/balloon_compaction.c +10
-0+inc_zone_page_state (page,NR_BALLOON_PAGES ); +} + +void __ClearPageBalloon (struct page *page) +{ +VM_BUG_ON_PAGE (!PageBalloon (page), page); +atomic_set (&page->_mapcount,-1 ); +dec_zone_page_state (page,NR_BALLOON_PAGES ); +} +
and if you go with (1), here:
-void __SetPageBalloon(struct page *page)
-{
- VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page); - atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE); - inc_zone_page_state(page, NR_BALLOON_PAGES);
-}
-
-void __ClearPageBalloon(struct page *page)
-{
- VM_BUG_ON_PAGE(!PageBalloon(page), page); - atomic_set(&page->_mapcount, -1); - dec_zone_page_state(page, NR_BALLOON_PAGES);
-}
Quoted 39 lines
mm/balloon_compaction.c +0
-0/* * balloon_devinfo_alloc - allocates a balloon device information descriptor. * @balloon_dev_descriptor: pointer to reference the balloon device which mm/vmstat.c +7
-1@@ -735,7 +735,7 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat, TEXT_FOR_HIGHMEM(xx) xx "_movable",const char *const vmstat_text[] = { -/* Zoned VM counters */ +/* enum zone_stat_item countes */ "nr_free_pages" ,"nr_alloc_batch" ,"nr_inactive_anon" ,@@ -778,10 +778,16 @@ const char * const vmstat_text[] = {"workingset_nodereclaim" ,"nr_anon_transparent_hugepages" ,"nr_free_cma" , +#ifdef CONFIG_MEMORY_BALLOON +"nr_balloon_pages" , +#endif + +/* enum writeback_stat_item counters */ "nr_dirty_threshold" ,"nr_dirty_background_threshold" , #ifdef CONFIG_VM_EVENT_COUNTERS +/* enum vm_event_item counters */ "pgpgin" ,"pgpgout" , "pswpin",tools/vm/page-types.c +0
-0
tools/vm/page-types.c static const char * const page_flag_names[] = { · line 138
Quoted 7 lines
tools/vm/page-types.c +1
-0@@ -132,6 +132,7 @@ static const char * const page_flag_names[] = { [KPF_NOPAGE] = "n:nopage", [KPF_KSM] = "x:ksm", [KPF_THP] = "t:thp", + [KPF_BALLOON] = "o:balloon", [KPF_RESERVED] = "r:reserved", [KPF_MLOCKED] = "m:mlocked",
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/7 mm/balloon_compaction: use common page ballooning
In reply to Konstantin KhlebnikovThis patch replaces checking AS_BALLOON_MAP in page->mapping->flags with PageBalloon which is stored directly in the struct page.
--- include/linux/balloon_compaction.h | 85 ++---------------------------------- mm/Kconfig | 2 - mm/balloon_compaction.c | 7 +-- mm/compaction.c | 9 ++-- mm/migrate.c | 4 +- mm/vmscan.c | 2 - 6 files changed, 15 insertions(+), 94 deletions(-)
include/linux/balloon_compaction.h +4 -81
@@ -108,77 +108,6 @@ static inline void balloon_mapping_free(struct address_space *balloon_mapping) }/* -* page_flags_cleared - helper to perform balloon @page ->flags tests. -* -* As balloon pages are obtained from buddy and we do not play with page->flags -* at driver level (exception made when we get the page lock for compaction), -* we can safely identify a ballooned page by checking if the -* PAGE_FLAGS_CHECK_AT_PREP page->flags are all cleared. This approach also -* helps us skip ballooned pages that are locked for compaction or release, thus -* mitigating their racy check at balloon_page_movable() -*/ -static inline bool page_flags_cleared (struct page *page) -{ -return !(page->flags &PAGE_FLAGS_CHECK_AT_PREP ); -} - -/* -* __is_movable_balloon_page - helper to perform @page mapping->flags tests -*/ -static inline bool __is_movable_balloon_page (struct page *page) -{ -struct address_space *mapping = page->mapping; -return !PageAnon (page) &&mapping_balloon (mapping); -} - -/* -* balloon_page_movable - test page->mapping->flags to identify balloon pages -* that can be moved by compaction/migration. -* -* This function is used at core compaction's page isolation scheme, therefore -* most pages exposed to it are not enlisted as balloon pages and so, to avoid -* undesired side effects like racing against __free_pages(), we cannot afford -* holding the page locked while testing page->mapping->flags here. -* -* As we might return false positives in the case of a balloon page being just -* released under us, the page->mapping->flags need to be re-tested later, -* under the proper page lock, at the functions that will be coping with the -* balloon page case. -*/ -static inline bool balloon_page_movable (struct page *page) -{ -/* -* Before dereferencing and testing mapping->flags, let's make sure -* this is not a page that uses ->mapping in a different way -*/ -if (page_flags_cleared (page) && !page_mapped (page) && -page_count (page) ==1 ) -return __is_movable_balloon_page (page); - -return false; -} - -/* -* isolated_balloon_page - identify an isolated balloon page on private -* compaction/migration page lists. -* -* After a compaction thread isolates a balloon page for migration, it raises -* the page refcount to prevent concurrent compaction threads from re-isolating -* the same page. For that reason putback_movable_pages(), or other routines -* that need to identify isolated balloon pages on private pagelists, cannot -* rely on balloon_page_movable() to accomplish the task. -*/ -static inline bool isolated_balloon_page (struct page *page) -{ -/* Already isolated balloon pages, by default, have a raised refcount */ -if (page_flags_cleared (page) && !page_mapped (page) && -page_count (page) >=2 ) -return __is_movable_balloon_page (page); - -return false; -} - -/* * balloon_page_insert - insert a page into the balloon's page list and make * the page->mapping assignment accordingly. * @page : page to be assigned as a 'balloon page'
@@ -192,6 +121,7 @@ static inline void balloon_page_insert(struct page *page,struct address_space *mapping, struct list_head *head) { +__SetPageBalloon (page ); page->mapping = mapping;list_add (&page->lru, head); }
@@ -206,6 +136,7 @@ static inline void balloon_page_insert(struct page *page,*/ static inline void balloon_page_delete (struct page *page) { +__ClearPageBalloon (page); page->mapping =NULL ;list_del (&page->lru); }
@@ -250,24 +181,16 @@ static inline void balloon_page_insert(struct page *page,struct address_space *mapping, struct list_head *head) { +__SetPageBalloon (page );list_add (&page->lru, head); }static inline void balloon_page_delete (struct page *page) { +__ClearPageBalloon (page);list_del (&page->lru); } -static inline bool balloon_page_movable (struct page *page) -{ -return false; -} - -static inline bool isolated_balloon_page (struct page *page) -{ -return false; -} -static inline bool balloon_page_isolate (struct page *page) {return false;
mm/Kconfig +1 -1
@@ -237,7 +237,7 @@ config MEMORY_BALLOON config BALLOON_COMPACTION bool "Allow for balloon memory compaction/migration" def_bool y - depends on COMPACTION && VIRTIO_BALLOON + depends on COMPACTION && MEMORY_BALLOON help Memory fragmentation introduced by ballooning might reduce significantly the number of 2MB contiguous memory blocks that can be
mm/balloon_compaction.c +3 -4
@@ -253,8 +253,7 @@ bool balloon_page_isolate(struct page *page)* Prevent concurrent compaction threads from isolating * an already isolated balloon page by refcount check. */ -if (__is_movable_balloon_page (page) && -page_count (page) ==2 ) { +if (PageBalloon (page) &&page_count (page) ==2 ) {__isolate_balloon_page (page);unlock_page (page);return true;
@@ -275,7 +274,7 @@ void balloon_page_putback(struct page *page)*/ lock_page (page); -if (__is_movable_balloon_page (page)) { +if (PageBalloon (page)) {__putback_balloon_page (page);/* drop the extra ref count taken for page isolation */ put_page (page);
@@ -300,7 +299,7 @@ int balloon_page_migrate(struct page *newpage,*/ BUG_ON (!trylock_page (newpage)); -if (WARN_ON (!__is_movable_balloon_page (page))) { +if (WARN_ON (!PageBalloon (page))) {dump_page (page,"not movable balloon page" );unlock_page (newpage);return rc;
mm/compaction.c +4 -5
@@ -596,11 +596,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,* Skip any other type of page */ if (!PageLRU (page)) { -if (unlikely (balloon_page_movable (page))) { -if (balloon_page_isolate (page)) { -/* Successfully isolated */ - goto isolate_success; - } +if (unlikely (PageBalloon (page)) && +balloon_page_isolate (page)) { +/* Successfully isolated */ + goto isolate_success; }continue ; }
mm/migrate.c +2 -2
@@ -92,7 +92,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))) +if (unlikely (PageBalloon (page)))balloon_page_putback (page);else putback_lru_page (page);
@@ -873,7 +873,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, } } -if (unlikely (__is_movable_balloon_page (page))) { +if (unlikely (PageBalloon (page))) {/* * A ballooned page does not need any special attention from * physical to virtual reverse mapping procedures.
mm/vmscan.c +1 -1
@@ -1160,7 +1160,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)) { + !PageBalloon (page)) {ClearPageActive (page);list_move (&page->lru, &clean_pages); }
Re: [PATCH 6/7] mm/balloon_compaction: use common page ballooning
Quoted 231 lines · Konstantin Khlebnikov
This patch replaces checking
AS_BALLOON_MAPinpage->mapping->flagswith PageBalloon which is stored directly in the struct page.Signed-off-by Konstantin Khlebnikov <[email protected]>--- include/linux/balloon_compaction.h | 85 ++---------------------------------- mm/Kconfig | 2 - mm/balloon_compaction.c | 7 +-- mm/compaction.c | 9 ++-- mm/migrate.c | 4 +- mm/vmscan.c | 2 - 6 files changed, 15 insertions(+), 94 deletions(-)include/linux/balloon_compaction.h +4
-81@@ -108,77 +108,6 @@ static inline void balloon_mapping_free(struct address_space *balloon_mapping) }/* -* page_flags_cleared - helper to perform balloon @page ->flags tests. -* -* As balloon pages are obtained from buddy and we do not play with page->flags -* at driver level (exception made when we get the page lock for compaction), -* we can safely identify a ballooned page by checking if the -* PAGE_FLAGS_CHECK_AT_PREP page->flags are all cleared. This approach also -* helps us skip ballooned pages that are locked for compaction or release, thus -* mitigating their racy check at balloon_page_movable() -*/ -static inline bool page_flags_cleared (struct page *page) -{ -return !(page->flags &PAGE_FLAGS_CHECK_AT_PREP ); -} - -/* -* __is_movable_balloon_page - helper to perform @page mapping->flags tests -*/ -static inline bool __is_movable_balloon_page (struct page *page) -{ -struct address_space *mapping = page->mapping; -return !PageAnon (page) &&mapping_balloon (mapping); -} - -/* -* balloon_page_movable - test page->mapping->flags to identify balloon pages -* that can be moved by compaction/migration. -* -* This function is used at core compaction's page isolation scheme, therefore -* most pages exposed to it are not enlisted as balloon pages and so, to avoid -* undesired side effects like racing against __free_pages(), we cannot afford -* holding the page locked while testing page->mapping->flags here. -* -* As we might return false positives in the case of a balloon page being just -* released under us, the page->mapping->flags need to be re-tested later, -* under the proper page lock, at the functions that will be coping with the -* balloon page case. -*/ -static inline bool balloon_page_movable (struct page *page) -{ -/* -* Before dereferencing and testing mapping->flags, let's make sure -* this is not a page that uses ->mapping in a different way -*/ -if (page_flags_cleared (page) && !page_mapped (page) && -page_count (page) ==1 ) -return __is_movable_balloon_page (page); - -return false; -} - -/* -* isolated_balloon_page - identify an isolated balloon page on private -* compaction/migration page lists. -* -* After a compaction thread isolates a balloon page for migration, it raises -* the page refcount to prevent concurrent compaction threads from re-isolating -* the same page. For that reason putback_movable_pages(), or other routines -* that need to identify isolated balloon pages on private pagelists, cannot -* rely on balloon_page_movable() to accomplish the task. -*/ -static inline bool isolated_balloon_page (struct page *page) -{ -/* Already isolated balloon pages, by default, have a raised refcount */ -if (page_flags_cleared (page) && !page_mapped (page) && -page_count (page) >=2 ) -return __is_movable_balloon_page (page); - -return false; -} - -/* * balloon_page_insert - insert a page into the balloon's page list and make * the page->mapping assignment accordingly. * @page : page to be assigned as a 'balloon page' @@ -192,6 +121,7 @@ static inline void balloon_page_insert(struct page *page,struct address_space *mapping, struct list_head *head) { +__SetPageBalloon (page ); page->mapping = mapping;list_add (&page->lru, head); }@@ -206,6 +136,7 @@ static inline void balloon_page_insert(struct page *page,*/ static inline void balloon_page_delete (struct page *page) { +__ClearPageBalloon (page); page->mapping =NULL ;list_del (&page->lru); }@@ -250,24 +181,16 @@ static inline void balloon_page_insert(struct page *page,struct address_space *mapping, struct list_head *head) { +__SetPageBalloon (page );list_add (&page->lru, head); }static inline void balloon_page_delete (struct page *page) { +__ClearPageBalloon (page);list_del (&page->lru); } -static inline bool balloon_page_movable (struct page *page) -{ -return false; -} - -static inline bool isolated_balloon_page (struct page *page) -{ -return false; -} -static inline bool balloon_page_isolate (struct page *page) {return false;mm/Kconfig +1
-1@@ -237,7 +237,7 @@ config MEMORY_BALLOON config BALLOON_COMPACTION bool "Allow for balloon memory compaction/migration" def_bool y - depends on COMPACTION && VIRTIO_BALLOON + depends on COMPACTION && MEMORY_BALLOON help Memory fragmentation introduced by ballooning might reduce significantly the number of 2MB contiguous memory blocks that can bemm/balloon_compaction.c +3
-4@@ -253,8 +253,7 @@ bool balloon_page_isolate(struct page *page)* Prevent concurrent compaction threads from isolating * an already isolated balloon page by refcount check. */ -if (__is_movable_balloon_page (page) && -page_count (page) ==2 ) { +if (PageBalloon (page) &&page_count (page) ==2 ) {__isolate_balloon_page (page);unlock_page (page);return true;@@ -275,7 +274,7 @@ void balloon_page_putback(struct page *page)*/ lock_page (page); -if (__is_movable_balloon_page (page)) { +if (PageBalloon (page)) {__putback_balloon_page (page);/* drop the extra ref count taken for page isolation */ put_page (page);@@ -300,7 +299,7 @@ int balloon_page_migrate(struct page *newpage,*/ BUG_ON (!trylock_page (newpage)); -if (WARN_ON (!__is_movable_balloon_page (page))) { +if (WARN_ON (!PageBalloon (page))) {dump_page (page,"not movable balloon page" );unlock_page (newpage);return rc;mm/compaction.c +4
-5@@ -596,11 +596,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,* Skip any other type of page */ if (!PageLRU (page)) { -if (unlikely (balloon_page_movable (page))) { -if (balloon_page_isolate (page)) { -/* Successfully isolated */ - goto isolate_success; - } +if (unlikely (PageBalloon (page)) && +balloon_page_isolate (page)) { +/* Successfully isolated */ + goto isolate_success; }continue ; }mm/migrate.c +2
-2@@ -92,7 +92,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))) +if (unlikely (PageBalloon (page)))balloon_page_putback (page);else putback_lru_page (page);@@ -873,7 +873,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, } } -if (unlikely (__is_movable_balloon_page (page))) { +if (unlikely (PageBalloon (page))) {/* * A ballooned page does not need any special attention from * physical to virtual reverse mapping procedures. mm/vmscan.c +0
-0
mm/vmscan.c unsigned long reclaim_clean_pages_from_list(struct zone *zone, · line 1166
Quoted 8 lines
mm/vmscan.c +1
-1@@ -1160,7 +1160,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)) { + !PageBalloon (page)) {ClearPageActive (page);list_move (&page->lru, &clean_pages); }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/7 mm/balloon_compaction: general cleanup
In reply to Konstantin Khlebnikov* move special branch for balloon migraion into migrate_pages
* remove special mapping for balloon and its flag AS_BALLOON_MAP
* embed struct balloon_dev_info into struct virtio_balloon
* cleanup balloon_page_dequeue, kill balloon_page_free
--- drivers/virtio/virtio_balloon.c | 77 ++++--------- include/linux/balloon_compaction.h | 107 ++++++------------ include/linux/migrate.h | 11 -- include/linux/pagemap.h | 18 --- mm/balloon_compaction.c | 214 ++++++++++++------------------------ mm/migrate.c | 27 +---- 6 files changed, 130 insertions(+), 324 deletions(-)
drivers/virtio/virtio_balloon.c +21 -56
@@ -59,7 +59,7 @@ struct virtio_balloon* Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE * to num_pages above. */ -struct balloon_dev_info *vb_dev_info; +struct balloon_dev_info vb_dev_info;/* Synchronize access/update to this struct virtio_balloon elements */ struct mutex balloon_lock;
@@ -127,7 +127,7 @@ static void set_page_pfns(u32 pfns[], struct page *page)static void fill_balloon (struct virtio_balloon *vb,size_t num) { -struct balloon_dev_info *vb_dev_info = vb->vb_dev_info; +struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info;/* We can only do one array worth at a time. */ num =min (num,ARRAY_SIZE (vb->pfns));
@@ -163,15 +163,15 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)/* Find pfns pointing at start of each page, get pages and free them. */ for (i =0 ; i < num; i +=VIRTIO_BALLOON_PAGES_PER_PAGE ) {struct page *page =balloon_pfn_to_page (pfns[i]); -balloon_page_free (page);adjust_managed_page_count (page,1 ); +put_page (page); } }static void leak_balloon (struct virtio_balloon *vb,size_t num) {struct page *page; -struct balloon_dev_info *vb_dev_info = vb->vb_dev_info; +struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info;/* We can only do one array worth at a time. */ num =min (num,ARRAY_SIZE (vb->pfns));
@@ -353,12 +353,11 @@ static int init_vqs(struct virtio_balloon *vb)return 0 ; } -static const struct address_space_operations virtio_balloon_aops;#ifdef CONFIG_BALLOON_COMPACTION /* * virtballoon_migratepage - perform the balloon page migration on behalf of * a compation thread. (called under page lock) -* @mapping: the page->mapping which will be assigned to the new migrated page. +* @vb_dev_info: the balloon device * @newpage: page that will replace the isolated page after migration finishes. * @page : the isolated (old) page that is about to be migrated to newpage. * @mode : compaction mode -- not used for balloon page migration.
@@ -373,17 +372,13 @@ static const struct address_space_operations virtio_balloon_aops;* This function preforms the balloon page migration task. * Called through balloon_mapping->a_ops->migratepage */ -static int virtballoon_migratepage (struct address_space *mapping, +static int virtballoon_migratepage (struct balloon_dev_info *vb_dev_info,struct page *newpage,struct page *page,enum migrate_mode mode) { -struct balloon_dev_info *vb_dev_info =balloon_page_device (page); -struct virtio_balloon *vb; +struct virtio_balloon *vb =container_of (vb_dev_info, + struct virtio_balloon, vb_dev_info);unsigned long flags; -BUG_ON (!vb_dev_info); - - vb = vb_dev_info->balloon_device; -/* * In order to avoid lock contention while migrating pages concurrently * to leak_balloon() or fill_balloon() we just give up the balloon_lock
@@ -395,42 +390,34 @@ static int virtballoon_migratepage(struct address_space *mapping,if (!mutex_trylock (&vb->balloon_lock))return -EAGAIN ; +get_page (newpage);/* balloon reference */ +/* balloon's page migration 1st step -- inflate "newpage" */ spin_lock_irqsave (&vb_dev_info->pages_lock, flags); -balloon_page_insert (newpage, mapping, &vb_dev_info->pages); +balloon_page_insert (vb_dev_info, newpage); vb_dev_info->isolated_pages--;spin_unlock_irqrestore (&vb_dev_info->pages_lock, flags); vb->num_pfns =VIRTIO_BALLOON_PAGES_PER_PAGE ;set_page_pfns (vb->pfns, newpage);tell_host (vb, vb->inflate_vq); -/* -* balloon's page migration 2nd step -- deflate "page" -* -* It's safe to delete page->lru here because this page is at -* an isolated migration list, and this step is expected to happen here -*/ -balloon_page_delete (page); +/* balloon's page migration 2nd step -- deflate "page" */ +balloon_page_delete (page, true); vb->num_pfns =VIRTIO_BALLOON_PAGES_PER_PAGE ;set_page_pfns (vb->pfns, page);tell_host (vb, vb->deflate_vq);mutex_unlock (&vb->balloon_lock); - return MIGRATEPAGE_BALLOON_SUCCESS; -} +put_page (page);/* balloon reference */ -/* define the balloon_mapping->a_ops callback to allow balloon page migration */ -static const struct address_space_operations virtio_balloon_aops = { - .migratepage = virtballoon_migratepage, -}; + return MIGRATEPAGE_SUCCESS; +}#endif /* CONFIG_BALLOON_COMPACTION */ static int virtballoon_probe (struct virtio_device *vdev) {struct virtio_balloon *vb; -struct address_space *vb_mapping; -struct balloon_dev_info *vb_devinfo;int err; vdev->priv = vb =kmalloc (sizeof (*vb),GFP_KERNEL );
@@ -446,30 +433,14 @@ static int virtballoon_probe(struct virtio_device *vdev) vb->vdev = vdev; vb->need_stats_update =0 ; - vb_devinfo =balloon_devinfo_alloc (vb); -if (IS_ERR (vb_devinfo)) { - err =PTR_ERR (vb_devinfo); - goto out_free_vb; - } - - vb_mapping =balloon_mapping_alloc (vb_devinfo, - (balloon_compaction_check ()) ? - &virtio_balloon_aops :NULL ); -if (IS_ERR (vb_mapping)) { -/* -* IS_ERR(vb_mapping) && PTR_ERR(vb_mapping) == -EOPNOTSUPP -* This means !CONFIG_BALLOON_COMPACTION, otherwise we get off. -*/ - err =PTR_ERR (vb_mapping); -if (err != -EOPNOTSUPP ) - goto out_free_vb_devinfo; - } - - vb->vb_dev_info = vb_devinfo; +balloon_devinfo_init (&vb->vb_dev_info); +#ifdef CONFIG_BALLOON_COMPACTION + vb->vb_dev_info.migrate_page = virtballoon_migratepage; +#endif err =init_vqs (vb);if (err) - goto out_free_vb_mapping; + goto out_free_vb; vb->thread =kthread_run (balloon, vb,"vballoon" );if (IS_ERR (vb->thread)) {
@@ -481,10 +452,6 @@ static int virtballoon_probe(struct virtio_device *vdev) out_del_vqs: vdev->config->del_vqs (vdev); -out_free_vb_mapping: -balloon_mapping_free (vb_mapping); -out_free_vb_devinfo: -balloon_devinfo_free (vb_devinfo); out_free_vb:kfree (vb); out:
@@ -510,8 +477,6 @@ static void virtballoon_remove(struct virtio_device *vdev)kthread_stop (vb->thread);remove_common (vb); -balloon_mapping_free (vb->vb_dev_info->mapping); -balloon_devinfo_free (vb->vb_dev_info);kfree (vb); }
include/linux/balloon_compaction.h +34 -73
178 lines not on this page · raw message
include/linux/migrate.h +1 -10
@@ -13,18 +13,9 @@ typedef void free_page_t(struct page *page, unsigned long private);* Return values from addresss_space_operations.migratepage(): * - negative errno on page migration failure; * - zero on page migration success; -* -* The balloon page migration introduces this special case where a 'distinct' -* return code is used to flag a successful page migration to unmap_and_move(). -* This approach is necessary because page migration can race against balloon -* deflation procedure, and for such case we could introduce a nasty page leak -* if a successfully migrated balloon page gets released concurrently with -* migration's unmap_and_move() wrap-up steps. */ #define MIGRATEPAGE_SUCCESS 0 -#define MIGRATEPAGE_BALLOON_SUCCESS 1/* special ret code for balloon page -* sucessful migration case. -*/ +enum migrate_reason {MR_COMPACTION ,MR_MEMORY_FAILURE ,
include/linux/pagemap.h +1 -17
@@ -24,8 +24,7 @@ enum mapping_flags {AS_ENOSPC = __GFP_BITS_SHIFT +1 ,/* ENOSPC on async write */ AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT +2 ,/* under mm_take_all_locks() */ AS_UNEVICTABLE = __GFP_BITS_SHIFT +3 ,/* e.g., ramdisk, SHM_LOCK */ -AS_BALLOON_MAP = __GFP_BITS_SHIFT +4 ,/* balloon page special map */ - AS_EXITING = __GFP_BITS_SHIFT + 5, /* final truncate in progress */ + AS_EXITING = __GFP_BITS_SHIFT + 4, /* final truncate in progress */ };static inline void mapping_set_error (struct address_space *mapping,int error)
@@ -55,21 +54,6 @@ static inline int mapping_unevictable(struct address_space *mapping)return !!mapping; } -static inline void mapping_set_balloon (struct address_space *mapping) -{ -set_bit (AS_BALLOON_MAP , &mapping->flags); -} - -static inline void mapping_clear_balloon (struct address_space *mapping) -{ -clear_bit (AS_BALLOON_MAP , &mapping->flags); -} - -static inline int mapping_balloon (struct address_space *mapping) -{ -return mapping &&test_bit (AS_BALLOON_MAP , &mapping->flags); -} -static inline void mapping_set_exiting (struct address_space *mapping) {set_bit (AS_EXITING , &mapping->flags);
mm/balloon_compaction.c +69 -145
274 lines not on this page · raw message
mm/migrate.c +4 -23
@@ -873,18 +873,6 @@ static int __unmap_and_move(struct page *page, struct page *newpage, } } -if (unlikely (PageBalloon (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; - } -/* * Corner case handling: * 1. When a new swap-cache page is read into, it is added to the LRU
@@ -952,17 +940,6 @@ static int unmap_and_move(new_page_t get_new_page, free_page_t put_new_page, rc =__unmap_and_move (page, newpage, force, mode); -if (unlikely (rc ==MIGRATEPAGE_BALLOON_SUCCESS )) { -/* -* A ballooned page has been migrated already. -* Now, it's the time to wrap-up counters, -* handle the page back to Buddy and return. -*/ -dec_zone_page_state (page,NR_ISOLATED_ANON + -page_is_file_cache (page)); -balloon_page_free (page); -return MIGRATEPAGE_SUCCESS ; - } out:if (rc != -EAGAIN ) {/*
@@ -1137,6 +1114,10 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page, rc =unmap_and_move_huge_page (get_new_page, put_new_page, private, page, pass >2 , mode); + else if (PageBalloon(page)) + rc =balloon_page_migrate (get_new_page, + put_new_page, private, + page, pass >2 , mode); else rc =unmap_and_move (get_new_page, put_new_page, private, page, pass >2 , mode);
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 6 lines · Konstantin Khlebnikov
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freeSigned-off-by Konstantin Khlebnikov <[email protected]>
Quoted 9 lines
--- drivers/virtio/virtio_balloon.c | 77 ++++--------- include/linux/balloon_compaction.h | 107 ++++++------------ include/linux/migrate.h | 11 -- include/linux/pagemap.h | 18 --- mm/balloon_compaction.c | 214 ++++++++++++------------------------ mm/migrate.c | 27 +---- 6 files changed, 130 insertions(+), 324 deletions(-)
Very nice clean-up, just as all other patches in this set. Please, just consider amending the following changes to this patch of yours
Rafael
---
include/linux/balloon_compaction.h +41 -61
@@ -75,41 +75,6 @@ extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);#ifdef CONFIG_BALLOON_COMPACTION extern bool balloon_page_isolate (struct page *page);extern void balloon_page_putback (struct page *page); - -/* -* balloon_page_insert - insert a page into the balloon's page list and make -* the page->mapping assignment accordingly. -* @page : page to be assigned as a 'balloon page' -* @mapping : allocated special 'balloon_mapping' -* @head : balloon's device page list head -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before inserting a page into the balloon device. -*/ -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -set_page_private (page, (unsigned long )balloon); -list_add (&page->lru, &balloon->pages); -} - -/* -* balloon_page_delete - delete a page from balloon's page list and clear -* the page->mapping assignement accordingly. -* @page : page to be released from balloon's page list -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before deleting a page from the balloon device. -*/ -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -set_page_private (page,0 ); -if (!isolated) -list_del (&page->lru); -} -int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode);
@@ -130,31 +95,6 @@ static inline gfp_t balloon_mapping_gfp_mask(void)#else /* !CONFIG_BALLOON_COMPACTION */ -static inline void *balloon_mapping_alloc (void *balloon_device, -const struct address_space_operations *a_ops) -{ -return ERR_PTR (-EOPNOTSUPP ); -} - -static inline void balloon_mapping_free (struct address_space *balloon_mapping) -{ -return ; -} - -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -list_add (&page->lru, head); -} - -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -if (!isolated) -list_del (&page->lru); -} -static inline int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode)
@@ -176,6 +116,46 @@ static inline gfp_t balloon_mapping_gfp_mask(void) {return GFP_HIGHUSER ; } -#endif /* CONFIG_BALLOON_COMPACTION */ + +/* +* balloon_page_insert - insert a page into the balloon's page list and make +* the page->mapping assignment accordingly. +* @page : page to be assigned as a 'balloon page' +* @mapping : allocated special 'balloon_mapping' +* @head : balloon's device page list head +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before inserting a page into the balloon device. +*/ +static inline void +balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) +{ +#ifdef CONFIG_MEMORY_BALLOON +__SetPageBalloon (page); +set_page_private (page, (unsigned long )balloon); +list_add (&page->lru, &balloon->pages); +inc_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} + +/* +* balloon_page_delete - delete a page from balloon's page list and clear +* the page->mapping assignement accordingly. +* @page : page to be released from balloon's page list +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before deleting a page from the balloon device. +*/ +static inline void balloon_page_delete (struct page *page,bool isolated) +{ +#ifdef CONFIG_MEMORY_BALLOON +__ClearPageBalloon (page); +set_page_private (page,0 ); +if (!isolated) +list_del (&page->lru); +dec_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} +#endif /* _LINUX_BALLOON_COMPACTION_H */
Signature · 7 lines
1.9.3 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 16 lines · Rafael Aquini
Quoted 6 lines · Konstantin Khlebnikov
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freeSigned-off-by Konstantin Khlebnikov <[email protected]>Quoted 9 lines
--- drivers/virtio/virtio_balloon.c | 77 ++++--------- include/linux/balloon_compaction.h | 107 ++++++------------ include/linux/migrate.h | 11 -- include/linux/pagemap.h | 18 --- mm/balloon_compaction.c | 214 ++++++++++++------------------------ mm/migrate.c | 27 +---- 6 files changed, 130 insertions(+), 324 deletions(-)
Quoted 2 lines
Very nice clean-up, just as all other patches in this set. Please, just consider amending the following changes to this patch of yours
Well. Probably it's better to hide __Set/Clear inside mm/balloon_compaction.c it very unlikely that they might be used by somebody else.mm.h contains too many obscure static inlines and other barely used stuff.
And it's worth to rename balloon_compaction.c/h into just balloon.c or memory_balloon because
it provides generic balloon wtihout compaction too. Any objections?
Quoted 133 lines
Rafael
---include/linux/balloon_compaction.h +41
-62@@ -75,41 +75,6 @@ extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);#ifdef CONFIG_BALLOON_COMPACTION extern bool balloon_page_isolate (struct page *page);extern void balloon_page_putback (struct page *page); - -/* -* balloon_page_insert - insert a page into the balloon's page list and make -* the page->mapping assignment accordingly. -* @page : page to be assigned as a 'balloon page' -* @mapping : allocated special 'balloon_mapping' -* @head : balloon's device page list head -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before inserting a page into the balloon device. -*/ -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -set_page_private (page, (unsigned long )balloon); -list_add (&page->lru, &balloon->pages); -} - -/* -* balloon_page_delete - delete a page from balloon's page list and clear -* the page->mapping assignement accordingly. -* @page : page to be released from balloon's page list -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before deleting a page from the balloon device. -*/ -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -set_page_private (page,0 ); -if (!isolated) -list_del (&page->lru); -} -int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode);@@ -130,31 +95,6 @@ static inline gfp_t balloon_mapping_gfp_mask(void)#else /* !CONFIG_BALLOON_COMPACTION */ -static inline void *balloon_mapping_alloc (void *balloon_device, -const struct address_space_operations *a_ops) -{ -return ERR_PTR (-EOPNOTSUPP ); -} - -static inline void balloon_mapping_free (struct address_space *balloon_mapping) -{ -return ; -} - -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -list_add (&page->lru, head); -} - -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -if (!isolated) -list_del (&page->lru); -} -static inline int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode)@@ -176,6 +116,46 @@ static inline gfp_t balloon_mapping_gfp_mask(void) {return GFP_HIGHUSER ; } -#endif /* CONFIG_BALLOON_COMPACTION */ + +/* +* balloon_page_insert - insert a page into the balloon's page list and make +* the page->mapping assignment accordingly. +* @page : page to be assigned as a 'balloon page' +* @mapping : allocated special 'balloon_mapping' +* @head : balloon's device page list head +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before inserting a page into the balloon device. +*/ +static inline void +balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) +{ +#ifdef CONFIG_MEMORY_BALLOON +__SetPageBalloon (page); +set_page_private (page, (unsigned long )balloon); +list_add (&page->lru, &balloon->pages); +inc_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} + +/* +* balloon_page_delete - delete a page from balloon's page list and clear +* the page->mapping assignement accordingly. +* @page : page to be released from balloon's page list +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before deleting a page from the balloon device. +*/ +static inline void balloon_page_delete (struct page *page,bool isolated) +{ +#ifdef CONFIG_MEMORY_BALLOON +__ClearPageBalloon (page); +set_page_private (page,0 ); +if (!isolated) +list_del (&page->lru); +dec_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} +#endif /* _LINUX_BALLOON_COMPACTION_H */ --1.9.3
Quoted 5 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 17 lines · Konstantin Khlebnikov
Quoted 16 lines · Rafael Aquini
Quoted 15 lines · Konstantin Khlebnikov
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freeSigned-off-by Konstantin Khlebnikov <[email protected]>--- drivers/virtio/virtio_balloon.c | 77 ++++--------- include/linux/balloon_compaction.h | 107 ++++++------------ include/linux/migrate.h | 11 -- include/linux/pagemap.h | 18 --- mm/balloon_compaction.c | 214 ++++++++++++------------------------ mm/migrate.c | 27 +---- 6 files changed, 130 insertions(+), 324 deletions(-)
Quoted 7 lines
Quoted 2 lines
Very nice clean-up, just as all other patches in this set. Please, just consider amending the following changes to this patch of yours
Well. Probably it's better to hide __Set/Clear inside
mm/balloon_compaction.cit very unlikely that they might be used by somebody else.mm.hcontains too many obscure static inlines and other barely used stuff.
Although I agree that very few codesites will actually resort to them, I believe there's no argument to hide __Set/Clear if PageBalloon() itself is there. Take a look into how many codesites __{Set,Clear}PageBuddy are being called -- (as in their Balloon counterpart, just 1 codesite each).
For the sake of consistency and ease of maintainability, either leave all BalloonPage() and friends at mm.h or move them all out, hiding them in balloon_compaction.h.
Quoted 4 lines
And it's worth to rename balloon_compaction.c/h into just
balloon.cormemory_balloonbecause
it provides generic balloon wtihout compaction too. Any objections?
No objections here, I was actually thinking about renaming them too.
--
Rafael
Quoted 133 lines
Quoted 133 lines
Rafael
---include/linux/balloon_compaction.h +41
-62@@ -75,41 +75,6 @@ extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);#ifdef CONFIG_BALLOON_COMPACTION extern bool balloon_page_isolate (struct page *page);extern void balloon_page_putback (struct page *page); - -/* -* balloon_page_insert - insert a page into the balloon's page list and make -* the page->mapping assignment accordingly. -* @page : page to be assigned as a 'balloon page' -* @mapping : allocated special 'balloon_mapping' -* @head : balloon's device page list head -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before inserting a page into the balloon device. -*/ -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -set_page_private (page, (unsigned long )balloon); -list_add (&page->lru, &balloon->pages); -} - -/* -* balloon_page_delete - delete a page from balloon's page list and clear -* the page->mapping assignement accordingly. -* @page : page to be released from balloon's page list -* -* Caller must ensure the page is locked and the spin_lock protecting balloon -* pages list is held before deleting a page from the balloon device. -*/ -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -set_page_private (page,0 ); -if (!isolated) -list_del (&page->lru); -} -int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode);@@ -130,31 +95,6 @@ static inline gfp_t balloon_mapping_gfp_mask(void)#else /* !CONFIG_BALLOON_COMPACTION */ -static inline void *balloon_mapping_alloc (void *balloon_device, -const struct address_space_operations *a_ops) -{ -return ERR_PTR (-EOPNOTSUPP ); -} - -static inline void balloon_mapping_free (struct address_space *balloon_mapping) -{ -return ; -} - -static inline void -balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) -{ -__SetPageBalloon (page); -list_add (&page->lru, head); -} - -static inline void balloon_page_delete (struct page *page,bool isolated) -{ -__ClearPageBalloon (page); -if (!isolated) -list_del (&page->lru); -} -static inline int balloon_page_migrate (new_page_t get_new_page,free_page_t put_new_page,unsigned long private,struct page *page,int force,enum migrate_mode mode)@@ -176,6 +116,46 @@ static inline gfp_t balloon_mapping_gfp_mask(void) {return GFP_HIGHUSER ; } -#endif /* CONFIG_BALLOON_COMPACTION */ + +/* +* balloon_page_insert - insert a page into the balloon's page list and make +* the page->mapping assignment accordingly. +* @page : page to be assigned as a 'balloon page' +* @mapping : allocated special 'balloon_mapping' +* @head : balloon's device page list head +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before inserting a page into the balloon device. +*/ +static inline void +balloon_page_insert (struct balloon_dev_info *balloon,struct page *page) +{ +#ifdef CONFIG_MEMORY_BALLOON +__SetPageBalloon (page); +set_page_private (page, (unsigned long )balloon); +list_add (&page->lru, &balloon->pages); +inc_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} + +/* +* balloon_page_delete - delete a page from balloon's page list and clear +* the page->mapping assignement accordingly. +* @page : page to be released from balloon's page list +* +* Caller must ensure the page is locked and the spin_lock protecting balloon +* pages list is held before deleting a page from the balloon device. +*/ +static inline void balloon_page_delete (struct page *page,bool isolated) +{ +#ifdef CONFIG_MEMORY_BALLOON +__ClearPageBalloon (page); +set_page_private (page,0 ); +if (!isolated) +list_del (&page->lru); +dec_zone_page_state (page,NR_BALLOON_PAGES ); +#endif +} +#endif /* _LINUX_BALLOON_COMPACTION_H */ --1.9.3
Quoted 5 lines
Quoted 5 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [PATCH 7/7] mm/balloon_compaction: general cleanup
In reply to Konstantin KhlebnikovQuoted 5 lines · On Wed, 20 Aug 2014 19:05:09 +0400 Konstantin Khlebnikov…
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_free
grump.
include/linux/balloon_compaction.h renamed from include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fix +1 -1
@@ -145,7 +145,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, struct page *page) {__SetPageBalloon (page); -list_add (&page->lru, head); +list_add (&page->lru, &balloon->pages); }static inline void balloon_page_delete (struct page *page,bool isolated)
This obviously wasn't tested with CONFIG_BALLOON_COMPACTION=n. Please complete the testing of this patchset and let us know the result?
Thanks.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 24 lines · Andrew Morton
Quoted 5 lines · On Wed, 20 Aug 2014 19:05:09 +0400 Konstantin Khlebnikov…
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freegrump.
diff -puN
include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fixinclude/linux/balloon_compaction.hinclude/linux/balloon_compaction.h renamed from include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fix +1
-1@@ -145,7 +145,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, struct page *page) {__SetPageBalloon (page); -list_add (&page->lru, head); +list_add (&page->lru, &balloon->pages); }static inline void balloon_page_delete (struct page *page,bool isolated)
Quoted 3 lines
This obviously wasn't tested with
CONFIG_BALLOON_COMPACTION=n. Please complete the testing of this patchset and let us know the result?
That also reminds me why I suggested moving those as static inlines into mm.h, instead of getting them hidden in mm/balloon_compaction.c
Cheers,
-- Rafael
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 22 lines · Rafael Aquini
Quoted 21 lines · Andrew Morton
Quoted 5 lines · On Wed, 20 Aug 2014 19:05:09 +0400 Konstantin Khlebnikov…
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freegrump.
diff -puN
include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fixinclude/linux/balloon_compaction.hinclude/linux/balloon_compaction.h renamed from include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fix +1
-1@@ -145,7 +145,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, struct page *page) {__SetPageBalloon (page); -list_add (&page->lru, head); +list_add (&page->lru, &balloon->pages); }
Quoted 7 lines
Quoted 6 lines
include/linux/balloon_compaction.h renamed from include/linux/balloon_compaction.h~mm-balloon_compaction-general-cleanup-fix +0
-0static inline void balloon_page_delete (struct page *page,bool isolated)This obviously wasn't tested with
CONFIG_BALLOON_COMPACTION=n. Please complete the testing of this patchset and let us know the result?
Btw, I'll do a mea culpa here. Although this build failure was addressed by my extra-cleanup suggestion, I never made that statement clear at my original message.
http://permalink.gmane.org/gmane.linux.kernel.mm/121788
Sorry,
-- Rafael
Quoted 5 lines
That also reminds me why I suggested moving those as static inlines into
mm.h, instead of getting them hidden inmm/balloon_compaction.cCheers,
-- Rafael
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [PATCH 7/7] mm/balloon_compaction: general cleanup
In reply to Konstantin KhlebnikovQuoted 4 lines · On Wed, 20 Aug 2014 19:05:09 +0400 Konstantin Khlebnikov…
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_free
Another testing failure. Guys, allnoconfig is really fast.
Quoted 4 lines
include/linux/balloon_compaction.h +0
-0@@ -54,58 +54,27 @@* balloon driver as a page book-keeper for its registered balloon devices.
include/linux/balloon_compaction.h line 62
Quoted 10 lines
include/linux/balloon_compaction.h +2
-2*/ struct balloon_dev_info { -void *balloon_device;/* balloon device descriptor */ -struct address_space *mapping;/* balloon special page->mapping */ unsigned long isolated_pages;/* # of isolated pages for migration */ spinlock_t pages_lock;/* Protection to pages list */ struct list_head pages;/* Pages enqueued & handled to Host */ +int (* migrate_page)(struct balloon_dev_info *,struct page *newpage, +struct page *page,enum migrate_mode mode); };
If CONFIG_MIGRATION=n this gets turned into "NULL" and chaos ensues. I think I'll just nuke that #define:
include/linux/migrate.h renamed from include/linux/migrate.h~include-linux-migrateh-remove-migratepage-define +0 -3
@@ -82,9 +82,6 @@ static inline int migrate_huge_page_move return -ENOSYS; } -/* Possible settings for the migrate_page() method in address_operations */ -#define migrate_page NULL -#endif /* CONFIG_MIGRATION */ #ifdef CONFIG_NUMA_BALANCING
mm/swap_state.c renamed from mm/swap_state.c~include-linux-migrateh-remove-migratepage-define +2 -0
@@ -28,7 +28,9 @@static const struct address_space_operations swap_aops = { .writepage = swap_writepage, .set_page_dirty = swap_set_page_dirty, +#ifdef CONFIG_MIGRATION .migratepage = migrate_page, +#endif };static struct backing_dev_info swap_backing_dev_info = {
mm/shmem.c renamed from mm/shmem.c~include-linux-migrateh-remove-migratepage-define +2 -0
@@ -3075,7 +3075,9 @@ static const struct address_space_operat .write_begin = shmem_write_begin, .write_end = shmem_write_end,#endif +#ifdef CONFIG_MIGRATION .migratepage = migrate_page, +#endif .error_remove_page = generic_error_remove_page, };
Our mixture of "migratepage" and "migrate_page" is maddening.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/7] mm/balloon_compaction: general cleanup
Quoted 8 lines · Andrew Morton
Quoted 4 lines · On Wed, 20 Aug 2014 19:05:09 +0400 Konstantin Khlebnikov…
* move special branch for balloon migraion into
migrate_pages
* remove special mapping for balloon and its flagAS_BALLOON_MAP
* embed structballoon_dev_infointo structvirtio_balloon
* cleanupballoon_page_dequeue, killballoon_page_freeAnother testing failure. Guys, allnoconfig is really fast.
Heh, mea culpa too. I've missed messages about including my patches except one with stress-test, probably they are stuck somewhere in my corporate email. So I thought you've picked only one patch.
Rafael had several suggestions so I postponed them till v2 patchset which never been sent.
Quoted 10 lines
Quoted 10 lines
include/linux/balloon_compaction.h +0
-2@@ -54,58 +54,27 @@* balloon driver as a page book-keeper for its registered balloon devices. */ struct balloon_dev_info { -void *balloon_device;/* balloon device descriptor */ -struct address_space *mapping;/* balloon special page->mapping */ unsigned long isolated_pages;/* # of isolated pages for migration */
Quoted 8 lines
include/linux/balloon_compaction.h line 62
Quoted 5 lines
include/linux/balloon_compaction.h +2
-0spinlock_t pages_lock;/* Protection to pages list */ struct list_head pages;/* Pages enqueued & handled to Host */ +int (* migrate_page)(struct balloon_dev_info *,struct page *newpage, +struct page *page,enum migrate_mode mode); };If
CONFIG_MIGRATION=nthis gets turned into "NULL" and chaos ensues. I think I'll just nuke that #define:
Hmm, i think it's better to rename migrate_page() into something less generic. for example generic_migrate_page() or generic_migratepage().
Quoted 38 lines
include/linux/migrate.h renamed from include/linux/migrate.h~include-linux-migrateh-remove-migratepage-define +0
-3@@ -82,9 +82,6 @@ static inline int migrate_huge_page_move return -ENOSYS; } -/* Possible settings for the migrate_page() method in address_operations */ -#define migrate_page NULL -#endif /* CONFIG_MIGRATION */ #ifdef CONFIG_NUMA_BALANCING mm/swap_state.c renamed from mm/swap_state.c~include-linux-migrateh-remove-migratepage-define +2
-0@@ -28,7 +28,9 @@static const struct address_space_operations swap_aops = { .writepage = swap_writepage, .set_page_dirty = swap_set_page_dirty, +#ifdef CONFIG_MIGRATION .migratepage = migrate_page, +#endif };static struct backing_dev_info swap_backing_dev_info = {mm/shmem.c renamed from mm/shmem.c~include-linux-migrateh-remove-migratepage-define +2
-0@@ -3075,7 +3075,9 @@ static const struct address_space_operat .write_begin = shmem_write_begin, .write_end = shmem_write_end,#endif +#ifdef CONFIG_MIGRATION .migratepage = migrate_page, +#endif .error_remove_page = generic_error_remove_page, };
Quoted 7 lines
Our mixture of "migratepage" and "
migrate_page" is maddening.--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 mm: rename "migrate_page" to "generic_migrate_page"
If CONFIG_MIGRATION=n "migrate_page" turns into NULL. This kills ifdef-endif mess inside definitions of address space operations. But this macro affects everything with this name, "migrate_page" is too short and generic.
This patch renames it into generic_migrate_page. Fortunately it's used only in few places. Also here minor update for documentation: a_ops method is called "migratepage", without underscore, obviously for keeping the macro away.
--- Documentation/filesystems/vfs.txt | 13 ++++++++----- fs/btrfs/disk-io.c | 2 +- fs/nfs/write.c | 2 +- include/linux/migrate.h | 6 +++--- mm/migrate.c | 10 +++++----- mm/shmem.c | 2 +- mm/swap_state.c | 2 +- 7 files changed, 20 insertions(+), 17 deletions(-)
Documentation/filesystems/vfs.txt +8 -5
@@ -746,12 +746,15 @@ struct address_space_operations { Filesystems that want to use execute-in-place (XIP) need to implement it. An example implementation can be found in fs/ext2/xip.c. - migrate_page: This is used to compact the physical memory usage. - If the VM wants to relocate a page (maybe off a memory card - that is signalling imminent failure) it will pass a new page - and an old page to this function. migrate_page should + migratepage: This is used to compact the physical memory usage. + If the VM wants to relocate a page (maybe off a memory card + that is signalling imminent failure) it will pass a new page + and an old page to this function. migratepage should transfer any private data across and update any references - that it has to the page. + that it has to the page. + + Filesystem might use here generic_migrate_page if pages have no + private data or buffer_migrate_page for pages with buffers. launder_page: Called before freeing a page - it writes back the dirty page. To prevent redirtying the page, it is kept locked during the whole
fs/btrfs/disk-io.c +1 -1
@@ -973,7 +973,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, mode); + return generic_migrate_page(mapping, newpage, page, mode); }#endif
fs/nfs/write.c +1 -1
@@ -1898,7 +1898,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,if (!nfs_fscache_release_page (page,GFP_KERNEL ))return -EBUSY ; - return migrate_page(mapping, newpage, page, mode); + return generic_migrate_page(mapping, newpage, page, mode); }#endif
include/linux/migrate.h +3 -3
@@ -38,7 +38,7 @@ enum migrate_reason {#ifdef CONFIG_MIGRATION extern void putback_movable_pages (struct list_head *l); -extern int migrate_page (struct address_space *, +extern int generic_migrate_page (struct address_space *,struct page *,struct page *,enum migrate_mode );extern int migrate_pages (struct list_head *l,new_page_t new,free_page_t free,unsigned long private,enum migrate_mode mode,int reason);
@@ -82,8 +82,8 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, return -ENOSYS; } -/* Possible settings for the migrate_page() method in address_operations */ -#define migrate_page NULL +/* Possible settings for the migratepage() method in address_operations */ +#define generic_migrate_page NULL#endif /* CONFIG_MIGRATION */
mm/migrate.c +5 -5
@@ -588,7 +588,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)* * Pages are locked upon entry and exit. */ -int migrate_page (struct address_space *mapping, +int generic_migrate_page (struct address_space *mapping,struct page *newpage,struct page *page,enum migrate_mode mode) {
@@ -604,7 +604,7 @@ int migrate_page(struct address_space *mapping,migrate_page_copy (newpage, page);return MIGRATEPAGE_SUCCESS ; } -EXPORT_SYMBOL (migrate_page); +EXPORT_SYMBOL (generic_migrate_page);#ifdef CONFIG_BLOCK /*
@@ -619,7 +619,7 @@ int buffer_migrate_page(struct address_space *mapping,int rc;if (!page_has_buffers (page)) -return migrate_page (mapping, newpage, page, mode); +return generic_migrate_page (mapping, newpage, page, mode); head =page_buffers (page);
@@ -728,7 +728,7 @@ static int fallback_migrate_page(struct address_space *mapping, !try_to_release_page(page, GFP_KERNEL))return -EAGAIN ; -return migrate_page (mapping, newpage, page, mode); +return generic_migrate_page (mapping, newpage, page, mode); }/*
@@ -764,7 +764,7 @@ static int move_to_new_page(struct page *newpage, struct page *page, mapping =page_mapping (page);if (!mapping) - rc =migrate_page (mapping, newpage, page, mode); + rc =generic_migrate_page (mapping, newpage, page, mode);else if (mapping->a_ops->migratepage)/* * Most pages have a mapping and most filesystems provide a
mm/shmem.c +1 -1
@@ -3075,7 +3075,7 @@ static const struct address_space_operations shmem_aops = { .write_begin = shmem_write_begin, .write_end = shmem_write_end, #endif - .migratepage = migrate_page, + .migratepage = generic_migrate_page, .error_remove_page = generic_error_remove_page, };
mm/swap_state.c +1 -1
@@ -28,7 +28,7 @@static const struct address_space_operations swap_aops = { .writepage = swap_writepage, .set_page_dirty = swap_set_page_dirty, - .migratepage = migrate_page, + .migratepage = generic_migrate_page, };static struct backing_dev_info swap_backing_dev_info = {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 19 lines · Konstantin Khlebnikov
Sasha Levin reported KASAN splash inside
isolate_migratepages_range(). Problem is in function__is_movable_balloon_page()which testsAS_BALLOON_MAPinpage->mapping->flags. This function has no protection against anonymous pages. As result it tried to check address space flags in inside anon-vma.Signed-off-by Konstantin Khlebnikov <[email protected]>Reported-by Sasha Levin <[email protected]>Cc stable <[email protected]> # v3.8--- include/linux/balloon_compaction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)include/linux/balloon_compaction.h +0
-0
include/linux/balloon_compaction.h static inline bool page_flags_cleared(struct page *page) · line 134
Quoted 8 lines
include/linux/balloon_compaction.h +1
-1@@ -128,7 +128,7 @@ static inline bool page_flags_cleared(struct page *page)static inline bool __is_movable_balloon_page (struct page *page) {struct address_space *mapping = page->mapping; -return mapping_balloon (mapping); +return !PageAnon (page) &&mapping_balloon (mapping); }/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>