Commit 09316c09 authored by Konstantin Khlebnikov's avatar Konstantin Khlebnikov Committed by Linus Torvalds

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: default avatarKonstantin Khlebnikov <k.khlebnikov@samsung.com>
Cc: Rafael Aquini <aquini@redhat.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9d1ba805
...@@ -25,6 +25,7 @@ config VIRTIO_PCI ...@@ -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.
......
...@@ -396,6 +396,7 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, ...@@ -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);
......
...@@ -133,6 +133,9 @@ u64 stable_page_flags(struct page *page) ...@@ -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);
......
...@@ -166,11 +166,13 @@ static inline gfp_t balloon_mapping_gfp_mask(void) ...@@ -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);
} }
......
...@@ -72,6 +72,13 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, ...@@ -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 */
......
...@@ -31,6 +31,7 @@ ...@@ -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 */
...@@ -230,12 +230,17 @@ config SPLIT_PTLOCK_CPUS ...@@ -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
......
...@@ -16,7 +16,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ ...@@ -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 ...@@ -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
...@@ -36,6 +36,7 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info) ...@@ -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) ...@@ -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;
......
...@@ -735,7 +735,7 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat, ...@@ -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[] = { ...@@ -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[] = { ...@@ -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",
......
...@@ -132,6 +132,7 @@ static const char * const page_flag_names[] = { ...@@ -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",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment