lkml.org 
[lkml]   [2008]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC][PATCH 5/6] fix inactive_ratio under hierarchy

    From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>

    After lru updates for memcg, followint test easily see OOM.
    and memory-reclaim speed was very bad.

    mkdir /opt/cgroup/xxx
    echo 1 > /opt/cgroup/xxx/memory.use_hierarchy
    mkdir /opt/cgroup/xxx/01
    mkdir /opt/cgroup/xxx/02
    echo 40M > /opt/cgroup/xxx/memory.limit_in_bytes

    Run task under group 01 or 02.

    This is because calclation of inactive_ratio doesn't handle hierarchy.
    In above, 01 and 02's inactive_ratio = 65535 and inactive list will be
    empty.

    This patch tries to set 01 and 02 's inactive ration to appropriate value
    under hierarchy. inactive_ratio is adjusted to the minimum limit found in
    upwards in hierarchy.


    ex)In following tree,
    /opt/cgroup/01 limit=1G
    /opt/cgroup/01/A limit=500M
    /opt/cgroup/01/A/B limit=unlimited
    /opt/cgroup/01/A/C limit=50M
    /opt/cgroup/01/Z limit=700M


    /opt/cgroup/01's inactive_ratio is calculated by limit of 1G.
    /opt/cgroup/01/A's inactive_ratio is calculated by limit of 500M
    /opt/cgroup/01/A/B's inactive_ratio is calculated by limit of 500M.
    /opt/cgroup/01/A/C's inactive_ratio is calculated by limit of 50M.
    /opt/cgroup/01's inactive_ratio is calculated by limit of 700M.


    Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujisu.com>

    mm/memcontrol.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++------
    1 file changed, 64 insertions(+), 7 deletions(-)

    ---
    Index: mmotm-2.6.28-Dec08/mm/memcontrol.c
    ===================================================================
    --- mmotm-2.6.28-Dec08.orig/mm/memcontrol.c
    +++ mmotm-2.6.28-Dec08/mm/memcontrol.c
    @@ -1382,20 +1382,73 @@ int mem_cgroup_shrink_usage(struct mm_st
    * page_alloc.c::setup_per_zone_inactive_ratio().
    * it describe more detail.
    */
    -static void mem_cgroup_set_inactive_ratio(struct mem_cgroup *memcg)
    +static int __mem_cgroup_inactive_ratio(unsigned long long gb)
    {
    - unsigned int gb, ratio;
    + unsigned int ratio;

    - gb = res_counter_read_u64(&memcg->res, RES_LIMIT) >> 30;
    + gb = gb >> 30;
    if (gb)
    ratio = int_sqrt(10 * gb);
    else
    ratio = 1;

    - memcg->inactive_ratio = ratio;
    + return ratio;
    +}
    +
    +
    +static void mem_cgroup_update_inactive_ratio(struct mem_cgroup *memcg)
    +{
    + struct cgroup *cur;
    + struct mem_cgroup *root_memcg, *tmp;
    + unsigned long long min_limit, limit;
    + int depth, nextid, rootid, found, ratio;
    +
    + if (!memcg->use_hierarchy) {
    + limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
    + memcg->inactive_ratio = __mem_cgroup_inactive_ratio(limit);
    + return;
    + }

    + cur = memcg->css.cgroup;
    + min_limit = res_counter_read_u64(&tmp->res, RES_LIMIT);
    +
    + /* go up to root cgroup and find min limit.*/
    + while (cur->parent != NULL) {
    + tmp = mem_cgroup_from_cont(cur);
    + if (!tmp->use_hierarchy)
    + break;
    + limit = res_counter_read_u64(&tmp->res, RES_LIMIT);
    + if (limit < min_limit)
    + limit = min_limit;
    + cur = cur->parent;
    + }
    + /* new inactive ratio for this hierarchy */
    + ratio = __mem_cgroup_inactive_ratio(min_limit);
    +
    + /*
    + * update inactive ratio under this.
    + * all children's inactive_ratio will be updated.
    + */
    + cur = memcg->css.cgroup;
    + rootid = cgroup_id(cur);
    + depth = cgroup_depth(cur);
    + nextid = 0;
    + rcu_read_lock();
    + while (1) {
    + cur = cgroup_get_next(nextid, rootid, depth, &found);
    + if (!cur)
    + break;
    + if (!cgroup_is_removed(cur)) {
    + tmp = mem_cgroup_from_cont(cur);
    + tmp->inactive_ratio = ratio;
    + }
    + nextid = found + 1;
    + }
    + rcu_read_unlock();
    }

    +
    +
    static DEFINE_MUTEX(set_limit_mutex);

    static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,
    @@ -1435,8 +1488,11 @@ static int mem_cgroup_resize_limit(struc
    if (!progress) retry_count--;
    }

    - if (!ret)
    - mem_cgroup_set_inactive_ratio(memcg);
    + if (!ret) {
    + mutex_lock(&set_limit_mutex);
    + mem_cgroup_update_inactive_ratio(memcg);
    + mutex_unlock(&set_limit_mutex);
    + }

    return ret;
    }
    @@ -2081,11 +2137,12 @@ mem_cgroup_create(struct cgroup_subsys *
    if (parent && parent->use_hierarchy) {
    res_counter_init(&mem->res, &parent->res);
    res_counter_init(&mem->memsw, &parent->memsw);
    + /* min_limit under hierarchy is unchanged.*/
    + mem->inactive_ratio = parent->inactive_ratio;
    } else {
    res_counter_init(&mem->res, NULL);
    res_counter_init(&mem->memsw, NULL);
    }
    - mem_cgroup_set_inactive_ratio(mem);
    mem->last_scanned_child = 0;
    mem->scan_age = 0;
    spin_lock_init(&mem->reclaim_param_lock);


    \
     
     \ /
      Last update: 2008-12-09 12:13    [W:0.032 / U:29.488 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site