summaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorIgor Redko <redkoi@virtuozzo.com>2016-03-17 17:19:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 18:09:34 -0400
commitd02bd27bd33dd7e8d22594cd568b81be0cb584cd (patch)
treee8bbd51013b90f2b9cf6ea239128f9da1f714e55 /mm/page_alloc.c
parent7eb50292d7f74ccb89155960d62b2697f2536b28 (diff)
mm/page_alloc.c: calculate 'available' memory in a separate function
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@virtuozzo.com> Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: Roman Kagan <rkagan@virtuozzo.com> Cc: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 25a75da53c27..941b802e11ec 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3713,6 +3713,49 @@ static inline void show_node(struct zone *zone)
3713 printk("Node %d ", zone_to_nid(zone)); 3713 printk("Node %d ", zone_to_nid(zone));
3714} 3714}
3715 3715
3716long si_mem_available(void)
3717{
3718 long available;
3719 unsigned long pagecache;
3720 unsigned long wmark_low = 0;
3721 unsigned long pages[NR_LRU_LISTS];
3722 struct zone *zone;
3723 int lru;
3724
3725 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
3726 pages[lru] = global_page_state(NR_LRU_BASE + lru);
3727
3728 for_each_zone(zone)
3729 wmark_low += zone->watermark[WMARK_LOW];
3730
3731 /*
3732 * Estimate the amount of memory available for userspace allocations,
3733 * without causing swapping.
3734 */
3735 available = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
3736
3737 /*
3738 * Not all the page cache can be freed, otherwise the system will
3739 * start swapping. Assume at least half of the page cache, or the
3740 * low watermark worth of cache, needs to stay.
3741 */
3742 pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
3743 pagecache -= min(pagecache / 2, wmark_low);
3744 available += pagecache;
3745
3746 /*
3747 * Part of the reclaimable slab consists of items that are in use,
3748 * and cannot be freed. Cap this estimate at the low watermark.
3749 */
3750 available += global_page_state(NR_SLAB_RECLAIMABLE) -
3751 min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
3752
3753 if (available < 0)
3754 available = 0;
3755 return available;
3756}
3757EXPORT_SYMBOL_GPL(si_mem_available);
3758
3716void si_meminfo(struct sysinfo *val) 3759void si_meminfo(struct sysinfo *val)
3717{ 3760{
3718 val->totalram = totalram_pages; 3761 val->totalram = totalram_pages;