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