[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20081113131807.b2f22261.kamezawa.hiroyu@jp.fujitsu.com>
Date: Thu, 13 Nov 2008 13:18:07 +0900
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@...fujitsu.com>
To: balbir@...ux.vnet.ibm.com
Cc: linux-mm@...ck.org, YAMAMOTO Takashi <yamamoto@...inux.co.jp>,
Paul Menage <menage@...gle.com>, lizf@...fujitsu.com,
linux-kernel@...r.kernel.org,
Nick Piggin <nickpiggin@...oo.com.au>,
David Rientjes <rientjes@...gle.com>,
Pavel Emelianov <xemul@...nvz.org>,
Dhaval Giani <dhaval@...ux.vnet.ibm.com>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: Re: [RFC][mm] [PATCH 3/4] Memory cgroup hierarchical reclaim (v3)
On Wed, 12 Nov 2008 16:51:41 +0530
Balbir Singh <balbir@...ux.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);
}
}
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists