Messages in this thread | | | Date | Thu, 13 Nov 2008 13:18:07 +0900 | From | KAMEZAWA Hiroyuki <> | Subject | Re: [RFC][mm] [PATCH 3/4] Memory cgroup hierarchical reclaim (v3) |
| |
On Wed, 12 Nov 2008 16:51:41 +0530 Balbir Singh <balbir@linux.vnet.ibm.com> wrote:
> Here is the iterative version of this patch. I tested it in my > test environment. NOTE: The cgroup_locked check is still present, I'll > remove that shortly after your patch is accepted. > > This patch introduces hierarchical reclaim. When an ancestor goes over its > limit, the charging routine points to the parent that is above its limit. > The reclaim process then starts from the last scanned child of the ancestor > and reclaims until the ancestor goes below its limit. >
complicated as you said but it seems it's from style.
I expected following kind of one. ==
struct mem_cgroup *memcg_select_next_token(struct mem_cgroup *itr, struct mem_cgroup *cur, struct mem_cgroup *root) { struct cgroup *pos, *tmp, *parent, *rootpos;
cgroup_lock(); if (!itr || itr->obsolete) itr = cur;
rootpos = root->css.cgroup; pos = itr->css.cgroup; parent = pos->parent; /* start from children */ if (!list_empty(&pos->children)) { pos = list_entry(pos->children.next, struct cgroup, sibling); mem_cgroup_put(itr); itr = mem_cgroup_from_cont(pos); mem_cgroup_get(itr); goto unlock; } next_parent: if (pos == rootpos) { /* I'm root and no available children */ mem_cgroup_put(itr); itr = mem_cgroup_from_cont(pos); mem_cgroup_get(itr); goto unlock; } /* Do I have next siblings ? */ if (pos->sibling.next != &parent->children) { pos = list_entry(pos->sibling.next, struct cgroup, sibling); mem_cgroup_put(itr); itr = mem_cgroup_from_cont(pos); mem_cgroup_get(itr); goto unlock; } /* Ok, go back to parent */ pos = pos->parent; goto next_parent; unlock: root->reclaim_token = token; cgroup_unlock(); return itr; }
struct mem_cgroup *memcg_select_start_token(struct mem_cgroup *cur, struct mem_cgroup *root) { struct mem_cgroup *token;
if (cur == root) return cur;
cgroup_lock();
token = root->reclaim_token; if (token->obsolete) { mem_cgroup_put(token); /* decrease refcnt */ root->reclaim_token = cur; token = cur; mem_cgroup_get(cur); /* increase refcnt */ cgroup_unlock(); return token; } cgroup_unlock(); return memcg_select_next_token(token, cur, root); }
int mem_cgroup_do_reclaim(struct mem_cgroup *mem, struct mem_cgroup *root_mem, gfp_t mask) { struct cgroup *cgroup; struct mem_cgroup *tmp, *token, *start; /* * We do memory reclaim under "root_mem". * We have to be careful not to reclaim memory only from * unlucky one. For avoiding that, we use "token". */
token = memcg_select_start_token(mem, root_mem);
start = NULL;
while (start != token) { if (!token->obsolete) { ret = try_to_free_mem_cgroup_pages(token, GFP_HIGHUSER_MOVABLE); if (!res_counter_check_under_limit(&root_mem->res)) return 0; if (ret == 0) retry--; start = token; token = memcg_select_next_token(token, mem, root_mem); } else { /* This mem_cgroup is destroyed. */ mem_cgroup_put(token); token = memcg_select_next_token(NULL, mem, root_mem); } } }
| |