[Devel] [PATCH rh7 2/4] ub: make cached and shmem meminfo output more accurate

Andrey Ryabinin aryabinin at virtuozzo.com
Thu May 5 05:27:09 PDT 2016



On 05/05/2016 01:23 PM, Vladimir Davydov wrote:
> Currently, these fields are faked using file lru size and UB_SHMPAGES.
> The result leaves a lot to be desired, because UB_SHMPAGES accounts
> every shared pages as many times as it is mapped. Let's instead take
> these values directly from memory cgroup where they are already properly
> accounted.
> 
> Along the way, zap ub_page_stat and use mem_cgroup_get_nr_pages
> directly.
> 
> Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>

Reviewed-by: Andrey Ryabinin <aryabinin at virtuozzo.com>

> ---
>  include/bc/beancounter.h |  3 ---
>  kernel/bc/beancounter.c  | 15 ---------------
>  kernel/bc/proc.c         | 15 ++++++++++-----
>  kernel/bc/vm_pages.c     | 24 +++++++-----------------
>  mm/memcontrol.c          | 19 +++++++++++++++++++
>  5 files changed, 36 insertions(+), 40 deletions(-)
> 
> diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h
> index 8316cc4861a3..8f3119d214e9 100644
> --- a/include/bc/beancounter.h
> +++ b/include/bc/beancounter.h
> @@ -288,9 +288,6 @@ extern void uncharge_warn(struct user_beancounter *ub, const char *resource,
>  
>  extern int ub_update_memcg(struct user_beancounter *ub);
>  extern void ub_sync_memcg(struct user_beancounter *ub);
> -extern void ub_page_stat(struct user_beancounter *ub,
> -			 const nodemask_t *nodemask,
> -			 unsigned long *pages);
>  extern unsigned long ub_total_pages(struct user_beancounter *ub, bool swap);
>  
>  extern const char *ub_rnames[];
> diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
> index 90fc1ddf8f89..5023bd2b208d 100644
> --- a/kernel/bc/beancounter.c
> +++ b/kernel/bc/beancounter.c
> @@ -231,21 +231,6 @@ void ub_sync_memcg(struct user_beancounter *ub)
>  	css_put(css);
>  }
>  
> -void ub_page_stat(struct user_beancounter *ub, const nodemask_t *nodemask,
> -		  unsigned long *pages)
> -{
> -	int nid;
> -	struct cgroup_subsys_state *css;
> -
> -	memset(pages, 0, sizeof(unsigned long) * NR_LRU_LISTS);
> -
> -	css = ub_get_mem_css(ub);
> -	for_each_node_mask(nid, *nodemask)
> -		mem_cgroup_get_nr_pages(mem_cgroup_from_cont(css->cgroup),
> -					nid, pages);
> -	css_put(css);
> -}
> -
>  unsigned long ub_total_pages(struct user_beancounter *ub, bool swap)
>  {
>  	struct cgroup_subsys_state *css;
> diff --git a/kernel/bc/proc.c b/kernel/bc/proc.c
> index 9e9fde4904a0..4c79550cb036 100644
> --- a/kernel/bc/proc.c
> +++ b/kernel/bc/proc.c
> @@ -17,6 +17,7 @@
>  #include <linux/mnt_namespace.h>
>  #include <linux/lglock.h>
>  #include <linux/ve.h>
> +#include <linux/memcontrol.h>
>  
>  #include <bc/beancounter.h>
>  #include <bc/proc.h>
> @@ -129,18 +130,21 @@ static struct bc_proc_entry bc_meminfo_entry = {
>  	.u.show = bc_proc_meminfo_show,
>  };
>  
> +extern void mem_cgroup_get_nr_pages(struct mem_cgroup *memcg, int nid,
> +				    unsigned long *pages);
> +
>  #define K(x) ((x) << (PAGE_SHIFT - 10))
>  static int bc_proc_nodeinfo_show(struct seq_file *f, void *v)
>  {
>  	int nid;
> -	struct user_beancounter *ub;
> +	struct cgroup_subsys_state *css;
>  	unsigned long pages[NR_LRU_LISTS];
>  
> -	ub = seq_beancounter(f);
> +	css = ub_get_mem_css(seq_beancounter(f));
>  	for_each_node_state(nid, N_HIGH_MEMORY) {
> -		nodemask_t nodemask = nodemask_of_node(nid);
> -
> -		ub_page_stat(ub, &nodemask, pages);
> +		memset(pages, 0, sizeof(pages));
> +		mem_cgroup_get_nr_pages(mem_cgroup_from_cont(css->cgroup),
> +					nid, pages);
>  		seq_printf(f,
>  			"Node %d Active:         %8lu kB\n"
>  			"Node %d Inactive:       %8lu kB\n"
> @@ -159,6 +163,7 @@ static int bc_proc_nodeinfo_show(struct seq_file *f, void *v)
>  			nid, K(pages[LRU_INACTIVE_FILE]),
>  			nid, K(pages[LRU_UNEVICTABLE]));
>  	}
> +	css_put(css);
>  	return 0;
>  }
>  #undef K
> diff --git a/kernel/bc/vm_pages.c b/kernel/bc/vm_pages.c
> index b46da98fece2..5e588d1f036c 100644
> --- a/kernel/bc/vm_pages.c
> +++ b/kernel/bc/vm_pages.c
> @@ -159,22 +159,23 @@ static int bc_fill_sysinfo(struct user_beancounter *ub,
>  	return NOTIFY_OK;
>  }
>  
> +extern void mem_cgroup_fill_meminfo(struct mem_cgroup *memcg, struct meminfo *mi);
> +
>  static int bc_fill_meminfo(struct user_beancounter *ub,
>  		unsigned long meminfo_val, struct meminfo *mi)
>  {
> +	struct cgroup_subsys_state *css;
>  	int cpu, ret;
> -	long dcache;
>  
>  	ret = bc_fill_sysinfo(ub, meminfo_val, mi->si);
>  	if (ret & NOTIFY_STOP_MASK)
>  		goto out;
>  
> -	ub_sync_memcg(ub);
> -	ub_page_stat(ub, &node_online_map, mi->pages);
> +	css = ub_get_mem_css(ub);
> +	mem_cgroup_fill_meminfo(mem_cgroup_from_cont(css->cgroup), mi);
> +	css_put(css);
>  
>  	mi->locked = ub->ub_parms[UB_LOCKEDPAGES].held;
> -	mi->shmem = ub->ub_parms[UB_SHMPAGES].held;
> -	dcache = ub->ub_parms[UB_DCACHESIZE].held;
>  
>  	mi->dirty_pages = __ub_stat_get(ub, dirty_pages);
>  	mi->writeback_pages = __ub_stat_get(ub, writeback_pages);
> @@ -182,22 +183,11 @@ static int bc_fill_meminfo(struct user_beancounter *ub,
>  		struct ub_percpu_struct *pcpu = ub_percpu(ub, cpu);
>  
>  		mi->dirty_pages	+= pcpu->dirty_pages;
> -		mi->writeback_pages	+= pcpu->writeback_pages;
> +		mi->writeback_pages += pcpu->writeback_pages;
>  	}
>  
>  	mi->dirty_pages = max_t(long, 0, mi->dirty_pages);
>  	mi->writeback_pages = max_t(long, 0, mi->writeback_pages);
> -
> -	mi->slab_reclaimable = DIV_ROUND_UP(max(0L, dcache), PAGE_SIZE);
> -	mi->slab_unreclaimable =
> -		DIV_ROUND_UP(max(0L, (long)ub->ub_parms[UB_KMEMSIZE].held -
> -							dcache), PAGE_SIZE);
> -
> -	mi->cached = min(mi->si->totalram - mi->si->freeram -
> -			mi->slab_reclaimable - mi->slab_unreclaimable,
> -			mi->pages[LRU_INACTIVE_FILE] +
> -			mi->pages[LRU_ACTIVE_FILE] +
> -			ub->ub_parms[UB_SHMPAGES].held);
>  out:
>  	return ret;
>  }
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 034bc451705f..f6037581cf09 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -53,6 +53,7 @@
>  #include <linux/page_cgroup.h>
>  #include <linux/cpu.h>
>  #include <linux/oom.h>
> +#include <linux/virtinfo.h>
>  #include "internal.h"
>  #include <net/sock.h>
>  #include <net/ip.h>
> @@ -5002,6 +5003,24 @@ static unsigned long mem_cgroup_recursive_stat(struct mem_cgroup *memcg,
>  	return val;
>  }
>  
> +void mem_cgroup_fill_meminfo(struct mem_cgroup *memcg, struct meminfo *mi)
> +{
> +	int nid;
> +	unsigned long slab;
> +
> +	memset(&mi->pages, 0, sizeof(mi->pages));
> +	for_each_online_node(nid)
> +		mem_cgroup_get_nr_pages(memcg, nid, mi->pages);
> +
> +	slab = res_counter_read_u64(&memcg->kmem, RES_USAGE) >> PAGE_SHIFT;
> +	mi->slab_reclaimable = res_counter_read_u64(&memcg->dcache, RES_USAGE)
> +								>> PAGE_SHIFT;
> +	mi->slab_unreclaimable = max_t(long, slab - mi->slab_reclaimable, 0);
> +
> +	mi->cached = mem_cgroup_recursive_stat(memcg, MEM_CGROUP_STAT_CACHE);
> +	mi->shmem = mem_cgroup_recursive_stat(memcg, MEM_CGROUP_STAT_SHMEM);
> +}
> +
>  static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
>  {
>  	u64 val;
> 


More information about the Devel mailing list