OpenVZ Forum - RDF feed
type: channel
items: [RFC][PATCH] memory cgroup enhancements updated [0/10] intro
items: [RFC][PATCH] memory cgroup enhancements updated [1/10] try_to_free_mem_cgroup_pages bugfix
items: [RFC][PATCH] memory cgroup enhancements updated [2/10] force empty interface
items: [RFC][PATCH] memory cgroup enhancements updated [3/10] remember pagecache
items: [RFC][PATCH] memory cgroup enhancements updated [4/10] record page cgroup on active list
items: [RFC][PATCH] memory cgroup enhancements updated [5/10] per cpu accounting
items: [RFC][PATCH] memory cgroup enhancements updated [6/10] memory.stat interface
items: [RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
items: [RFC][PATCH] memory cgroup enhancements updated [8/10] add pre_destroy handler
items: [RFC][PATCH] memory cgroup enhancements updated [9/10] implicit force empty at rmdir
items: [RFC][PATCH] memory cgroup enhancements updated [10/10] NUMA aware account
items: Re: [RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
items: Re: [RFC][PATCH] memory cgroup enhancements updated [1/10] try_to_free_mem_cgroup_pages bugfix
items: Re: [RFC][PATCH] memory cgroup enhancements updated [2/10] force empty interface
items: Re: [RFC][PATCH] memory cgroup enhancements updated [3/10] remember pagecache
items: Re: [RFC][PATCH] memory cgroup enhancements updated [8/10] add pre_destroy handler
items: Re: [RFC][PATCH] memory cgroup enhancements updated [10/10] NUMA aware account

[RFC][PATCH] memory cgroup enhancements updated [0/10] intro
type: item
description: These patches are for memory cgroup on my queue. Just dumping before week-end. I'd like to post these against the next -mm. This is RFC again. Comments for previous version is reflected AMAP, thanks. Some of patches has no change. Several pathces are new. [1/10] fix try_to_free_mem_cgroup_pages() for NUMA (NEW) [2/10] force_empty for drop all page_cgroup in empty cgroup. (REFLESHED) [3/10] rememember page is charged as page cache (changed #define placement) [4/10] rememember page is on active list (changed #define placement) [5/10] per cpu memory cgroup accounting [6/10] show per cpu memory cgroup accounting [7/10] account failcnt for RSS and CACHE (NEW) [8/10] add pre_destroy handler for cgroup (NEW) [9/10] do force_empty at rmdir() implicitly (NEW) [10/10] NUMA-aware accounting. (NEW) Any comments are welcome. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:24:36-00:00

[RFC][PATCH] memory cgroup enhancements updated [1/10] try_to_free_mem_cgroup_pages bugfix
type: item
description: Because NODE_DATA(node)->node_zonelists[] is guaranteed to contain all necessary zones, it is not necessary to use for_each_online_node. And this for_each_online_node() makes reclaim routine start always from node 0. This is bad. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/vmscan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) Index: devel-2.6.23-mm1/mm/vmscan.c =================================================================== --- devel-2.6.23-mm1.orig/mm/vmscan.c +++ devel-2.6.23-mm1/mm/vmscan.c @@ -1375,15 +1375,13 @@ unsigned long try_to_free_mem_cgroup_pag .mem_cgroup = mem_cont, .isolate_pages = mem_cgroup_isolate_pages, }; - int node; + int node = numa_node_id(); struct zone **zones; int target_zone = gfp_zone(GFP_HIGHUSER_MOVABLE); - for_each_online_node(node) { - zones = NODE_DATA(node)->node_zonelists[target_zone].zones; - if (do_try_to_free_pages(zones, sc.gfp_mask, &sc)) + zones = NODE_DATA(node)->node_zonelists[target_zone].zones; + if (do_try_to_free_pages(zones, sc.gfp_mask, &sc)) return 1; - } return 0; } #endif _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:29:52-00:00

[RFC][PATCH] memory cgroup enhancements updated [2/10] force empty interface
type: item
description: This patch adds an interface "memory.force_empty". Any write to this file will drop all charges in this cgroup if there is no task under. %echo 1 > /....../memory.force_empty will drop all charges of memory cgroup if cgroup's tasks is empty. This is useful to invoke rmdir() against memory cgroup successfully. Tested and worked well on x86_64/fake-NUMA system. Changelog v4 -> v5: - added comments to mem_cgroup_force_empty() - made mem_force_empty_read return -EINVAL - cleanup mem_cgroup_force_empty_list() - removed SWAP_CLUSTER_MAX Changelog v3 -> v4: - adjusted to 2.6.23-mm1 - fixed typo - changes buf[2]="0" to static const Changelog v2 -> v3: - changed the name from force_reclaim to force_empty. Changelog v1 -> v2: - added a new interface force_reclaim. - changes spin_lock to spin_lock_irqsave(). Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/memcontrol.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 7 deletions(-) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -480,6 +480,7 @@ void mem_cgroup_uncharge(struct page_cgr page = pc->page; /* * get page->cgroup and clear it under lock. + * force_empty can drop page->cgroup without checking refcnt. */ if (clear_page_cgroup(page, pc) == pc) { mem = pc->mem_cgroup; @@ -489,13 +490,6 @@ void mem_cgroup_uncharge(struct page_cgr list_del_init(&pc->lru); spin_unlock_irqrestore(&mem->lru_lock, flags); kfree(pc); - } else { - /* - * Note:This will be removed when force-empty patch is - * applied. just show warning here. - */ - printk(KERN_ERR "Race in mem_cgroup_uncharge() ?"); - dump_stack(); } } } @@ -543,6 +537,76 @@ retry: return; } +/* + * This routine traverse page_cgroup in given list and drop them all. + * This routine ignores page_cgroup->ref_cnt. + * *And* this routine doesn't reclaim page itself, just rem…
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:30:31-00:00

[RFC][PATCH] memory cgroup enhancements updated [3/10] remember pagecache
type: item
description: Add PCGF_PAGECACHE flag to page_cgroup to remember "this page is charged as page-cache." This is very useful for implementing precise accounting in memory cgroup. Changelog v1 -> v2 - moved #define to out-side of struct definition Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> mm/memcontrol.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -83,7 +83,9 @@ struct page_cgroup { struct mem_cgroup *mem_cgroup; atomic_t ref_cnt; /* Helpful when pages move b/w */ /* mapped and cached states */ + int flags; }; +#define PCGF_PAGECACHE (0x1) /* charged as page-cache */ enum { MEM_CGROUP_TYPE_UNSPEC = 0, @@ -315,8 +317,8 @@ unsigned long mem_cgroup_isolate_pages(u * 0 if the charge was successful * < 0 if the cgroup is over its limit */ -int mem_cgroup_charge(struct page *page, struct mm_struct *mm, - gfp_t gfp_mask) +static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask, int is_cache) { struct mem_cgroup *mem; struct page_cgroup *pc; @@ -418,6 +420,10 @@ noreclaim: atomic_set(&pc->ref_cnt, 1); pc->mem_cgroup = mem; pc->page = page; + if (is_cache) + pc->flags = PCGF_PAGECACHE; + else + pc->flags = 0; if (page_cgroup_assign_new_page_cgroup(page, pc)) { /* * an another charge is added to this page already. @@ -442,6 +448,12 @@ err: return -ENOMEM; } +int mem_cgroup_charge(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask) +{ + return mem_cgroup_charge_common(page, mm, gfp_mask, 0); +} + /* * See if the cached pages should be charged at all? */ @@ -454,7 +466,7 @@ int mem_cgroup_cache_charge(struct page mem = rcu_dereference(mm->mem_cgroup); if (mem->control_type == MEM_CGROUP_TYPE_ALL) - return mem_cgroup_charge(page, mm, gfp_mask); + return mem…
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:31:06-00:00

[RFC][PATCH] memory cgroup enhancements updated [4/10] record page cgroup on active list
type: item
description: Remember page_cgroup is on active_list or not in page_cgroup->flags. Against 2.6.23-mm1. Changelog v1->v2 - moved #define to out-side of struct definition Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> mm/memcontrol.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -86,6 +86,7 @@ struct page_cgroup { int flags; }; #define PCGF_PAGECACHE (0x1) /* charged as page-cache */ +#define PCGF_ACTIVE (0x2) /* page_cgroup is on active list */ enum { MEM_CGROUP_TYPE_UNSPEC = 0, @@ -208,10 +209,13 @@ clear_page_cgroup(struct page *page, str static void __mem_cgroup_move_lists(struct page_cgroup *pc, bool active) { - if (active) + if (active) { + pc->flags |= PCGF_ACTIVE; list_move(&pc->lru, &pc->mem_cgroup->active_list); - else + } else { + pc->flags &= ~PCGF_ACTIVE; list_move(&pc->lru, &pc->mem_cgroup->inactive_list); + } } int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) @@ -421,9 +425,9 @@ noreclaim: pc->mem_cgroup = mem; pc->page = page; if (is_cache) - pc->flags = PCGF_PAGECACHE; + pc->flags = PCGF_PAGECACHE | PCGF_ACTIVE; else - pc->flags = 0; + pc->flags = PCGF_ACTIVE; if (page_cgroup_assign_new_page_cgroup(page, pc)) { /* * an another charge is added to this page already. _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:31:48-00:00

[RFC][PATCH] memory cgroup enhancements updated [5/10] per cpu accounting
type: item
description: Add statistics account infrastructure for memory controller. Changelog v1 -> v2 - Removed Charge/Uncharge counter - reflected comments. - changes __move_lists() args. - changes __mem_cgroup_stat_add() name, comment and added VM_BUGON Changes from original: - divided into 2 patch (account and show info) - changed from u64 to s64 - added mem_cgroup_stat_add() and batched statistics modification logic. - removed stat init code because mem_cgroup is allocated by kzalloc(). Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> mm/memcontrol.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 7 deletions(-) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -35,6 +35,64 @@ struct cgroup_subsys mem_cgroup_subsys; static const int MEM_CGROUP_RECLAIM_RETRIES = 5; /* + * Statistics for memory cgroup. + */ +enum mem_cgroup_stat_index { + /* + * For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss. + */ + MEM_CGROUP_STAT_PAGECACHE, /* # of pages charged as cache */ + MEM_CGROUP_STAT_RSS, /* # of pages charged as rss */ + + /* + * usage = charge - uncharge. + */ + MEM_CGROUP_STAT_ACTIVE, /* # of pages in active list */ + MEM_CGROUP_STAT_INACTIVE, /* # of pages on inactive list */ + + MEM_CGROUP_STAT_NSTATS, +}; + +struct mem_cgroup_stat_cpu { + s64 count[MEM_CGROUP_STAT_NSTATS]; +} ____cacheline_aligned_in_smp; + +struct mem_cgroup_stat { + struct mem_cgroup_stat_cpu cpustat[NR_CPUS]; +}; + +/* + * For batching....mem_cgroup_charge_statistics()(see below). + * MUST be called under preempt_disable(). + */ +static inline void __mem_cgroup_stat_add(struct mem_cgroup_stat *stat, + enum mem_cgroup_stat_index idx, int val) +{ + int cpu = smp_processor_id(); +#ifdef CONFIG_PREEMPT + VM_BUG_ON(preempt_count() == 0); +#endif + stat->cpus…
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:32:03-00:00

[RFC][PATCH] memory cgroup enhancements updated [6/10] memory.stat interface
type: item
description: Show accounted information of memory cgroup by memory.stat file Changelog v1->v2 - dropped Charge/Uncharge entry. Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/memcontrol.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -28,6 +28,7 @@ #include <linux/swap.h> #include <linux/spinlock.h> #include <linux/fs.h> +#include <linux/seq_file.h> #include <asm/uaccess.h> @@ -841,6 +842,53 @@ static ssize_t mem_force_empty_read(stru } +static const struct mem_cgroup_stat_desc { + const char *msg; + u64 unit; +} mem_cgroup_stat_desc[] = { + [MEM_CGROUP_STAT_PAGECACHE] = { "page_cache", PAGE_SIZE, }, + [MEM_CGROUP_STAT_RSS] = { "rss", PAGE_SIZE, }, + [MEM_CGROUP_STAT_ACTIVE] = { "active", PAGE_SIZE, }, + [MEM_CGROUP_STAT_INACTIVE] = { "inactive", PAGE_SIZE, }, +}; + +static int mem_control_stat_show(struct seq_file *m, void *arg) +{ + struct cgroup *cont = m->private; + struct mem_cgroup *mem_cont = mem_cgroup_from_cont(cont); + struct mem_cgroup_stat *stat = &mem_cont->stat; + int i; + + for (i = 0; i < ARRAY_SIZE(stat->cpustat[0].count); i++) { + unsigned int cpu; + s64 val; + + val = 0; + for (cpu = 0; cpu < NR_CPUS; cpu++) + val += stat->cpustat[cpu].count[i]; + val *= mem_cgroup_stat_desc[i].unit; + seq_printf(m, "%s %lld\n", mem_cgroup_stat_desc[i].msg, val); + } + return 0; +} + +static const struct file_operations mem_control_stat_file_operations = { + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int mem_control_stat_open(struct inode *unused, struct file *file) +{ + /* XXX __d_cont */ + struct cgroup *cont = file->f_dentry->d_parent->d_fsdata; + + file->f_op = &mem_control_stat_file_operations; + return single_open(file, mem…
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:33:08-00:00

[RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
type: item
description: cgroup's resource has "failure" counter. But I think memory cgroup has 2 types of failure - failure of cache - failure of RSS This patch adds above 2 information to stat file. Above information is shown in "byte". But I wonder showing just counter is better o not...rather than PAGE_SIZE. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/memcontrol.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -50,6 +50,11 @@ enum mem_cgroup_stat_index { */ MEM_CGROUP_STAT_ACTIVE, /* # of pages in active list */ MEM_CGROUP_STAT_INACTIVE, /* # of pages on inactive list */ + /* + * precise failcnt + */ + MEM_CGROUP_STAT_FAIL_RSS, /* # of failure in RSS charging */ + MEM_CGROUP_STAT_FAIL_CACHE,/* # of failure in CACHE charging */ MEM_CGROUP_STAT_NSTATS, }; @@ -486,6 +491,12 @@ retry: */ while (res_counter_charge(&mem->res, PAGE_SIZE)) { bool is_atomic = gfp_mask & GFP_ATOMIC; + if (is_cache) + mem_cgroup_stat_inc(&mem->stat, + MEM_CGROUP_STAT_FAIL_CACHE); + else + mem_cgroup_stat_inc(&mem->stat, + MEM_CGROUP_STAT_FAIL_RSS); /* * We cannot reclaim under GFP_ATOMIC, fail the charge */ @@ -850,6 +861,8 @@ static const struct mem_cgroup_stat_desc [MEM_CGROUP_STAT_RSS] = { "rss", PAGE_SIZE, }, [MEM_CGROUP_STAT_ACTIVE] = { "active", PAGE_SIZE, }, [MEM_CGROUP_STAT_INACTIVE] = { "inactive", PAGE_SIZE, }, + [MEM_CGROUP_STAT_FAIL_RSS] = { "rss_failure", PAGE_SIZE, }, + [MEM_CGROUP_STAT_FAIL_CACHE] = { "cache_failure", PAGE_SIZE, }, }; static int mem_control_stat_show(struct seq_file *m, void *arg) _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:34:52-00:00

[RFC][PATCH] memory cgroup enhancements updated [8/10] add pre_destroy handler
type: item
description: My main purpose of this patch is for memory controller.. This patch adds a handler "pre_destroy" to cgroup_subsys. It is called before cgroup_rmdir() checks all subsys's refcnt. I think this is useful for subsyses which have some extra refs even if there are no tasks in cgroup. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> include/linux/cgroup.h | 1 + kernel/cgroup.c | 7 +++++++ 2 files changed, 8 insertions(+) Index: devel-2.6.23-mm1/include/linux/cgroup.h =================================================================== --- devel-2.6.23-mm1.orig/include/linux/cgroup.h +++ devel-2.6.23-mm1/include/linux/cgroup.h @@ -233,6 +233,7 @@ int cgroup_is_descendant(const struct cg struct cgroup_subsys { struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss, struct cgroup *cont); + void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cont); void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont); int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cont, struct task_struct *tsk); Index: devel-2.6.23-mm1/kernel/cgroup.c =================================================================== --- devel-2.6.23-mm1.orig/kernel/cgroup.c +++ devel-2.6.23-mm1/kernel/cgroup.c @@ -2158,6 +2158,13 @@ static int cgroup_rmdir(struct inode *un parent = cont->parent; root = cont->root; sb = root->sb; + /* + * Notify subsyses that rmdir() request comes. + */ + for_each_subsys(root, ss) { + if ((cont->subsys[ss->subsys_id]) && ss->pre_destroy) + ss->pre_destroy(ss, cont); + } if (cgroup_has_css_refs(cont)) { mutex_unlock(&cgroup_mutex); _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:35:44-00:00

[RFC][PATCH] memory cgroup enhancements updated [9/10] implicit force empty at rmdir
type: item
description: This patch adds pre_destroy handler for mem_cgroup and try to make mem_cgroup empty at rmdir(). Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/memcontrol.c | 8 ++++++++ 1 file changed, 8 insertions(+) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -959,6 +959,13 @@ mem_cgroup_create(struct cgroup_subsys * return &mem->css; } +static void mem_cgroup_pre_destroy(struct cgroup_subsys *ss, + struct cgroup *cont) +{ + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); + mem_cgroup_force_empty(mem); +} + static void mem_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cont) { @@ -1010,6 +1017,7 @@ struct cgroup_subsys mem_cgroup_subsys = .name = "memory", .subsys_id = mem_cgroup_subsys_id, .create = mem_cgroup_create, + .pre_destroy = mem_cgroup_pre_destroy, .destroy = mem_cgroup_destroy, .populate = mem_cgroup_populate, .attach = mem_cgroup_move_task, _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:36:27-00:00

[RFC][PATCH] memory cgroup enhancements updated [10/10] NUMA aware account
type: item
description: This patch is a trial for making stat for memory_cgroup NUMA-aware. * dividing per-cpu stat to handle nid information. * add nid information to page_cgroup * Because init routine has to call kmalloc, init_early is set to be 0. This is just a trial at this stage. Any comments are welcome. Works well on my fake NUMA system. I think we can add "numastat" based on this. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> mm/memcontrol.c | 97 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 26 deletions(-) Index: devel-2.6.23-mm1/mm/memcontrol.c =================================================================== --- devel-2.6.23-mm1.orig/mm/memcontrol.c +++ devel-2.6.23-mm1/mm/memcontrol.c @@ -29,6 +29,7 @@ #include <linux/spinlock.h> #include <linux/fs.h> #include <linux/seq_file.h> +#include <linux/vmalloc.h> #include <asm/uaccess.h> @@ -59,12 +60,18 @@ enum mem_cgroup_stat_index { MEM_CGROUP_STAT_NSTATS, }; +#ifndef CONFIG_NUMA struct mem_cgroup_stat_cpu { - s64 count[MEM_CGROUP_STAT_NSTATS]; + s64 count[1][MEM_CGROUP_STAT_NSTATS]; } ____cacheline_aligned_in_smp; +#else +struct mem_cgroup_stat_cpu { + s64 count[MAX_NUMNODES][MEM_CGROUP_STAT_NSTATS]; +} ____cacheline_aligned_in_smp; +#endif struct mem_cgroup_stat { - struct mem_cgroup_stat_cpu cpustat[NR_CPUS]; + struct mem_cgroup_stat_cpu *cpustat[NR_CPUS]; }; /* @@ -72,28 +79,28 @@ struct mem_cgroup_stat { * MUST be called under preempt_disable(). */ static inline void __mem_cgroup_stat_add(struct mem_cgroup_stat *stat, - enum mem_cgroup_stat_index idx, int val) + enum mem_cgroup_stat_index idx, int nid, int val) { int cpu = smp_processor_id(); #ifdef CONFIG_PREEMPT VM_BUG_ON(preempt_count() == 0); #endif - stat->cpustat[cpu].count[idx] += val; + stat->cpustat[cpu]->count[nid][idx] += val; } static inline void mem_cgroup_stat_inc(struct mem_cgroup_stat *stat, - enum mem_cgroup_stat_index idx) + enum mem_cgroup_stat_index idx, int nid) { preempt_disable(); - __me…
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T09:37:30-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
type: item
description: On 10/19/07, KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote: > cgroup's resource has "failure" counter. But I think memory cgroup > has 2 types of failure > - failure of cache > - failure of RSS Why do you think these are significantly different? Also, what kind of failure do we get when a task tries to fault on a mapping for a file-backed VMA? That's both RSS (since it's due to be mapped into the process' memory) and pagecache (assuming a cache-backed filesystem). Paul _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: Paul Menage
date: 2007-10-19T16:54:23-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
type: item
description: On Fri, 19 Oct 2007 09:54:23 -0700 "Paul Menage" <menage@google.com> wrote: > On 10/19/07, KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote: > > cgroup's resource has "failure" counter. But I think memory cgroup > > has 2 types of failure > > - failure of cache > > - failure of RSS > > Why do you think these are significantly different? Also, what kind of > failure do we get when a task tries to fault on a mapping for a > file-backed VMA? That's both RSS (since it's due to be mapped into the > process' memory) and pagecache (assuming a cache-backed filesystem). > One is for checking how memory cgroup works. When memory reaches limit and amount of CACHE doesn't change but CACHE.failure increases, maybe CACHE is rotating. One is for debug, I'd like to check swapiness <-> RSS.failure:CACHE.failure releationship. It's ok to turn these params to be DEBUG option. File-backed VMA gets RSS.failure. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T22:33:38-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [7/10] RSS/CACHE failcnt
type: item
description: On Sat, 20 Oct 2007 07:33:38 +0900 KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote: > One is for debug, I'd like to check swapiness <-> RSS.failure:CACHE.failure > releationship. It's ok to turn these params to be DEBUG option. > AH...but it's maybe better to check # of page fault in cgroup directly. I'll consider again. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-19T22:40:26-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [1/10] try_to_free_mem_cgroup_pages bugfix
type: item
description: KAMEZAWA Hiroyuki wrote: > Because NODE_DATA(node)->node_zonelists[] is guaranteed to contain > all necessary zones, it is not necessary to use for_each_online_node. > > And this for_each_online_node() makes reclaim routine start always > from node 0. This is bad. > But with this change, we'll start reclaim on the node that the task hit the limit on - right? > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > > > > mm/vmscan.c | 8 +++----- > 1 file changed, 3 insertions(+), 5 deletions(-) > > Index: devel-2.6.23-mm1/mm/vmscan.c > =================================================================== > --- devel-2.6.23-mm1.orig/mm/vmscan.c > +++ devel-2.6.23-mm1/mm/vmscan.c > @@ -1375,15 +1375,13 @@ unsigned long try_to_free_mem_cgroup_pag > .mem_cgroup = mem_cont, > .isolate_pages = mem_cgroup_isolate_pages, > }; > - int node; > + int node = numa_node_id(); > struct zone **zones; > int target_zone = gfp_zone(GFP_HIGHUSER_MOVABLE); > > - for_each_online_node(node) { > - zones = NODE_DATA(node)->node_zonelists[target_zone].zones; > - if (do_try_to_free_pages(zones, sc.gfp_mask, &sc)) > + zones = NODE_DATA(node)->node_zonelists[target_zone].zones; > + if (do_try_to_free_pages(zones, sc.gfp_mask, &sc)) > return 1; > - } > return 0; > } > #endif > -- Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: Balbir Singh
date: 2007-10-23T04:00:53-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [1/10] try_to_free_mem_cgroup_pages bugfix
type: item
description: On Tue, 23 Oct 2007 09:30:53 +0530 Balbir Singh <balbir@linux.vnet.ibm.com> wrote: > KAMEZAWA Hiroyuki wrote: > > Because NODE_DATA(node)->node_zonelists[] is guaranteed to contain > > all necessary zones, it is not necessary to use for_each_online_node. > > > > And this for_each_online_node() makes reclaim routine start always > > from node 0. This is bad. > > > > But with this change, we'll start reclaim on the node that the task > hit the limit on - right? > yes. I wonder it can be changed if we have precise information and some logic. But no concrete idea of better logic now. -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-23T04:19:14-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [2/10] force empty interface
type: item
description: KAMEZAWA Hiroyuki wrote: > This patch adds an interface "memory.force_empty". > Any write to this file will drop all charges in this cgroup if > there is no task under. > > %echo 1 > /....../memory.force_empty > > will drop all charges of memory cgroup if cgroup's tasks is empty. > > This is useful to invoke rmdir() against memory cgroup successfully. > > Tested and worked well on x86_64/fake-NUMA system. > > Changelog v4 -> v5: > - added comments to mem_cgroup_force_empty() > - made mem_force_empty_read return -EINVAL > - cleanup mem_cgroup_force_empty_list() > - removed SWAP_CLUSTER_MAX > > Changelog v3 -> v4: > - adjusted to 2.6.23-mm1 > - fixed typo > - changes buf[2]="0" to static const > > Changelog v2 -> v3: > - changed the name from force_reclaim to force_empty. > > Changelog v1 -> v2: > - added a new interface force_reclaim. > - changes spin_lock to spin_lock_irqsave(). > > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > > > mm/memcontrol.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 103 insertions(+), 7 deletions(-) > > Index: devel-2.6.23-mm1/mm/memcontrol.c > =================================================================== > --- devel-2.6.23-mm1.orig/mm/memcontrol.c > +++ devel-2.6.23-mm1/mm/memcontrol.c > @@ -480,6 +480,7 @@ void mem_cgroup_uncharge(struct page_cgr > page = pc->page; > /* > * get page->cgroup and clear it under lock. > + * force_empty can drop page->cgroup without checking refcnt. > */ > if (clear_page_cgroup(page, pc) == pc) { > mem = pc->mem_cgroup; > @@ -489,13 +490,6 @@ void mem_cgroup_uncharge(struct page_cgr > list_del_init(&pc->lru); > spin_unlock_irqrestore(&mem->lru_lock, flags); > kfree(pc); > - } else { > - /* > - * Note:This will be removed when force-empty patch is > - * applied. just show warning here. > - */ > - printk(KERN_ERR "Race in mem_cgroup_uncharge() ?"); > - dump_stack(); > } > } > } > @@ -543,6 +537,76 @@ retry: > return; > } > > +/* > + * This routin…
creator: Balbir Singh
date: 2007-10-24T13:52:00-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [3/10] remember pagecache
type: item
description: KAMEZAWA Hiroyuki wrote: > Add PCGF_PAGECACHE flag to page_cgroup to remember "this page is > charged as page-cache." > This is very useful for implementing precise accounting in memory cgroup. > > Changelog v1 -> v2 > - moved #define to out-side of struct definition > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> > > mm/memcontrol.c | 18 +++++++++++++++--- > 1 file changed, 15 insertions(+), 3 deletions(-) > > Index: devel-2.6.23-mm1/mm/memcontrol.c > =================================================================== > --- devel-2.6.23-mm1.orig/mm/memcontrol.c > +++ devel-2.6.23-mm1/mm/memcontrol.c > @@ -83,7 +83,9 @@ struct page_cgroup { > struct mem_cgroup *mem_cgroup; > atomic_t ref_cnt; /* Helpful when pages move b/w */ > /* mapped and cached states */ > + int flags; > }; > +#define PCGF_PAGECACHE (0x1) /* charged as page-cache */ > > enum { > MEM_CGROUP_TYPE_UNSPEC = 0, > @@ -315,8 +317,8 @@ unsigned long mem_cgroup_isolate_pages(u > * 0 if the charge was successful > * < 0 if the cgroup is over its limit > */ > -int mem_cgroup_charge(struct page *page, struct mm_struct *mm, > - gfp_t gfp_mask) > +static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, > + gfp_t gfp_mask, int is_cache) > { > struct mem_cgroup *mem; > struct page_cgroup *pc; > @@ -418,6 +420,10 @@ noreclaim: > atomic_set(&pc->ref_cnt, 1); > pc->mem_cgroup = mem; > pc->page = page; > + if (is_cache) > + pc->flags = PCGF_PAGECACHE; I prefer PAGE_CGROUP_CACHE since cache can be page cache/swap cache. > + else > + pc->flags = 0; > if (page_cgroup_assign_new_page_cgroup(page, pc)) { > /* > * an another charge is added to this page already. > @@ -442,6 +448,12 @@ err: > return -ENOMEM; > } > > +int mem_cgroup_charge(struct page *page, struct mm_struct *mm, > + gfp_t gfp_mask) > +{ > + return mem_cgroup_charge_common(page, mm, gfp_mask, 0); Could we define enum { MEM_CGROUP_CHARGE_TYPE_CACHE = 0, MEM…
creator: Balbir Singh
date: 2007-10-24T13:56:34-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [8/10] add pre_destroy handler
type: item
description: KAMEZAWA Hiroyuki wrote: > My main purpose of this patch is for memory controller.. > > This patch adds a handler "pre_destroy" to cgroup_subsys. > It is called before cgroup_rmdir() checks all subsys's refcnt. > > I think this is useful for subsyses which have some extra refs > even if there are no tasks in cgroup. > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > > include/linux/cgroup.h | 1 + > kernel/cgroup.c | 7 +++++++ > 2 files changed, 8 insertions(+) > > Index: devel-2.6.23-mm1/include/linux/cgroup.h > =================================================================== > --- devel-2.6.23-mm1.orig/include/linux/cgroup.h > +++ devel-2.6.23-mm1/include/linux/cgroup.h > @@ -233,6 +233,7 @@ int cgroup_is_descendant(const struct cg > struct cgroup_subsys { > struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss, > struct cgroup *cont); > + void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cont); > void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont); > int (*can_attach)(struct cgroup_subsys *ss, > struct cgroup *cont, struct task_struct *tsk); > Index: devel-2.6.23-mm1/kernel/cgroup.c > =================================================================== > --- devel-2.6.23-mm1.orig/kernel/cgroup.c > +++ devel-2.6.23-mm1/kernel/cgroup.c > @@ -2158,6 +2158,13 @@ static int cgroup_rmdir(struct inode *un > parent = cont->parent; > root = cont->root; > sb = root->sb; > + /* > + * Notify subsyses that rmdir() request comes. > + */ > + for_each_subsys(root, ss) { > + if ((cont->subsys[ss->subsys_id]) && ss->pre_destroy) > + ss->pre_destroy(ss, cont); > + } > Is pre_destroy really required? Can't we do what we do here in destroy? > if (cgroup_has_css_refs(cont)) { > mutex_unlock(&cgroup_mutex); > -- Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/co…
creator: Balbir Singh
date: 2007-10-24T14:49:34-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [10/10] NUMA aware account
type: item
description: KAMEZAWA Hiroyuki wrote: > This patch is a trial for making stat for memory_cgroup NUMA-aware. > > * dividing per-cpu stat to handle nid information. > * add nid information to page_cgroup > * Because init routine has to call kmalloc, init_early is set to be 0. > > This is just a trial at this stage. Any comments are welcome. > Works well on my fake NUMA system. > I think we can add "numastat" based on this. > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > > > mm/memcontrol.c | 97 ++++++++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 71 insertions(+), 26 deletions(-) > > Index: devel-2.6.23-mm1/mm/memcontrol.c > =================================================================== > --- devel-2.6.23-mm1.orig/mm/memcontrol.c > +++ devel-2.6.23-mm1/mm/memcontrol.c > @@ -29,6 +29,7 @@ > #include <linux/spinlock.h> > #include <linux/fs.h> > #include <linux/seq_file.h> > +#include <linux/vmalloc.h> > > #include <asm/uaccess.h> > > @@ -59,12 +60,18 @@ enum mem_cgroup_stat_index { > MEM_CGROUP_STAT_NSTATS, > }; > > +#ifndef CONFIG_NUMA > struct mem_cgroup_stat_cpu { > - s64 count[MEM_CGROUP_STAT_NSTATS]; > + s64 count[1][MEM_CGROUP_STAT_NSTATS]; > } ____cacheline_aligned_in_smp; > +#else > +struct mem_cgroup_stat_cpu { > + s64 count[MAX_NUMNODES][MEM_CGROUP_STAT_NSTATS]; > +} ____cacheline_aligned_in_smp; > +#endif > > struct mem_cgroup_stat { > - struct mem_cgroup_stat_cpu cpustat[NR_CPUS]; > + struct mem_cgroup_stat_cpu *cpustat[NR_CPUS]; > }; > > /* > @@ -72,28 +79,28 @@ struct mem_cgroup_stat { > * MUST be called under preempt_disable(). > */ > static inline void __mem_cgroup_stat_add(struct mem_cgroup_stat *stat, > - enum mem_cgroup_stat_index idx, int val) > + enum mem_cgroup_stat_index idx, int nid, int val) > { > int cpu = smp_processor_id(); > #ifdef CONFIG_PREEMPT > VM_BUG_ON(preempt_count() == 0); > #endif > - stat->cpustat[cpu].count[idx] += val; > + stat->cpustat[cpu]->count[nid][idx] += val; > } > > static inline void…
creator: Balbir Singh
date: 2007-10-24T14:59:08-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [8/10] add pre_destroy handler
type: item
description: On Wed, 24 Oct 2007 20:19:34 +0530 Balbir Singh <balbir@linux.vnet.ibm.com> wrote: > > + /* > > + * Notify subsyses that rmdir() request comes. > > + */ > > + for_each_subsys(root, ss) { > > + if ((cont->subsys[ss->subsys_id]) && ss->pre_destroy) > > + ss->pre_destroy(ss, cont); > > + } > > > > Is pre_destroy really required? Can't we do what we do here in destroy? > I think keeping "we can destroy cgroup only when refcnt=0" semantics is better. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-24T15:46:14-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [3/10] remember pagecache
type: item
description: On Wed, 24 Oct 2007 19:26:34 +0530 Balbir Singh <balbir@linux.vnet.ibm.com> wrote: > Could we define > > enum { > MEM_CGROUP_CHARGE_TYPE_CACHE = 0, > MEM_CGROUP_CHARGE_TYPE_MAPPED = 1, > }; > > and use the enums here and below. > Okay, I'll use this approach. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-24T15:47:24-00:00

Re: [RFC][PATCH] memory cgroup enhancements updated [10/10] NUMA aware account
type: item
description: On Wed, 24 Oct 2007 20:29:08 +0530 Balbir Singh <balbir@linux.vnet.ibm.com> wrote: > > + for_each_possible_cpu(cpu) { > > + int nid = cpu_to_node(cpu); > > + struct mem_cgroup_stat_cpu *mcsc; > > + if (sizeof(*mcsc) < PAGE_SIZE) > > + mcsc = kmalloc_node(sizeof(*mcsc), GFP_KERNEL, nid); > > + else > > + mcsc = vmalloc_node(sizeof(*mcsc), nid); > > Do we need to use the vmalloc() pool? I think we might be better off > using a dedicated slab for ourselves > I admit this part is complicated. But ia64's MAX_NUMNODES=1024 and stat can be increased. we need vmalloc. I'll rewrite this part to be better looking. > > + memset(mcsc, 0, sizeof(*mcsc)); > > + mem->stat.cpustat[cpu] = mcsc; > > + } > > return &mem->css; > > } > > > > @@ -969,7 +1006,15 @@ static void mem_cgroup_pre_destroy(struc > > static void mem_cgroup_destroy(struct cgroup_subsys *ss, > > struct cgroup *cont) > > { > > - kfree(mem_cgroup_from_cont(cont)); > > + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); > > + int cpu; > > + for_each_possible_cpu(cpu) { > > + if (sizeof(struct mem_cgroup_stat_cpu) < PAGE_SIZE) > > + kfree(mem->stat.cpustat[cpu]); > > + else > > + vfree(mem->stat.cpustat[cpu]); > > + } > > + kfree(mem); > > } > > > > static int mem_cgroup_populate(struct cgroup_subsys *ss, > > @@ -1021,5 +1066,5 @@ struct cgroup_subsys mem_cgroup_subsys = > > .destroy = mem_cgroup_destroy, > > .populate = mem_cgroup_populate, > > .attach = mem_cgroup_move_task, > > - .early_init = 1, > > + .early_init = 0, > > I don't understand why this change is required here? > If early_init = 1, we cannot call kmalloc/vmalloc at initializing init_mem_cgroup. It's too early. Thanks, -Kame _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: KAMEZAWA Hiroyuki
date: 2007-10-24T15:53:04-00:00