08 May, 2013

1 commit

  • This exports the amount of anonymous transparent hugepages for each
    memcg via the new "rss_huge" stat in memory.stat. The units are in
    bytes.

    This is helpful to determine the hugepage utilization for individual
    jobs on the system in comparison to rss and opportunities where
    MADV_HUGEPAGE may be helpful.

    The amount of anonymous transparent hugepages is also included in "rss"
    for backwards compatibility.

    Signed-off-by: David Rientjes
    Acked-by: Michal Hocko
    Acked-by: Johannes Weiner
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Rientjes
     

30 Apr, 2013

12 commits

  • Pull cgroup updates from Tejun Heo:

    - Fixes and a lot of cleanups. Locking cleanup is finally complete.
    cgroup_mutex is no longer exposed to individual controlelrs which
    used to cause nasty deadlock issues. Li fixed and cleaned up quite a
    bit including long standing ones like racy cgroup_path().

    - device cgroup now supports proper hierarchy thanks to Aristeu.

    - perf_event cgroup now supports proper hierarchy.

    - A new mount option "__DEVEL__sane_behavior" is added. As indicated
    by the name, this option is to be used for development only at this
    point and generates a warning message when used. Unfortunately,
    cgroup interface currently has too many brekages and inconsistencies
    to implement a consistent and unified hierarchy on top. The new flag
    is used to collect the behavior changes which are necessary to
    implement consistent unified hierarchy. It's likely that this flag
    won't be used verbatim when it becomes ready but will be enabled
    implicitly along with unified hierarchy.

    The option currently disables some of broken behaviors in cgroup core
    and also .use_hierarchy switch in memcg (will be routed through -mm),
    which can be used to make very unusual hierarchy where nesting is
    partially honored. It will also be used to implement hierarchy
    support for blk-throttle which would be impossible otherwise without
    introducing a full separate set of control knobs.

    This is essentially versioning of interface which isn't very nice but
    at this point I can't see any other options which would allow keeping
    the interface the same while moving towards hierarchy behavior which
    is at least somewhat sane. The planned unified hierarchy is likely
    to require some level of adaptation from userland anyway, so I think
    it'd be best to take the chance and update the interface such that
    it's supportable in the long term.

    Maintaining the existing interface does complicate cgroup core but
    shouldn't put too much strain on individual controllers and I think
    it'd be manageable for the foreseeable future. Maybe we'll be able
    to drop it in a decade.

    Fix up conflicts (including a semantic one adding a new #include to ppc
    that was uncovered by header the file changes) as per Tejun.

    * 'for-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (45 commits)
    cpuset: fix compile warning when CONFIG_SMP=n
    cpuset: fix cpu hotplug vs rebuild_sched_domains() race
    cpuset: use rebuild_sched_domains() in cpuset_hotplug_workfn()
    cgroup: restore the call to eventfd->poll()
    cgroup: fix use-after-free when umounting cgroupfs
    cgroup: fix broken file xattrs
    devcg: remove parent_cgroup.
    memcg: force use_hierarchy if sane_behavior
    cgroup: remove cgrp->top_cgroup
    cgroup: introduce sane_behavior mount option
    move cgroupfs_root to include/linux/cgroup.h
    cgroup: convert cgroupfs_root flag bits to masks and add CGRP_ prefix
    cgroup: make cgroup_path() not print double slashes
    Revert "cgroup: remove bind() method from cgroup_subsys."
    perf: make perf_event cgroup hierarchical
    cgroup: implement cgroup_is_descendant()
    cgroup: make sure parent won't be destroyed before its children
    cgroup: remove bind() method from cgroup_subsys.
    devcg: remove broken_hierarchy tag
    cgroup: remove cgroup_lock_is_held()
    ...

    Linus Torvalds
     
  • The memcg is not referenced, so it can be destroyed at anytime right
    after we exit rcu read section, so it's not safe to access it.

    To fix this, we call css_tryget() to get a reference while we're still
    in rcu read section.

    This also removes a bogus comment above __memcg_create_cache_enqueue().

    Signed-off-by: Li Zefan
    Acked-by: Glauber Costa
    Acked-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Li Zefan
     
  • A memcg may livelock when oom if the process that grabs the hierarchy's
    oom lock is never the first process with PF_EXITING set in the memcg's
    task iteration.

    The oom killer, both global and memcg, will defer if it finds an
    eligible process that is in the process of exiting and it is not being
    ptraced. The idea is to allow it to exit without using memory reserves
    before needlessly killing another process.

    This normally works fine except in the memcg case with a large number of
    threads attached to the oom memcg. In this case, the memcg oom killer
    only gets called for the process that grabs the hierarchy's oom lock;
    all others end up blocked on the memcg's oom waitqueue. Thus, if the
    process that grabs the hierarchy's oom lock is never the first
    PF_EXITING process in the memcg's task iteration, the oom killer is
    constantly deferred without anything making progress.

    The fix is to give PF_EXITING processes access to memory reserves so
    that we've marked them as oom killed without any iteration. This allows
    __mem_cgroup_try_charge() to succeed so that the process may exit. This
    makes the memcg oom killer exemption for TIF_MEMDIE tasks, now
    immediately granted for processes with pending SIGKILLs and those in the
    exit path, to be equivalent to what is done for the global oom killer.

    Signed-off-by: David Rientjes
    Acked-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Acked-by: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Rientjes
     
  • This might cause a use-after-free bug.

    Signed-off-by: Li Zefan
    Cc: Glauber Costa
    Acked-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Li Zefan
     
  • With this patch userland applications that want to maintain the
    interactivity/memory allocation cost can use the pressure level
    notifications. The levels are defined like this:

    The "low" level means that the system is reclaiming memory for new
    allocations. Monitoring this reclaiming activity might be useful for
    maintaining cache level. Upon notification, the program (typically
    "Activity Manager") might analyze vmstat and act in advance (i.e.
    prematurely shutdown unimportant services).

    The "medium" level means that the system is experiencing medium memory
    pressure, the system might be making swap, paging out active file
    caches, etc. Upon this event applications may decide to further analyze
    vmstat/zoneinfo/memcg or internal memory usage statistics and free any
    resources that can be easily reconstructed or re-read from a disk.

    The "critical" level means that the system is actively thrashing, it is
    about to out of memory (OOM) or even the in-kernel OOM killer is on its
    way to trigger. Applications should do whatever they can to help the
    system. It might be too late to consult with vmstat or any other
    statistics, so it's advisable to take an immediate action.

    The events are propagated upward until the event is handled, i.e. the
    events are not pass-through. Here is what this means: for example you
    have three cgroups: A->B->C. Now you set up an event listener on
    cgroups A, B and C, and suppose group C experiences some pressure. In
    this situation, only group C will receive the notification, i.e. groups
    A and B will not receive it. This is done to avoid excessive
    "broadcasting" of messages, which disturbs the system and which is
    especially bad if we are low on memory or thrashing. So, organize the
    cgroups wisely, or propagate the events manually (or, ask us to
    implement the pass-through events, explaining why would you need them.)

    Performance wise, the memory pressure notifications feature itself is
    lightweight and does not require much of bookkeeping, in contrast to the
    rest of memcg features. Unfortunately, as of current memcg
    implementation, pages accounting is an inseparable part and cannot be
    turned off. The good news is that there are some efforts[1] to improve
    the situation; plus, implementing the same, fully API-compatible[2]
    interface for CONFIG_MEMCG=n case (e.g. embedded) is also a viable
    option, so it will not require any changes on the userland side.

    [1] http://permalink.gmane.org/gmane.linux.kernel.cgroups/6291
    [2] http://lkml.org/lkml/2013/2/21/454

    [akpm@linux-foundation.org: coding-style fixes]
    [akpm@linux-foundation.org: fix CONFIG_CGROPUPS=n warnings]
    Signed-off-by: Anton Vorontsov
    Acked-by: Kirill A. Shutemov
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Tejun Heo
    Cc: David Rientjes
    Cc: Pekka Enberg
    Cc: Mel Gorman
    Cc: Glauber Costa
    Cc: Michal Hocko
    Cc: Luiz Capitulino
    Cc: Greg Thelen
    Cc: Leonid Moiseichuk
    Cc: KOSAKI Motohiro
    Cc: Minchan Kim
    Cc: Bartlomiej Zolnierkiewicz
    Cc: John Stultz
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Anton Vorontsov
     
  • Just a trivial issue I stumbled on while doing something else...

    Signed-off-by: Michel Lespinasse
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michel Lespinasse
     
  • Since commit 2d11085e404f ("memcg: do not create memsw files if swap
    accounting is disabled") memsw files are created only if memcg swap
    accounting is enabled so it doesn't make any sense to check for it
    explicitly in mem_cgroup_read(), mem_cgroup_write() and
    mem_cgroup_reset().

    Signed-off-by: Michal Hocko
    Cc: Kamezawa Hiroyuki
    Cc: Tejun Heo
    Acked-by: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • mem_cgroup_iter basically does two things currently. It takes care of
    the house keeping (reference counting, raclaim cookie) and it iterates
    through a hierarchy tree (by using cgroup generic tree walk). The code
    would be much more easier to follow if we move the iteration outside of
    the function (to __mem_cgrou_iter_next) so the distinction is more
    clear. This patch doesn't introduce any functional changes.

    Signed-off-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Johannes Weiner
    Cc: Li Zefan
    Cc: Ying Han
    Cc: Tejun Heo
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • The current implementation of mem_cgroup_iter has to consider both css
    and memcg to find out whether no group has been found (css==NULL - aka
    the loop is completed) and that no memcg is associated with the found
    node (!memcg - aka css_tryget failed because the group is no longer
    alive). This leads to awkward tweaks like tests for css && !memcg to
    skip the current node.

    It will be much easier if we got rid off css variable altogether and
    only rely on memcg. In order to do that the iteration part has to skip
    dead nodes. This sounds natural to me and as a nice side effect we will
    get a simple invariant that memcg is always alive when non-NULL and all
    nodes have been visited otherwise.

    We could get rid of the surrounding while loop but keep it in for now to
    make review easier. It will go away in the following patch.

    Signed-off-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Johannes Weiner
    Cc: Li Zefan
    Cc: Ying Han
    Cc: Tejun Heo
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • Now that the per-node-zone-priority iterator caches memory cgroups
    rather than their css ids we have to be careful and remove them from the
    iterator when they are on the way out otherwise they might live for
    unbounded amount of time even though their group is already gone (until
    the global/targeted reclaim triggers the zone under priority to find out
    the group is dead and let it to find the final rest).

    We can fix this issue by relaxing rules for the last_visited memcg.
    Instead of taking a reference to the css before it is stored into
    iter->last_visited we can just store its pointer and track the number of
    removed groups from each memcg's subhierarchy.

    This number would be stored into iterator everytime when a memcg is
    cached. If the iter count doesn't match the curent walker root's one we
    will start from the root again. The group counter is incremented
    upwards the hierarchy every time a group is removed.

    The iter_lock can be dropped because racing iterators cannot leak the
    reference anymore as the reference count is not elevated for
    last_visited when it is cached.

    Locking rules got a bit complicated by this change though. The iterator
    primarily relies on rcu read lock which makes sure that once we see a
    valid last_visited pointer then it will be valid for the whole RCU walk.
    smp_rmb makes sure that dead_count is read before last_visited and
    last_dead_count while smp_wmb makes sure that last_visited is updated
    before last_dead_count so the up-to-date last_dead_count cannot point to
    an outdated last_visited. css_tryget then makes sure that the
    last_visited is still alive in case the iteration races with the cached
    group removal (css is invalidated before mem_cgroup_css_offline
    increments dead_count).

    In short:
    mem_cgroup_iter
    rcu_read_lock()
    dead_count = atomic_read(parent->dead_count)
    smp_rmb()
    if (dead_count != iter->last_dead_count)
    last_visited POSSIBLY INVALID -> last_visited = NULL
    if (!css_tryget(iter->last_visited))
    last_visited DEAD -> last_visited = NULL
    next = find_next(last_visited)
    css_tryget(next)
    css_put(last_visited) // css would be invalidated and parent->dead_count
    // incremented if this was the last reference
    iter->last_visited = next
    smp_wmb()
    iter->last_dead_count = dead_count
    rcu_read_unlock()

    cgroup_rmdir
    cgroup_destroy_locked
    atomic_add(CSS_DEACT_BIAS, &css->refcnt) // subsequent css_tryget fail
    mem_cgroup_css_offline
    mem_cgroup_invalidate_reclaim_iterators
    while(parent = parent_mem_cgroup)
    atomic_inc(parent->dead_count)
    css_put(css) // last reference held by cgroup core

    Spotted by Ying Han.

    Original idea from Johannes Weiner.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Michal Hocko
    Signed-off-by: Johannes Weiner
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Ying Han
    Cc: Li Zefan
    Cc: Tejun Heo
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • mem_cgroup_iter curently relies on css->id when walking down a group
    hierarchy tree. This is really awkward because the tree walk depends on
    the groups creation ordering. The only guarantee is that a parent node is
    visited before its children.

    Example:

    1) mkdir -p a a/d a/b/c
    2) mkdir -a a/b/c a/d

    Will create the same trees but the tree walks will be different:

    1) a, d, b, c
    2) a, b, c, d

    Commit 574bd9f7c7c1 ("cgroup: implement generic child / descendant walk
    macros") has introduced generic cgroup tree walkers which provide either
    pre-order or post-order tree walk. This patch converts css->id based
    iteration to pre-order tree walk to keep the semantic with the original
    iterator where parent is always visited before its subtree.

    cgroup_for_each_descendant_pre suggests using post_create and
    pre_destroy for proper synchronization with groups addidition resp.
    removal. This implementation doesn't use those because a new memory
    cgroup is initialized sufficiently for iteration in mem_cgroup_css_alloc
    already and css reference counting enforces that the group is alive for
    both the last seen cgroup and the found one resp. it signals that the
    group is dead and it should be skipped.

    If the reclaim cookie is used we need to store the last visited group
    into the iterator so we have to be careful that it doesn't disappear in
    the mean time. Elevated reference count on the css keeps it alive even
    though the group have been removed (parked waiting for the last dput so
    that it can be freed).

    Per node-zone-prio iter_lock has been introduced to ensure that
    css_tryget and iter->last_visited is set atomically. Otherwise two
    racing walkers could both take a references and only one release it
    leading to a css leak (which pins cgroup dentry).

    Signed-off-by: Michal Hocko
    Cc: Johannes Weiner
    Cc: KAMEZAWA Hiroyuki
    Cc: Li Zefan
    Cc: Ying Han
    Cc: Tejun Heo
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • The patchset tries to make mem_cgroup_iter saner in the way how it walks
    hierarchies. css->id based traversal is far from being ideal as it is not
    deterministic because it depends on the creation ordering. Additional to
    that css_id is considered a burden for cgroup maintainers because it is
    quite some code and memcg is the last user of it. After this series only
    the swap accounting uses css_id but that one will follow up later.

    Diffstat (if we exclude removed/added comments) looks quite
    promising. We got rid of some code:

    $ git diff mmotm... | grep -v "^[+-][[:space:]]*[/ ]\*" | diffstat
    b/include/linux/cgroup.h | 3 ---
    kernel/cgroup.c | 33 ---------------------------------
    mm/memcontrol.c | 4 +++-
    3 files changed, 3 insertions(+), 37 deletions(-)

    The first patch is just preparatory and it changes when we release css of
    the previously returned memcg. Nothing controlversial.

    The second patch is the core of the patchset and it replaces css_get_next
    based on css_id by the generic cgroup pre-order. This brings some
    chalanges for the last visited group caching during the reclaim
    (mem_cgroup_per_zone::reclaim_iter). We have to use memcg pointers
    directly now which means that we have to keep a reference to those groups'
    css to keep them alive.

    I also folded iter_lock introduced by https://lkml.org/lkml/2013/1/3/295
    in the previous version into this patch. Johannes felt the race I was
    describing should be mostly harmless and I haven't been able to trigger it
    so the lock doesn't deserve its own patch. It is still needed
    temporarily, though, because the reference counting on iter->last_visited
    depends on it. It will go away with the next patch.

    The next patch fixups an unbounded cgroup removal holdoff caused by the
    elevated css refcount. The issue has been observed by Ying Han. Johannes
    wasn't impressed by the previous version of the fix
    (https://lkml.org/lkml/2013/2/8/379) which cleaned up pending references
    during mem_cgroup_css_offline when a group is removed. He has suggested a
    different way when the iterator checks whether a cached memcg is still
    valid or no. More on that in the patch but the basic idea is that every
    memcg tracks the number removed subgroups and iterator records this number
    when a group is cached. These numbers are checked before
    iter->last_visited is about to be used and the iteration is restarted if
    it is invalid.

    The fourth and fifth patches are an attempt for simplification of the
    mem_cgroup_iter. css juggling is removed and the iteration logic is moved
    to a helper so that the reference counting and iteration are separated.

    The last patch just removes css_get_next as there is no user for it any
    longer.

    My testing looked as follows:
    A (use_hierarchy=1, limit_in_bytes=150M)
    /|\
    1 2 3

    Children groups were created so that the number is never higher than 3 and
    their limits were random between 50-100M. Each group hosts a kernel build
    (starting with tar -xf so the tree is not shared and make -jNUM_CPUs/3)
    and terminated after random time - up to 5 minutes) and then it is
    removed.

    This should exercise both leaf and hierarchical reclaim as well as races
    with cgroup removals and debugging messages I added on top proved that.
    100 groups were created during the test.

    This patch:

    css reference counting keeps the cgroup alive even though it has been
    already removed. mem_cgroup_iter relies on this fact and takes a
    reference to the returned group. The reference is then released on the
    next iteration or mem_cgroup_iter_break. mem_cgroup_iter currently
    releases the reference right after it gets the last css_id.

    This is correct because neither prev's memcg nor cgroup are accessed after
    then. This will change in the next patch so we need to hold the group
    alive a bit longer so let's move the css_put at the end of the function.

    Signed-off-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki
    Cc: Johannes Weiner
    Cc: Li Zefan
    Cc: Ying Han
    Cc: Tejun Heo
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     

16 Apr, 2013

1 commit

  • Turn on use_hierarchy by default if sane_behavior is specified and
    don't create .use_hierarchy file.

    It is debatable whether to remove .use_hierarchy file or make it ro as
    the former could make transition easier in certain cases; however, the
    behavior changes which will be gated by sane_behavior are intensive
    including changing basic meaning of certain control knobs in a few
    controllers and I don't really think keeping this piece would make
    things easier in any noticeable way, so let's remove it.

    v2: Explain that mem_cgroup_bind() doesn't have to worry about
    children as suggested by Michal Hocko.

    Signed-off-by: Tejun Heo
    Acked-by: Serge E. Hallyn
    Acked-by: Li Zefan
    Acked-by: Michal Hocko
    Acked-by: KAMEZAWA Hiroyuki

    Tejun Heo
     

08 Apr, 2013

1 commit

  • As cgroup supports rename, it's unsafe to dereference dentry->d_name
    without proper vfs locks. Fix this by using cgroup_name() rather than
    dentry directly.

    Also open code memcg_cache_name because it is called only from
    kmem_cache_dup which frees the returned name right after
    kmem_cache_create_memcg makes a copy of it. Such a short-lived
    allocation doesn't make too much sense. So replace it by a static
    buffer as kmem_cache_dup is called with memcg_cache_mutex.

    Signed-off-by: Li Zefan
    Signed-off-by: Michal Hocko
    Acked-by: Glauber Costa
    Signed-off-by: Tejun Heo

    Michal Hocko
     

09 Mar, 2013

1 commit

  • Fix a warning from lockdep caused by calling cancel_work_sync() for
    uninitialized struct work. This path has been triggered by destructon
    kmem-cache hierarchy via destroying its root kmem-cache.

    cache ffff88003c072d80
    obj ffff88003b410000 cache ffff88003c072d80
    obj ffff88003b924000 cache ffff88003c20bd40
    INFO: trying to register non-static key.
    the code is fine but needs lockdep annotation.
    turning off the locking correctness validator.
    Pid: 2825, comm: insmod Tainted: G O 3.9.0-rc1-next-20130307+ #611
    Call Trace:
    __lock_acquire+0x16a2/0x1cb0
    lock_acquire+0x8a/0x120
    flush_work+0x38/0x2a0
    __cancel_work_timer+0x89/0xf0
    cancel_work_sync+0xb/0x10
    kmem_cache_destroy_memcg_children+0x81/0xb0
    kmem_cache_destroy+0xf/0xe0
    init_module+0xcb/0x1000 [kmem_test]
    do_one_initcall+0x11a/0x170
    load_module+0x19b0/0x2320
    SyS_init_module+0xc6/0xf0
    system_call_fastpath+0x16/0x1b

    Example module to demonstrate:

    #include
    #include
    #include
    #include

    int __init mod_init(void)
    {
    int size = 256;
    struct kmem_cache *cache;
    void *obj;
    struct page *page;

    cache = kmem_cache_create("kmem_cache_test", size, size, 0, NULL);
    if (!cache)
    return -ENOMEM;

    printk("cache %p\n", cache);

    obj = kmem_cache_alloc(cache, GFP_KERNEL);
    if (obj) {
    page = virt_to_head_page(obj);
    printk("obj %p cache %p\n", obj, page->slab_cache);
    kmem_cache_free(cache, obj);
    }

    flush_scheduled_work();

    obj = kmem_cache_alloc(cache, GFP_KERNEL);
    if (obj) {
    page = virt_to_head_page(obj);
    printk("obj %p cache %p\n", obj, page->slab_cache);
    kmem_cache_free(cache, obj);
    }

    kmem_cache_destroy(cache);

    return -EBUSY;
    }

    module_init(mod_init);
    MODULE_LICENSE("GPL");

    Signed-off-by: Konstantin Khlebnikov
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Konstantin Khlebnikov
     

24 Feb, 2013

17 commits

  • Whilst I run the risk of a flogging for disloyalty to the Lord of Sealand,
    I do have CONFIG_MEMCG=y CONFIG_MEMCG_KMEM not set, and grow tired of the
    "mm/memcontrol.c:4972:12: warning: `memcg_propagate_kmem' defined but not
    used [-Wunused-function]" seen in 3.8-rc: move the #ifdef outwards.

    Signed-off-by: Hugh Dickins
    Acked-by: Michal Hocko
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     
  • We should encourage all memcg controller initialization independent on a
    specific mem_cgroup to be done here rather than exploit css_alloc
    callback and assume that nothing happens before root cgroup is created.

    Signed-off-by: Michal Hocko
    Acked-by: Johannes Weiner
    Cc: Tejun Heo
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • memcg_stock are currently initialized during the root cgroup allocation
    which is OK but it pointlessly pollutes memcg allocation code with
    something that can be called when the memcg subsystem is initialized by
    mem_cgroup_init along with other controller specific parts.

    This patch wraps the current memcg_stock initialization code into a
    helper calls it from the controller subsystem initialization code.

    Signed-off-by: Michal Hocko
    Acked-by: Johannes Weiner
    Cc: Tejun Heo
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • Per-node-zone soft limit tree is currently initialized when the root
    cgroup is created which is OK but it pointlessly pollutes memcg
    allocation code with something that can be called when the memcg
    subsystem is initialized by mem_cgroup_init along with other controller
    specific parts.

    While we are at it let's make mem_cgroup_soft_limit_tree_init void
    because it doesn't make much sense to report memory failure because if
    we fail to allocate memory that early during the boot then we are
    screwed anyway (this saves some code).

    Signed-off-by: Michal Hocko
    Acked-by: Johannes Weiner
    Cc: Tejun Heo
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • An inactive file list is considered low when its active counterpart is
    bigger, regardless of whether it is a global zone LRU list or a memcg
    zone LRU list. The only difference is in how the LRU size is assessed.

    get_lru_size() does the right thing for both global and memcg reclaim
    situations.

    Get rid of inactive_file_is_low_global() and
    mem_cgroup_inactive_file_is_low() by using get_lru_size() and compare
    the numbers in common code.

    Signed-off-by: Johannes Weiner
    Acked-by: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Weiner
     
  • When use_hierarchy is enabled, we acquire an extra reference count in
    our parent during cgroup creation. We don't release it, though, if any
    failure exist in the creation process.

    Signed-off-by: Glauber Costa
    Reported-by: Michal Hocko
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • We were deferring the kmemcg static branch increment to a later time,
    due to a nasty dependency between the cpu_hotplug lock, taken by the
    jump label update, and the cgroup_lock.

    Now we no longer take the cgroup lock, and we can save ourselves the
    trouble.

    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • After the preparation work done in earlier patches, the cgroup_lock can
    be trivially replaced with a memcg-specific lock. This is an automatic
    translation at every site where the values involved were queried.

    The sites where values are written, however, used to be naturally called
    under cgroup_lock. This is the case for instance in the css_online
    callback. For those, we now need to explicitly add the memcg lock.

    With this, all the calls to cgroup_lock outside cgroup core are gone.

    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • Currently, we use cgroups' provided list of children to verify if it is
    safe to proceed with any value change that is dependent on the cgroup
    being empty.

    This is less than ideal, because it enforces a dependency over cgroup
    core that we would be better off without. The solution proposed here is
    to iterate over the child cgroups and if any is found that is already
    online, we bounce and return: we don't really care how many children we
    have, only if we have any.

    This is also made to be hierarchy aware. IOW, cgroups with hierarchy
    disabled, while they still exist, will be considered for the purpose of
    this interface as having no children.

    [akpm@linux-foundation.org: tweak comments]
    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • This patch is a preparatory work for later locking rework to get rid of
    big cgroup lock from memory controller code.

    The memory controller uses some tunables to adjust its operation. Those
    tunables are inherited from parent to children upon children
    intialization. For most of them, the value cannot be changed after the
    parent has a new children.

    cgroup core splits initialization in two phases: css_alloc and css_online.
    After css_alloc, the memory allocation and basic initialization are done.
    But the new group is not yet visible anywhere, not even for cgroup core
    code. It is only somewhere between css_alloc and css_online that it is
    inserted into the internal children lists. Copying tunable values in
    css_alloc will lead to inconsistent values: the children will copy the old
    parent values, that can change between the copy and the moment in which
    the groups is linked to any data structure that can indicate the presence
    of children.

    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • In memcg, we use the cgroup_lock basically to synchronize against
    attaching new children to a cgroup. We do this because we rely on
    cgroup core to provide us with this information.

    We need to guarantee that upon child creation, our tunables are
    consistent. For those, the calls to cgroup_lock() all live in handlers
    like mem_cgroup_hierarchy_write(), where we change a tunable in the
    group that is hierarchy-related. For instance, the use_hierarchy flag
    cannot be changed if the cgroup already have children.

    Furthermore, those values are propagated from the parent to the child
    when a new child is created. So if we don't lock like this, we can end
    up with the following situation:

    A B
    memcg_css_alloc() mem_cgroup_hierarchy_write()
    copy use hierarchy from parent change use hierarchy in parent
    finish creation.

    This is mainly because during create, we are still not fully connected
    to the css tree. So all iterators and the such that we could use, will
    fail to show that the group has children.

    My observation is that all of creation can proceed in parallel with
    those tasks, except value assignment. So what this patch series does is
    to first move all value assignment that is dependent on parent values
    from css_alloc to css_online, where the iterators all work, and then we
    lock only the value assignment. This will guarantee that parent and
    children always have consistent values. Together with an online test,
    that can be derived from the observation that the refcount of an online
    memcg can be made to be always positive, we should be able to
    synchronize our side without the cgroup lock.

    This patch:

    Currently, we rely on the cgroup_lock() to prevent changes to
    move_charge_at_immigrate during task migration. However, this is only
    needed because the current strategy keeps checking this value throughout
    the whole process. Since all we need is serialization, one needs only
    to guarantee that whatever decision we made in the beginning of a
    specific migration is respected throughout the process.

    We can achieve this by just saving it in mc. By doing this, no kind of
    locking is needed.

    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Hiroyuki Kamezawa
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • In order to maintain all the memcg bookkeeping, we need per-node
    descriptors, which will in turn contain a per-zone descriptor.

    Because we want to statically allocate those, this array ends up being
    very big. Part of the reason is that we allocate something large enough
    to hold MAX_NUMNODES, the compile time constant that holds the maximum
    number of nodes we would ever consider.

    However, we can do better in some cases if the firmware help us. This
    is true for modern x86 machines; coincidentally one of the architectures
    in which MAX_NUMNODES tends to be very big.

    By using the firmware-provided maximum number of nodes instead of
    MAX_NUMNODES, we can reduce the memory footprint of struct memcg
    considerably. In the extreme case in which we have only one node, this
    reduces the size of the structure from ~ 64k to ~2k. This is
    particularly important because it means that we will no longer resort to
    the vmalloc area for the struct memcg on defconfigs. We also have
    enough room for an extra node and still be outside vmalloc.

    One also has to keep in mind that with the industry's ability to fit
    more processors in a die as fast as the FED prints money, a nodes = 2
    configuration is already respectably big.

    [akpm@linux-foundation.org: add check for invalid nid, remove inline]
    Signed-off-by: Glauber Costa
    Acked-by: Michal Hocko
    Cc: Kamezawa Hiroyuki
    Cc: Johannes Weiner
    Reviewed-by: Greg Thelen
    Cc: Hugh Dickins
    Cc: Ying Han
    Cc: Mel Gorman
    Cc: Rik van Riel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • Memcg swap accounting is currently enabled by enable_swap_cgroup when
    the root cgroup is created. mem_cgroup_init acts as a memcg subsystem
    initializer which sounds like a much better place for enable_swap_cgroup
    as well. We already register memsw files from there so it makes a lot
    of sense to merge those two into a single enable_swap_cgroup function.

    This patch doesn't introduce any semantic changes.

    Signed-off-by: Michal Hocko
    Cc: Zhouping Liu
    Cc: Kamezawa Hiroyuki
    Cc: David Rientjes
    Cc: Li Zefan
    Cc: CAI Qian
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • Zhouping Liu has reported that memsw files are exported even though swap
    accounting is runtime disabled if MEMCG_SWAP is enabled. This behavior
    has been introduced by commit af36f906c0f4 ("memcg: always create memsw
    files if CGROUP_MEM_RES_CTLR_SWAP") and it causes any attempt to open
    the file to return EOPNOTSUPP. Although EOPNOTSUPP should say be clear
    that memsw operations are not supported in the given configuration it is
    fair to say that this behavior could be quite confusing.

    Let's tear memsw files out of default cgroup files and add them only if
    the swap accounting is really enabled (either by MEMCG_SWAP_ENABLED or
    swapaccount=1 boot parameter). We can hook into mem_cgroup_init which
    is called when the memcg subsystem is initialized and which happens
    after boot command line is processed.

    Signed-off-by: Michal Hocko
    Reported-by: Zhouping Liu
    Tested-by: Zhouping Liu
    Cc: Kamezawa Hiroyuki
    Cc: David Rientjes
    Cc: Li Zefan
    Cc: CAI Qian
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     
  • When I use several fast SSD to do swap, swapper_space.tree_lock is
    heavily contended. This makes each swap partition have one
    address_space to reduce the lock contention. There is an array of
    address_space for swap. The swap entry type is the index to the array.

    In my test with 3 SSD, this increases the swapout throughput 20%.

    [akpm@linux-foundation.org: revert unneeded change to __add_to_swap_cache]
    Signed-off-by: Shaohua Li
    Cc: Hugh Dickins
    Acked-by: Rik van Riel
    Acked-by: Minchan Kim
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Shaohua Li
     
  • Acked-by: Sha Zhengju
    Acked-by: Michal Hocko
    Cc: KAMEZAWA Hiroyuki
    Cc: David Rientjes
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     
  • Currently when a memcg oom is happening the oom dump messages is still
    global state and provides few useful info for users. This patch prints
    more pointed memcg page statistics for memcg-oom and take hierarchy into
    consideration:

    Based on Michal's advice, we take hierarchy into consideration: supppose
    we trigger an OOM on A's limit

    root_memcg
    |
    A (use_hierachy=1)
    / \
    B C
    |
    D
    then the printed info will be:

    Memory cgroup stats for /A:...
    Memory cgroup stats for /A/B:...
    Memory cgroup stats for /A/C:...
    Memory cgroup stats for /A/B/D:...

    Following are samples of oom output:

    (1) Before change:

    mal-80 invoked oom-killer:gfp_mask=0xd0, order=0, oom_score_adj=0
    mal-80 cpuset=/ mems_allowed=0
    Pid: 2976, comm: mal-80 Not tainted 3.7.0+ #10
    Call Trace:
    [] dump_header+0x83/0x1ca
    ..... (call trace)
    [] page_fault+0x28/0x30
    <<<<<<<<<<<<<<<<<<<<< memcg specific information
    Task in /A/B/D killed as a result of limit of /A
    memory: usage 101376kB, limit 101376kB, failcnt 57
    memory+swap: usage 101376kB, limit 101376kB, failcnt 0
    kmem: usage 0kB, limit 9007199254740991kB, failcnt 0
    <<<<<<<<<<<<<<<<<<<<< print per cpu pageset stat
    Mem-Info:
    Node 0 DMA per-cpu:
    CPU 0: hi: 0, btch: 1 usd: 0
    ......
    CPU 3: hi: 0, btch: 1 usd: 0
    Node 0 DMA32 per-cpu:
    CPU 0: hi: 186, btch: 31 usd: 173
    ......
    CPU 3: hi: 186, btch: 31 usd: 130
    <<<<<<<<<<<<<<<<<<<<< print global page state
    active_anon:92963 inactive_anon:40777 isolated_anon:0
    active_file:33027 inactive_file:51718 isolated_file:0
    unevictable:0 dirty:3 writeback:0 unstable:0
    free:729995 slab_reclaimable:6897 slab_unreclaimable:6263
    mapped:20278 shmem:35971 pagetables:5885 bounce:0
    free_cma:0
    <<<<<<<<<<<<<<<<<<<<< print per zone page state
    Node 0 DMA free:15836kB ... all_unreclaimable? no
    lowmem_reserve[]: 0 3175 3899 3899
    Node 0 DMA32 free:2888564kB ... all_unrelaimable? no
    lowmem_reserve[]: 0 0 724 724
    lowmem_reserve[]: 0 0 0 0
    Node 0 DMA: 1*4kB (U) ... 3*4096kB (M) = 15836kB
    Node 0 DMA32: 41*4kB (UM) ... 702*4096kB (MR) = 2888316kB
    120710 total pagecache pages
    0 pages in swap cache
    <<<<<<<<<<<<<<<<<<<<< print global swap cache stat
    Swap cache stats: add 0, delete 0, find 0/0
    Free swap = 499708kB
    Total swap = 499708kB
    1040368 pages RAM
    58678 pages reserved
    169065 pages shared
    173632 pages non-shared
    [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
    [ 2693] 0 2693 6005 1324 17 0 0 god
    [ 2754] 0 2754 6003 1320 16 0 0 god
    [ 2811] 0 2811 5992 1304 18 0 0 god
    [ 2874] 0 2874 6005 1323 18 0 0 god
    [ 2935] 0 2935 8720 7742 21 0 0 mal-30
    [ 2976] 0 2976 21520 17577 42 0 0 mal-80
    Memory cgroup out of memory: Kill process 2976 (mal-80) score 665 or sacrifice child
    Killed process 2976 (mal-80) total-vm:86080kB, anon-rss:69964kB, file-rss:344kB

    We can see that messages dumped by show_free_areas() are longsome and can
    provide so limited info for memcg that just happen oom.

    (2) After change
    mal-80 invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=0
    mal-80 cpuset=/ mems_allowed=0
    Pid: 2704, comm: mal-80 Not tainted 3.7.0+ #10
    Call Trace:
    [] dump_header+0x83/0x1d1
    .......(call trace)
    [] page_fault+0x28/0x30
    Task in /A/B/D killed as a result of limit of /A
    <<<<<<<<<<<<<<<<<<<<< memcg specific information
    memory: usage 102400kB, limit 102400kB, failcnt 140
    memory+swap: usage 102400kB, limit 102400kB, failcnt 0
    kmem: usage 0kB, limit 9007199254740991kB, failcnt 0
    Memory cgroup stats for /A: cache:32KB rss:30984KB mapped_file:0KB swap:0KB inactive_anon:6912KB active_anon:24072KB inactive_file:32KB active_file:0KB unevictable:0KB
    Memory cgroup stats for /A/B: cache:0KB rss:0KB mapped_file:0KB swap:0KB inactive_anon:0KB active_anon:0KB inactive_file:0KB active_file:0KB unevictable:0KB
    Memory cgroup stats for /A/C: cache:0KB rss:0KB mapped_file:0KB swap:0KB inactive_anon:0KB active_anon:0KB inactive_file:0KB active_file:0KB unevictable:0KB
    Memory cgroup stats for /A/B/D: cache:32KB rss:71352KB mapped_file:0KB swap:0KB inactive_anon:6656KB active_anon:64696KB inactive_file:16KB active_file:16KB unevictable:0KB
    [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
    [ 2260] 0 2260 6006 1325 18 0 0 god
    [ 2383] 0 2383 6003 1319 17 0 0 god
    [ 2503] 0 2503 6004 1321 18 0 0 god
    [ 2622] 0 2622 6004 1321 16 0 0 god
    [ 2695] 0 2695 8720 7741 22 0 0 mal-30
    [ 2704] 0 2704 21520 17839 43 0 0 mal-80
    Memory cgroup out of memory: Kill process 2704 (mal-80) score 669 or sacrifice child
    Killed process 2704 (mal-80) total-vm:86080kB, anon-rss:71016kB, file-rss:340kB

    This version provides more pointed info for memcg in "Memory cgroup stats
    for XXX" section.

    Signed-off-by: Sha Zhengju
    Acked-by: Michal Hocko
    Cc: KAMEZAWA Hiroyuki
    Acked-by: David Rientjes
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sha Zhengju
     

13 Feb, 2013

1 commit

  • The designed workflow for the caches in kmemcg is: register it with
    memcg_register_cache() if kmemcg is already available or later on when a
    new kmemcg appears at memcg_update_cache_sizes() which will handle all
    caches in the system. The caches created at boot time will be handled
    by the later, and the memcg-caches as well as any system caches that are
    registered later on by the former.

    There is a bug, however, in memcg_register_cache: we correctly set up
    the array size, but do not mark the cache as a root cache.

    This means that allocations for any cache appearing late in the game
    will see memcg->memcg_params->is_root_cache == false, and in particular,
    trigger VM_BUG_ON(!cachep->memcg_params->is_root_cache) in
    __memcg_kmem_cache_get.

    The obvious fix is to include the missing assignment.

    Signed-off-by: Glauber Costa
    Cc: Michal Hocko
    Cc: Johannes Weiner
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     

21 Dec, 2012

1 commit

  • Commit 648bb56d076b ("cgroup: lock cgroup_mutex in cgroup_init_subsys()")
    made cgroup_init_subsys() grab cgroup_mutex before invoking
    ->css_alloc() for the root css. Because memcg registers hotcpu notifier
    from ->css_alloc() for the root css, this introduced circular locking
    dependency between cgroup_mutex and cpu hotplug.

    Fix it by moving hotcpu notifier registration to a subsys initcall.

    ======================================================
    [ INFO: possible circular locking dependency detected ]
    3.7.0-rc4-work+ #42 Not tainted
    -------------------------------------------------------
    bash/645 is trying to acquire lock:
    (cgroup_mutex){+.+.+.}, at: [] cgroup_lock+0x17/0x20

    but task is already holding lock:
    (cpu_hotplug.lock){+.+.+.}, at: [] cpu_hotplug_begin+0x2f/0x60

    which lock already depends on the new lock.

    the existing dependency chain (in reverse order) is:

    -> #1 (cpu_hotplug.lock){+.+.+.}:
    lock_acquire+0x97/0x1e0
    mutex_lock_nested+0x61/0x3b0
    get_online_cpus+0x3c/0x60
    rebuild_sched_domains_locked+0x1b/0x70
    cpuset_write_resmask+0x298/0x2c0
    cgroup_file_write+0x1ef/0x300
    vfs_write+0xa8/0x160
    sys_write+0x52/0xa0
    system_call_fastpath+0x16/0x1b

    -> #0 (cgroup_mutex){+.+.+.}:
    __lock_acquire+0x14ce/0x1d20
    lock_acquire+0x97/0x1e0
    mutex_lock_nested+0x61/0x3b0
    cgroup_lock+0x17/0x20
    cpuset_handle_hotplug+0x1b/0x560
    cpuset_update_active_cpus+0xe/0x10
    cpuset_cpu_inactive+0x47/0x50
    notifier_call_chain+0x66/0x150
    __raw_notifier_call_chain+0xe/0x10
    __cpu_notify+0x20/0x40
    _cpu_down+0x7e/0x2f0
    cpu_down+0x36/0x50
    store_online+0x5d/0xe0
    dev_attr_store+0x18/0x30
    sysfs_write_file+0xe0/0x150
    vfs_write+0xa8/0x160
    sys_write+0x52/0xa0
    system_call_fastpath+0x16/0x1b
    other info that might help us debug this:

    Possible unsafe locking scenario:

    CPU0 CPU1
    ---- ----
    lock(cpu_hotplug.lock);
    lock(cgroup_mutex);
    lock(cpu_hotplug.lock);
    lock(cgroup_mutex);

    *** DEADLOCK ***

    5 locks held by bash/645:
    #0: (&buffer->mutex){+.+.+.}, at: [] sysfs_write_file+0x48/0x150
    #1: (s_active#42){.+.+.+}, at: [] sysfs_write_file+0xc8/0x150
    #2: (x86_cpu_hotplug_driver_mutex){+.+...}, at: [] cpu_hotplug_driver_lock+0x1
    +7/0x20
    #3: (cpu_add_remove_lock){+.+.+.}, at: [] cpu_maps_update_begin+0x17/0x20
    #4: (cpu_hotplug.lock){+.+.+.}, at: [] cpu_hotplug_begin+0x2f/0x60

    stack backtrace:
    Pid: 645, comm: bash Not tainted 3.7.0-rc4-work+ #42
    Call Trace:
    print_circular_bug+0x28e/0x29f
    __lock_acquire+0x14ce/0x1d20
    lock_acquire+0x97/0x1e0
    mutex_lock_nested+0x61/0x3b0
    cgroup_lock+0x17/0x20
    cpuset_handle_hotplug+0x1b/0x560
    cpuset_update_active_cpus+0xe/0x10
    cpuset_cpu_inactive+0x47/0x50
    notifier_call_chain+0x66/0x150
    __raw_notifier_call_chain+0xe/0x10
    __cpu_notify+0x20/0x40
    _cpu_down+0x7e/0x2f0
    cpu_down+0x36/0x50
    store_online+0x5d/0xe0
    dev_attr_store+0x18/0x30
    sysfs_write_file+0xe0/0x150
    vfs_write+0xa8/0x160
    sys_write+0x52/0xa0
    system_call_fastpath+0x16/0x1b

    Signed-off-by: Tejun Heo
    Reported-by: Fengguang Wu
    Acked-by: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

19 Dec, 2012

5 commits

  • SLAB allows us to tune a particular cache behavior with tunables. When
    creating a new memcg cache copy, we'd like to preserve any tunables the
    parent cache already had.

    This could be done by an explicit call to do_tune_cpucache() after the
    cache is created. But this is not very convenient now that the caches are
    created from common code, since this function is SLAB-specific.

    Another method of doing that is taking advantage of the fact that
    do_tune_cpucache() is always called from enable_cpucache(), which is
    called at cache initialization. We can just preset the values, and then
    things work as expected.

    It can also happen that a root cache has its tunables updated during
    normal system operation. In this case, we will propagate the change to
    all caches that are already active.

    This change will require us to move the assignment of root_cache in
    memcg_params a bit earlier. We need this to be already set - which
    memcg_kmem_register_cache will do - when we reach __kmem_cache_create()

    Signed-off-by: Glauber Costa
    Cc: Christoph Lameter
    Cc: David Rientjes
    Cc: Frederic Weisbecker
    Cc: Greg Thelen
    Cc: Johannes Weiner
    Cc: JoonSoo Kim
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Pekka Enberg
    Cc: Rik van Riel
    Cc: Suleiman Souhlal
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • When we create caches in memcgs, we need to display their usage
    information somewhere. We'll adopt a scheme similar to /proc/meminfo,
    with aggregate totals shown in the global file, and per-group information
    stored in the group itself.

    For the time being, only reads are allowed in the per-group cache.

    Signed-off-by: Glauber Costa
    Cc: Christoph Lameter
    Cc: David Rientjes
    Cc: Frederic Weisbecker
    Cc: Greg Thelen
    Cc: Johannes Weiner
    Cc: JoonSoo Kim
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Pekka Enberg
    Cc: Rik van Riel
    Cc: Suleiman Souhlal
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • This means that when we destroy a memcg cache that happened to be empty,
    those caches may take a lot of time to go away: removing the memcg
    reference won't destroy them - because there are pending references, and
    the empty pages will stay there, until a shrinker is called upon for any
    reason.

    In this patch, we will call kmem_cache_shrink() for all dead caches that
    cannot be destroyed because of remaining pages. After shrinking, it is
    possible that it could be freed. If this is not the case, we'll schedule
    a lazy worker to keep trying.

    Signed-off-by: Glauber Costa
    Cc: Christoph Lameter
    Cc: David Rientjes
    Cc: Frederic Weisbecker
    Cc: Greg Thelen
    Cc: Johannes Weiner
    Cc: JoonSoo Kim
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Pekka Enberg
    Cc: Rik van Riel
    Cc: Suleiman Souhlal
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • This enables us to remove all the children of a kmem_cache being
    destroyed, if for example the kernel module it's being used in gets
    unloaded. Otherwise, the children will still point to the destroyed
    parent.

    Signed-off-by: Suleiman Souhlal
    Signed-off-by: Glauber Costa
    Cc: Christoph Lameter
    Cc: David Rientjes
    Cc: Frederic Weisbecker
    Cc: Greg Thelen
    Cc: Johannes Weiner
    Cc: JoonSoo Kim
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Pekka Enberg
    Cc: Rik van Riel
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa
     
  • Implement destruction of memcg caches. Right now, only caches where our
    reference counter is the last remaining are deleted. If there are any
    other reference counters around, we just leave the caches lying around
    until they go away.

    When that happens, a destruction function is called from the cache code.
    Caches are only destroyed in process context, so we queue them up for
    later processing in the general case.

    Signed-off-by: Glauber Costa
    Cc: Christoph Lameter
    Cc: David Rientjes
    Cc: Frederic Weisbecker
    Cc: Greg Thelen
    Cc: Johannes Weiner
    Cc: JoonSoo Kim
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Pekka Enberg
    Cc: Rik van Riel
    Cc: Suleiman Souhlal
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Glauber Costa