ACK: [PATCH 1/2 Xenial SRU] mm/page_alloc.c: calculate 'available' memory in a separate function
Chris J Arges
chris.j.arges at canonical.com
Wed Jun 8 18:19:21 UTC 2016
Ack for both patches. Backport looks correct and cherry-pick seems reasonable.
I think this feature addition is minimal enough in just reporting additional
information which can be very useful when trying to allocate vms on a system.
--chris
On Wed, Jun 08, 2016 at 10:58:07AM -0600, Tim Gardner wrote:
> From: Igor Redko <redkoi at virtuozzo.com>
>
> BugLink: http://bugs.launchpad.net/bugs/1587091
>
> Add a new field, VIRTIO_BALLOON_S_AVAIL, to virtio_balloon memory
> statistics protocol, corresponding to 'Available' in /proc/meminfo.
>
> It indicates to the hypervisor how big the balloon can be inflated
> without pushing the guest system to swap. This metric would be very
> useful in VM orchestration software to improve memory management of
> different VMs under overcommit.
>
> This patch (of 2):
>
> Factor out calculation of the available memory counter into a separate
> exportable function, in order to be able to use it in other parts of the
> kernel.
>
> In particular, it appears a relevant metric to report to the hypervisor
> via virtio-balloon statistics interface (in a followup patch).
>
> Signed-off-by: Igor Redko <redkoi at virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den at openvz.org>
> Reviewed-by: Roman Kagan <rkagan at virtuozzo.com>
> Cc: Michael S. Tsirkin <mst at redhat.com>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
> (back ported from commit d02bd27bd33dd7e8d22594cd568b81be0cb584cd)
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
>
> Conflicts:
> fs/proc/meminfo.c
> ---
> fs/proc/meminfo.c | 34 +---------------------------------
> include/linux/mm.h | 1 +
> mm/page_alloc.c | 43 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 45 insertions(+), 33 deletions(-)
>
> diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
> index 9155a5a..8372046 100644
> --- a/fs/proc/meminfo.c
> +++ b/fs/proc/meminfo.c
> @@ -29,10 +29,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
> unsigned long committed;
> long cached;
> long available;
> - unsigned long pagecache;
> - unsigned long wmark_low = 0;
> unsigned long pages[NR_LRU_LISTS];
> - struct zone *zone;
> int lru;
>
> /*
> @@ -51,36 +48,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
> for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
> pages[lru] = global_page_state(NR_LRU_BASE + lru);
>
> - for_each_zone(zone)
> - wmark_low += zone->watermark[WMARK_LOW];
> -
> - /*
> - * Estimate the amount of memory available for userspace allocations,
> - * without causing swapping.
> - *
> - * Free memory cannot be taken below the low watermark, before the
> - * system starts swapping.
> - */
> - available = i.freeram - wmark_low;
> -
> - /*
> - * Not all the page cache can be freed, otherwise the system will
> - * start swapping. Assume at least half of the page cache, or the
> - * low watermark worth of cache, needs to stay.
> - */
> - pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
> - pagecache -= min(pagecache / 2, wmark_low);
> - available += pagecache;
> -
> - /*
> - * Part of the reclaimable slab consists of items that are in use,
> - * and cannot be freed. Cap this estimate at the low watermark.
> - */
> - available += global_page_state(NR_SLAB_RECLAIMABLE) -
> - min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
> -
> - if (available < 0)
> - available = 0;
> + available = si_mem_available();
>
> /*
> * Tagged format, for easy grepping and expansion.
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 70cbf8c..3b13fd3 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1829,6 +1829,7 @@ extern int __meminit init_per_zone_wmark_min(void);
> extern void mem_init(void);
> extern void __init mmap_init(void);
> extern void show_mem(unsigned int flags);
> +extern long si_mem_available(void);
> extern void si_meminfo(struct sysinfo * val);
> extern void si_meminfo_node(struct sysinfo *val, int nid);
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 6cf5cad..2f4e66a 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -3604,6 +3604,49 @@ static inline void show_node(struct zone *zone)
> printk("Node %d ", zone_to_nid(zone));
> }
>
> +long si_mem_available(void)
> +{
> + long available;
> + unsigned long pagecache;
> + unsigned long wmark_low = 0;
> + unsigned long pages[NR_LRU_LISTS];
> + struct zone *zone;
> + int lru;
> +
> + for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
> + pages[lru] = global_page_state(NR_LRU_BASE + lru);
> +
> + for_each_zone(zone)
> + wmark_low += zone->watermark[WMARK_LOW];
> +
> + /*
> + * Estimate the amount of memory available for userspace allocations,
> + * without causing swapping.
> + */
> + available = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
> +
> + /*
> + * Not all the page cache can be freed, otherwise the system will
> + * start swapping. Assume at least half of the page cache, or the
> + * low watermark worth of cache, needs to stay.
> + */
> + pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
> + pagecache -= min(pagecache / 2, wmark_low);
> + available += pagecache;
> +
> + /*
> + * Part of the reclaimable slab consists of items that are in use,
> + * and cannot be freed. Cap this estimate at the low watermark.
> + */
> + available += global_page_state(NR_SLAB_RECLAIMABLE) -
> + min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
> +
> + if (available < 0)
> + available = 0;
> + return available;
> +}
> +EXPORT_SYMBOL_GPL(si_mem_available);
> +
> void si_meminfo(struct sysinfo *val)
> {
> val->totalram = totalram_pages;
> --
> 1.9.1
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list