浏览代码

mm/balloon_compaction: add vmstat counters and kpageflags bit

Always mark pages with PageBalloon even if balloon compaction is disabled
and expose this mark in /proc/kpageflags as KPF_BALLOON.

Also this patch adds three counters into /proc/vmstat: "balloon_inflate",
"balloon_deflate" and "balloon_migrate".  They accumulate balloon
activity.  Current size of balloon is (balloon_inflate - balloon_deflate)
pages.

All generic balloon code now gathered under option CONFIG_MEMORY_BALLOON.
It should be selected by ballooning driver which wants use this feature.
Currently virtio-balloon is the only user.

Signed-off-by: Konstantin Khlebnikov <k.khlebnikov@samsung.com>
Cc: Rafael Aquini <aquini@redhat.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Konstantin Khlebnikov 10 年之前
父节点
当前提交
09316c09dd

+ 1 - 0
drivers/virtio/Kconfig

@@ -25,6 +25,7 @@ config VIRTIO_PCI
 config VIRTIO_BALLOON
 config VIRTIO_BALLOON
 	tristate "Virtio balloon driver"
 	tristate "Virtio balloon driver"
 	depends on VIRTIO
 	depends on VIRTIO
+	select MEMORY_BALLOON
 	---help---
 	---help---
 	 This driver supports increasing and decreasing the amount
 	 This driver supports increasing and decreasing the amount
 	 of memory within a KVM guest.
 	 of memory within a KVM guest.

+ 1 - 0
drivers/virtio/virtio_balloon.c

@@ -396,6 +396,7 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
 	spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
 	spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
 	balloon_page_insert(vb_dev_info, newpage);
 	balloon_page_insert(vb_dev_info, newpage);
 	vb_dev_info->isolated_pages--;
 	vb_dev_info->isolated_pages--;
+	__count_vm_event(BALLOON_MIGRATE);
 	spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
 	spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
 	set_page_pfns(vb->pfns, newpage);
 	set_page_pfns(vb->pfns, newpage);

+ 3 - 0
fs/proc/page.c

@@ -133,6 +133,9 @@ u64 stable_page_flags(struct page *page)
 	if (PageBuddy(page))
 	if (PageBuddy(page))
 		u |= 1 << KPF_BUDDY;
 		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_LOCKED,	PG_locked);
 
 
 	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);
 	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);

+ 2 - 0
include/linux/balloon_compaction.h

@@ -166,11 +166,13 @@ static inline gfp_t balloon_mapping_gfp_mask(void)
 static inline void balloon_page_insert(struct balloon_dev_info *balloon,
 static inline void balloon_page_insert(struct balloon_dev_info *balloon,
 				       struct page *page)
 				       struct page *page)
 {
 {
+	__SetPageBalloon(page);
 	list_add(&page->lru, &balloon->pages);
 	list_add(&page->lru, &balloon->pages);
 }
 }
 
 
 static inline void balloon_page_delete(struct page *page)
 static inline void balloon_page_delete(struct page *page)
 {
 {
+	__ClearPageBalloon(page);
 	list_del(&page->lru);
 	list_del(&page->lru);
 }
 }
 
 

+ 7 - 0
include/linux/vm_event_item.h

@@ -72,6 +72,13 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 		THP_ZERO_PAGE_ALLOC,
 		THP_ZERO_PAGE_ALLOC,
 		THP_ZERO_PAGE_ALLOC_FAILED,
 		THP_ZERO_PAGE_ALLOC_FAILED,
 #endif
 #endif
+#ifdef CONFIG_MEMORY_BALLOON
+		BALLOON_INFLATE,
+		BALLOON_DEFLATE,
+#ifdef CONFIG_BALLOON_COMPACTION
+		BALLOON_MIGRATE,
+#endif
+#endif
 #ifdef CONFIG_DEBUG_TLBFLUSH
 #ifdef CONFIG_DEBUG_TLBFLUSH
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 		NR_TLB_REMOTE_FLUSH,	/* cpu tried to flush others' tlbs */
 		NR_TLB_REMOTE_FLUSH,	/* cpu tried to flush others' tlbs */

+ 1 - 0
include/uapi/linux/kernel-page-flags.h

@@ -31,6 +31,7 @@
 
 
 #define KPF_KSM			21
 #define KPF_KSM			21
 #define KPF_THP			22
 #define KPF_THP			22
+#define KPF_BALLOON		23
 
 
 
 
 #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
 #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */

+ 6 - 1
mm/Kconfig

@@ -230,12 +230,17 @@ config SPLIT_PTLOCK_CPUS
 config ARCH_ENABLE_SPLIT_PMD_PTLOCK
 config ARCH_ENABLE_SPLIT_PMD_PTLOCK
 	boolean
 	boolean
 
 
+#
+# support for memory balloon
+config MEMORY_BALLOON
+	boolean
+
 #
 #
 # support for memory balloon compaction
 # support for memory balloon compaction
 config BALLOON_COMPACTION
 config BALLOON_COMPACTION
 	bool "Allow for balloon memory compaction/migration"
 	bool "Allow for balloon memory compaction/migration"
 	def_bool y
 	def_bool y
-	depends on COMPACTION && VIRTIO_BALLOON
+	depends on COMPACTION && MEMORY_BALLOON
 	help
 	help
 	  Memory fragmentation introduced by ballooning might reduce
 	  Memory fragmentation introduced by ballooning might reduce
 	  significantly the number of 2MB contiguous memory blocks that can be
 	  significantly the number of 2MB contiguous memory blocks that can be

+ 2 - 1
mm/Makefile

@@ -16,7 +16,7 @@ obj-y			:= filemap.o mempool.o oom_kill.o \
 			   readahead.o swap.o truncate.o vmscan.o shmem.o \
 			   readahead.o swap.o truncate.o vmscan.o shmem.o \
 			   util.o mmzone.o vmstat.o backing-dev.o \
 			   util.o mmzone.o vmstat.o backing-dev.o \
 			   mm_init.o mmu_context.o percpu.o slab_common.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 \
 			   interval_tree.o list_lru.o workingset.o \
 			   iov_iter.o debug.o $(mmu-y)
 			   iov_iter.o debug.o $(mmu-y)
 
 
@@ -67,3 +67,4 @@ obj-$(CONFIG_ZBUD)	+= zbud.o
 obj-$(CONFIG_ZSMALLOC)	+= zsmalloc.o
 obj-$(CONFIG_ZSMALLOC)	+= zsmalloc.o
 obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
 obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
 obj-$(CONFIG_CMA)	+= cma.o
 obj-$(CONFIG_CMA)	+= cma.o
+obj-$(CONFIG_MEMORY_BALLOON) += balloon_compaction.o

+ 2 - 0
mm/balloon_compaction.c

@@ -36,6 +36,7 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
 	BUG_ON(!trylock_page(page));
 	BUG_ON(!trylock_page(page));
 	spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 	spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 	balloon_page_insert(b_dev_info, page);
 	balloon_page_insert(b_dev_info, page);
+	__count_vm_event(BALLOON_INFLATE);
 	spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 	spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 	unlock_page(page);
 	unlock_page(page);
 	return page;
 	return page;
@@ -74,6 +75,7 @@ struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
 			}
 			}
 			spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 			spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 			balloon_page_delete(page);
 			balloon_page_delete(page);
+			__count_vm_event(BALLOON_DEFLATE);
 			spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 			spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 			unlock_page(page);
 			unlock_page(page);
 			dequeued_page = true;
 			dequeued_page = true;

+ 11 - 1
mm/vmstat.c

@@ -735,7 +735,7 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
 					TEXT_FOR_HIGHMEM(xx) xx "_movable",
 					TEXT_FOR_HIGHMEM(xx) xx "_movable",
 
 
 const char * const vmstat_text[] = {
 const char * const vmstat_text[] = {
-	/* Zoned VM counters */
+	/* enum zone_stat_item countes */
 	"nr_free_pages",
 	"nr_free_pages",
 	"nr_alloc_batch",
 	"nr_alloc_batch",
 	"nr_inactive_anon",
 	"nr_inactive_anon",
@@ -778,10 +778,13 @@ const char * const vmstat_text[] = {
 	"workingset_nodereclaim",
 	"workingset_nodereclaim",
 	"nr_anon_transparent_hugepages",
 	"nr_anon_transparent_hugepages",
 	"nr_free_cma",
 	"nr_free_cma",
+
+	/* enum writeback_stat_item counters */
 	"nr_dirty_threshold",
 	"nr_dirty_threshold",
 	"nr_dirty_background_threshold",
 	"nr_dirty_background_threshold",
 
 
 #ifdef CONFIG_VM_EVENT_COUNTERS
 #ifdef CONFIG_VM_EVENT_COUNTERS
+	/* enum vm_event_item counters */
 	"pgpgin",
 	"pgpgin",
 	"pgpgout",
 	"pgpgout",
 	"pswpin",
 	"pswpin",
@@ -860,6 +863,13 @@ const char * const vmstat_text[] = {
 	"thp_zero_page_alloc",
 	"thp_zero_page_alloc",
 	"thp_zero_page_alloc_failed",
 	"thp_zero_page_alloc_failed",
 #endif
 #endif
+#ifdef CONFIG_MEMORY_BALLOON
+	"balloon_inflate",
+	"balloon_deflate",
+#ifdef CONFIG_BALLOON_COMPACTION
+	"balloon_migrate",
+#endif
+#endif /* CONFIG_MEMORY_BALLOON */
 #ifdef CONFIG_DEBUG_TLBFLUSH
 #ifdef CONFIG_DEBUG_TLBFLUSH
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 	"nr_tlb_remote_flush",
 	"nr_tlb_remote_flush",

+ 1 - 0
tools/vm/page-types.c

@@ -132,6 +132,7 @@ static const char * const page_flag_names[] = {
 	[KPF_NOPAGE]		= "n:nopage",
 	[KPF_NOPAGE]		= "n:nopage",
 	[KPF_KSM]		= "x:ksm",
 	[KPF_KSM]		= "x:ksm",
 	[KPF_THP]		= "t:thp",
 	[KPF_THP]		= "t:thp",
+	[KPF_BALLOON]		= "o:balloon",
 
 
 	[KPF_RESERVED]		= "r:reserved",
 	[KPF_RESERVED]		= "r:reserved",
 	[KPF_MLOCKED]		= "m:mlocked",
 	[KPF_MLOCKED]		= "m:mlocked",