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>
This commit is contained in:
Konstantin Khlebnikov 2014-10-09 15:29:32 -07:00 committed by Linus Torvalds
parent 9d1ba80564
commit 09316c09dd
11 changed files with 37 additions and 3 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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);
} }

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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",

View File

@ -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",