[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