28 Oct, 2016

1 commit

  • As described in https://bugzilla.kernel.org/show_bug.cgi?id=177821:

    After some analysis it seems to be that the problem is in alloc_super().
    In case list_lru_init_memcg() fails it goes into destroy_super(), which
    calls list_lru_destroy().

    And in list_lru_init() we see that in case memcg_init_list_lru() fails,
    lru->node is freed, but not set NULL, which then leads list_lru_destroy()
    to believe it is initialized and call memcg_destroy_list_lru().
    memcg_destroy_list_lru() in turn can access lru->node[i].memcg_lrus,
    which is NULL.

    [akpm@linux-foundation.org: add comment]
    Signed-off-by: Alexander Polakov
    Acked-by: Vladimir Davydov
    Cc: Al Viro
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Alexander Polakov
     

21 Jan, 2016

1 commit


06 Nov, 2015

2 commits

  • Before the previous patch ("memcg: unify slab and other kmem pages
    charging"), __mem_cgroup_from_kmem had to handle two types of kmem - slab
    pages and pages allocated with alloc_kmem_pages - memcg in the page
    struct. Now we can unify it. Since after it, this function becomes tiny
    we can fold it into mem_cgroup_from_kmem.

    [hughd@google.com: move mem_cgroup_from_kmem into list_lru.c]
    Signed-off-by: Vladimir Davydov
    Acked-by: Michal Hocko
    Cc: Johannes Weiner
    Cc: Hugh Dickins
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     
  • The functions used in the patch are in slowpath, which gets called
    whenever alloc_super is called during mounts.

    Though this should not make difference for the architectures with
    sequential numa node ids, for the powerpc which can potentially have
    sparse node ids (for e.g., 4 node system having numa ids, 0,1,16,17 is
    common), this patch saves some unnecessary allocations for non existing
    numa nodes.

    Even without that saving, perhaps patch makes code more readable.

    [vdavydov@parallels.com: take memcg_aware check outside for_each loop]
    Signed-off-by: Raghavendra K T
    Reviewed-by: Vladimir Davydov
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Cc: Michael Ellerman
    Cc: Anton Blanchard
    Cc: Nishanth Aravamudan
    Cc: Greg Kurz
    Cc: Grant Likely
    Cc: Nikunj A Dadhania
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Raghavendra K T
     

09 Sep, 2015

1 commit


13 Feb, 2015

5 commits

  • Now, the only reason to keep kmemcg_id till css free is list_lru, which
    uses it to distribute elements between per-memcg lists. However, it can
    be easily sorted out - we only need to change kmemcg_id of an offline
    cgroup to its parent's id, making further list_lru_add()'s add elements to
    the parent's list, and then move all elements from the offline cgroup's
    list to the one of its parent. It will work, because a racing
    list_lru_del() does not need to know the list it is deleting the element
    from. It can decrement the wrong nr_items counter though, but the ongoing
    reparenting will fix it. After list_lru reparenting is done we are free
    to release kmemcg_id saving a valuable slot in a per-memcg array for new
    cgroups.

    Signed-off-by: Vladimir Davydov
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Tejun Heo
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Cc: Dave Chinner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     
  • Currently, the isolate callback passed to the list_lru_walk family of
    functions is supposed to just delete an item from the list upon returning
    LRU_REMOVED or LRU_REMOVED_RETRY, while nr_items counter is fixed by
    __list_lru_walk_one after the callback returns. Since the callback is
    allowed to drop the lock after removing an item (it has to return
    LRU_REMOVED_RETRY then), the nr_items can be less than the actual number
    of elements on the list even if we check them under the lock. This makes
    it difficult to move items from one list_lru_one to another, which is
    required for per-memcg list_lru reparenting - we can't just splice the
    lists, we have to move entries one by one.

    This patch therefore introduces helpers that must be used by callback
    functions to isolate items instead of raw list_del/list_move. These are
    list_lru_isolate and list_lru_isolate_move. They not only remove the
    entry from the list, but also fix the nr_items counter, making sure
    nr_items always reflects the actual number of elements on the list if
    checked under the appropriate lock.

    Signed-off-by: Vladimir Davydov
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Tejun Heo
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Cc: Dave Chinner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     
  • There are several FS shrinkers, including super_block::s_shrink, that
    keep reclaimable objects in the list_lru structure. Hence to turn them
    to memcg-aware shrinkers, it is enough to make list_lru per-memcg.

    This patch does the trick. It adds an array of lru lists to the
    list_lru_node structure (per-node part of the list_lru), one for each
    kmem-active memcg, and dispatches every item addition or removal to the
    list corresponding to the memcg which the item is accounted to. So now
    the list_lru structure is not just per node, but per node and per memcg.

    Not all list_lrus need this feature, so this patch also adds a new
    method, list_lru_init_memcg, which initializes a list_lru as memcg
    aware. Otherwise (i.e. if initialized with old list_lru_init), the
    list_lru won't have per memcg lists.

    Just like per memcg caches arrays, the arrays of per-memcg lists are
    indexed by memcg_cache_id, so we must grow them whenever
    memcg_nr_cache_ids is increased. So we introduce a callback,
    memcg_update_all_list_lrus, invoked by memcg_alloc_cache_id if the id
    space is full.

    The locking is implemented in a manner similar to lruvecs, i.e. we have
    one lock per node that protects all lists (both global and per cgroup) on
    the node.

    Signed-off-by: Vladimir Davydov
    Cc: Dave Chinner
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Greg Thelen
    Cc: Glauber Costa
    Cc: Alexander Viro
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     
  • To make list_lru memcg aware, we need all list_lrus to be kept on a list
    protected by a mutex, so that we could sleep while walking over the
    list.

    Therefore after this change list_lru_destroy may sleep. Fortunately,
    there is only one user that calls it from an atomic context - it's
    put_super - and we can easily fix it by calling list_lru_destroy before
    put_super in destroy_locked_super - anyway we don't longer need lrus by
    that time.

    Another point that should be noted is that list_lru_destroy is allowed
    to be called on an uninitialized zeroed-out object, in which case it is
    a no-op. Before this patch this was guaranteed by kfree, but now we
    need an explicit check there.

    Signed-off-by: Vladimir Davydov
    Cc: Dave Chinner
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Greg Thelen
    Cc: Glauber Costa
    Cc: Alexander Viro
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     
  • The active_nodes mask allows us to skip empty nodes when walking over
    list_lru items from all nodes in list_lru_count/walk. However, these
    functions are never called from hot paths, so it doesn't seem we need
    such kind of optimization there. OTOH, removing the mask will make it
    easier to make list_lru per-memcg.

    Signed-off-by: Vladimir Davydov
    Cc: Dave Chinner
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Greg Thelen
    Cc: Glauber Costa
    Cc: Alexander Viro
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Cc: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     

04 Apr, 2014

1 commit

  • Previously, page cache radix tree nodes were freed after reclaim emptied
    out their page pointers. But now reclaim stores shadow entries in their
    place, which are only reclaimed when the inodes themselves are
    reclaimed. This is problematic for bigger files that are still in use
    after they have a significant amount of their cache reclaimed, without
    any of those pages actually refaulting. The shadow entries will just
    sit there and waste memory. In the worst case, the shadow entries will
    accumulate until the machine runs out of memory.

    To get this under control, the VM will track radix tree nodes
    exclusively containing shadow entries on a per-NUMA node list. Per-NUMA
    rather than global because we expect the radix tree nodes themselves to
    be allocated node-locally and we want to reduce cross-node references of
    otherwise independent cache workloads. A simple shrinker will then
    reclaim these nodes on memory pressure.

    A few things need to be stored in the radix tree node to implement the
    shadow node LRU and allow tree deletions coming from the list:

    1. There is no index available that would describe the reverse path
    from the node up to the tree root, which is needed to perform a
    deletion. To solve this, encode in each node its offset inside the
    parent. This can be stored in the unused upper bits of the same
    member that stores the node's height at no extra space cost.

    2. The number of shadow entries needs to be counted in addition to the
    regular entries, to quickly detect when the node is ready to go to
    the shadow node LRU list. The current entry count is an unsigned
    int but the maximum number of entries is 64, so a shadow counter
    can easily be stored in the unused upper bits.

    3. Tree modification needs tree lock and tree root, which are located
    in the address space, so store an address_space backpointer in the
    node. The parent pointer of the node is in a union with the 2-word
    rcu_head, so the backpointer comes at no extra cost as well.

    4. The node needs to be linked to an LRU list, which requires a list
    head inside the node. This does increase the size of the node, but
    it does not change the number of objects that fit into a slab page.

    [akpm@linux-foundation.org: export the right function]
    Signed-off-by: Johannes Weiner
    Reviewed-by: Rik van Riel
    Reviewed-by: Minchan Kim
    Cc: Andrea Arcangeli
    Cc: Bob Liu
    Cc: Christoph Hellwig
    Cc: Dave Chinner
    Cc: Greg Thelen
    Cc: Hugh Dickins
    Cc: Jan Kara
    Cc: KOSAKI Motohiro
    Cc: Luigi Semenzato
    Cc: Mel Gorman
    Cc: Metin Doslu
    Cc: Michel Lespinasse
    Cc: Ozgun Erdogan
    Cc: Peter Zijlstra
    Cc: Roman Gushchin
    Cc: Ryan Mallon
    Cc: Tejun Heo
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Weiner
     

31 Oct, 2013

1 commit

  • I've seen a fair number of issues with kswapd and other processes
    appearing to get stuck in v3.12-rc. Using sysrq-p many times seems to
    indicate that it gets stuck somewhere in list_lru_walk_node(), called
    from prune_icache_sb() and super_cache_scan().

    I never seem to be able to trigger a calltrace for functions above that
    point.

    So I decided to add the following to super_cache_scan():

    @@ -81,10 +81,14 @@ static unsigned long super_cache_scan(struct shrinker *shrink,
    inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid);
    dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid);
    total_objects = dentries + inodes + fs_objects + 1;
    +printk("%s:%u: %s: dentries %lu inodes %lu total %lu\n", current->comm, current->pid, __func__, dentries, inodes, total_objects);

    /* proportion the scan between the caches */
    dentries = mult_frac(sc->nr_to_scan, dentries, total_objects);
    inodes = mult_frac(sc->nr_to_scan, inodes, total_objects);
    +printk("%s:%u: %s: dentries %lu inodes %lu\n", current->comm, current->pid, __func__, dentries, inodes);
    +BUG_ON(dentries == 0);
    +BUG_ON(inodes == 0);

    /*
    * prune the dcache first as the icache is pinned by it, then
    @@ -99,7 +103,7 @@ static unsigned long super_cache_scan(struct shrinker *shrink,
    freed += sb->s_op->free_cached_objects(sb, fs_objects,
    sc->nid);
    }
    -
    +printk("%s:%u: %s: dentries %lu inodes %lu freed %lu\n", current->comm, current->pid, __func__, dentries, inodes, freed);
    drop_super(sb);
    return freed;
    }

    and shortly thereafter, having applied some pressure, I got this:

    update-apt-xapi:1616: super_cache_scan: dentries 25632 inodes 2 total 25635
    update-apt-xapi:1616: super_cache_scan: dentries 1023 inodes 0
    ------------[ cut here ]------------
    Kernel BUG at c0101994 [verbose debug info unavailable]
    Internal error: Oops - BUG: 0 [#3] SMP ARM
    Modules linked in: fuse rfcomm bnep bluetooth hid_cypress
    CPU: 0 PID: 1616 Comm: update-apt-xapi Tainted: G D 3.12.0-rc7+ #154
    task: daea1200 ti: c3bf8000 task.ti: c3bf8000
    PC is at super_cache_scan+0x1c0/0x278
    LR is at trace_hardirqs_on+0x14/0x18
    Process update-apt-xapi (pid: 1616, stack limit = 0xc3bf8240)
    ...
    Backtrace:
    (super_cache_scan) from [] (shrink_slab+0x254/0x4c8)
    (shrink_slab) from [] (try_to_free_pages+0x3a0/0x5e0)
    (try_to_free_pages) from [] (__alloc_pages_nodemask+0x5)
    (__alloc_pages_nodemask) from [] (__pte_alloc+0x2c/0x13)
    (__pte_alloc) from [] (handle_mm_fault+0x84c/0x914)
    (handle_mm_fault) from [] (do_page_fault+0x1f0/0x3bc)
    (do_page_fault) from [] (do_translation_fault+0xac/0xb8)
    (do_translation_fault) from [] (do_DataAbort+0x38/0xa0)
    (do_DataAbort) from [] (__dabt_usr+0x38/0x40)

    Notice that we had a very low number of inodes, which were reduced to
    zero my mult_frac().

    Now, prune_icache_sb() calls list_lru_walk_node() passing that number of
    inodes (0) into that as the number of objects to scan:

    long prune_icache_sb(struct super_block *sb, unsigned long nr_to_scan,
    int nid)
    {
    LIST_HEAD(freeable);
    long freed;

    freed = list_lru_walk_node(&sb->s_inode_lru, nid, inode_lru_isolate,
    &freeable, &nr_to_scan);

    which does:

    unsigned long
    list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate,
    void *cb_arg, unsigned long *nr_to_walk)
    {

    struct list_lru_node *nlru = &lru->node[nid];
    struct list_head *item, *n;
    unsigned long isolated = 0;

    spin_lock(&nlru->lock);
    restart:
    list_for_each_safe(item, n, &nlru->list) {
    enum lru_status ret;

    /*
    * decrement nr_to_walk first so that we don't livelock if we
    * get stuck on large numbesr of LRU_RETRY items
    */
    if (--(*nr_to_walk) == 0)
    break;

    So, if *nr_to_walk was zero when this function was entered, that means
    we're wanting to operate on (~0UL)+1 objects - which might as well be
    infinite.

    Clearly this is not correct behaviour. If we think about the behaviour
    of this function when *nr_to_walk is 1, then clearly it's wrong - we
    decrement first and then test for zero - which results in us doing
    nothing at all. A post-decrement would give the desired behaviour -
    we'd try to walk one object and one object only if *nr_to_walk were one.

    It also gives the correct behaviour for zero - we exit at this point.

    Fixes: 5cedf721a7cd ("list_lru: fix broken LRU_RETRY behaviour")
    Signed-off-by: Russell King
    Cc: Dave Chinner
    Cc: Al Viro
    Cc: Andrew Morton
    [ Modified to make sure we never underflow the count: this function gets
    called in a loop, so the 0 -> ~0ul transition is dangerous - Linus ]
    Signed-off-by: Linus Torvalds

    Russell King
     

11 Sep, 2013

6 commits

  • We currently use a compile-time constant to size the node array for the
    list_lru structure. Due to this, we don't need to allocate any memory at
    initialization time. But as a consequence, the structures that contain
    embedded list_lru lists can become way too big (the superblock for
    instance contains two of them).

    This patch aims at ameliorating this situation by dynamically allocating
    the node arrays with the firmware provided nr_node_ids.

    Signed-off-by: Glauber Costa
    Cc: Dave Chinner
    Cc: Mel Gorman
    Cc: "Theodore Ts'o"
    Cc: Adrian Hunter
    Cc: Al Viro
    Cc: Artem Bityutskiy
    Cc: Arve Hjønnevåg
    Cc: Carlos Maiolino
    Cc: Christoph Hellwig
    Cc: Chuck Lever
    Cc: Daniel Vetter
    Cc: David Rientjes
    Cc: Gleb Natapov
    Cc: Greg Thelen
    Cc: J. Bruce Fields
    Cc: Jan Kara
    Cc: Jerome Glisse
    Cc: John Stultz
    Cc: KAMEZAWA Hiroyuki
    Cc: Kent Overstreet
    Cc: Kirill A. Shutemov
    Cc: Marcelo Tosatti
    Cc: Mel Gorman
    Cc: Steven Whitehouse
    Cc: Thomas Hellstrom
    Cc: Trond Myklebust
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Glauber Costa
     
  • The list_lru implementation has one function, list_lru_dispose_all, with
    only one user (the dentry code). At first, such function appears to make
    sense because we are really not interested in the result of isolating each
    dentry separately - all of them are going away anyway. However, it's
    implementation is buggy in the following way:

    When we call list_lru_dispose_all in fs/dcache.c, we scan all dentries
    marking them with DCACHE_SHRINK_LIST. However, this is done without the
    nlru->lock taken. The imediate result of that is that someone else may
    add or remove the dentry from the LRU at the same time. When list_lru_del
    happens in that scenario we will see an element that is not yet marked
    with DCACHE_SHRINK_LIST (even though it will be in the future) and
    obviously remove it from an lru where the element no longer is. Since
    list_lru_dispose_all will in effect count down nlru's nr_items and
    list_lru_del will do the same, this will lead to an imbalance.

    The solution for this would not be so simple: we can obviously just keep
    the lru_lock taken, but then we have no guarantees that we will be able to
    acquire the dentry lock (dentry->d_lock). To properly solve this, we need
    a communication mechanism between the lru and dentry code, so they can
    coordinate this with each other.

    Such mechanism already exists in the form of the list_lru_walk_cb
    callback. So it is possible to construct a dcache-side prune function
    that does the right thing only by calling list_lru_walk in a loop until no
    more dentries are available.

    With only one user, plus the fact that a sane solution for the problem
    would involve boucing between dcache and list_lru anyway, I see little
    justification to keep the special case list_lru_dispose_all in tree.

    Signed-off-by: Glauber Costa
    Cc: Michal Hocko
    Acked-by: Dave Chinner
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Glauber Costa
     
  • This patch adapts the list_lru API to accept an optional node argument, to
    be used by NUMA aware shrinking functions. Code that does not care about
    the NUMA placement of objects can still call into the very same functions
    as before. They will simply iterate over all nodes.

    Signed-off-by: Glauber Costa
    Cc: Dave Chinner
    Cc: Mel Gorman
    Cc: "Theodore Ts'o"
    Cc: Adrian Hunter
    Cc: Al Viro
    Cc: Artem Bityutskiy
    Cc: Arve Hjønnevåg
    Cc: Carlos Maiolino
    Cc: Christoph Hellwig
    Cc: Chuck Lever
    Cc: Daniel Vetter
    Cc: David Rientjes
    Cc: Gleb Natapov
    Cc: Greg Thelen
    Cc: J. Bruce Fields
    Cc: Jan Kara
    Cc: Jerome Glisse
    Cc: John Stultz
    Cc: KAMEZAWA Hiroyuki
    Cc: Kent Overstreet
    Cc: Kirill A. Shutemov
    Cc: Marcelo Tosatti
    Cc: Mel Gorman
    Cc: Steven Whitehouse
    Cc: Thomas Hellstrom
    Cc: Trond Myklebust
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Glauber Costa
     
  • The LRU_RETRY code assumes that the list traversal status after we have
    dropped and regained the list lock. Unfortunately, this is not a valid
    assumption, and that can lead to racing traversals isolating objects that
    the other traversal expects to be the next item on the list.

    This is causing problems with the inode cache shrinker isolation, with
    races resulting in an inode on a dispose list being "isolated" because a
    racing traversal still thinks it is on the LRU. The inode is then never
    reclaimed and that causes hangs if a subsequent lookup on that inode
    occurs.

    Fix it by always restarting the list walk on a LRU_RETRY return from the
    isolate callback. Avoid the possibility of livelocks the current code was
    trying to avoid by always decrementing the nr_to_walk counter on retries
    so that even if we keep hitting the same item on the list we'll eventually
    stop trying to walk and exit out of the situation causing the problem.

    Reported-by: Michal Hocko
    Signed-off-by: Dave Chinner
    Cc: Glauber Costa
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Dave Chinner
     
  • Now that we have an LRU list API, we can start to enhance the
    implementation. This splits the single LRU list into per-node lists and
    locks to enhance scalability. Items are placed on lists according to the
    node the memory belongs to. To make scanning the lists efficient, also
    track whether the per-node lists have entries in them in a active
    nodemask.

    Note: We use a fixed-size array for the node LRU, this struct can be very
    big if MAX_NUMNODES is big. If this becomes a problem this is fixable by
    turning this into a pointer and dynamically allocating this to
    nr_node_ids. This quantity is firwmare-provided, and still would provide
    room for all nodes at the cost of a pointer lookup and an extra
    allocation. Because that allocation will most likely come from a may very
    well fail.

    [glommer@openvz.org: fix warnings, added note about node lru]
    Signed-off-by: Dave Chinner
    Signed-off-by: Glauber Costa
    Reviewed-by: Greg Thelen
    Acked-by: Mel Gorman
    Cc: "Theodore Ts'o"
    Cc: Adrian Hunter
    Cc: Al Viro
    Cc: Artem Bityutskiy
    Cc: Arve Hjønnevåg
    Cc: Carlos Maiolino
    Cc: Christoph Hellwig
    Cc: Chuck Lever
    Cc: Daniel Vetter
    Cc: David Rientjes
    Cc: Gleb Natapov
    Cc: Greg Thelen
    Cc: J. Bruce Fields
    Cc: Jan Kara
    Cc: Jerome Glisse
    Cc: John Stultz
    Cc: KAMEZAWA Hiroyuki
    Cc: Kent Overstreet
    Cc: Kirill A. Shutemov
    Cc: Marcelo Tosatti
    Cc: Mel Gorman
    Cc: Steven Whitehouse
    Cc: Thomas Hellstrom
    Cc: Trond Myklebust
    Signed-off-by: Andrew Morton

    Signed-off-by: Al Viro

    Dave Chinner
     
  • Several subsystems use the same construct for LRU lists - a list head, a
    spin lock and and item count. They also use exactly the same code for
    adding and removing items from the LRU. Create a generic type for these
    LRU lists.

    This is the beginning of generic, node aware LRUs for shrinkers to work
    with.

    [glommer@openvz.org: enum defined constants for lru. Suggested by gthelen, don't relock over retry]
    Signed-off-by: Dave Chinner
    Signed-off-by: Glauber Costa
    Reviewed-by: Greg Thelen
    Acked-by: Mel Gorman
    Cc: "Theodore Ts'o"
    Cc: Adrian Hunter
    Cc: Al Viro
    Cc: Artem Bityutskiy
    Cc: Arve Hjønnevåg
    Cc: Carlos Maiolino
    Cc: Christoph Hellwig
    Cc: Chuck Lever
    Cc: Daniel Vetter
    Cc: David Rientjes
    Cc: Gleb Natapov
    Cc: Greg Thelen
    Cc: J. Bruce Fields
    Cc: Jan Kara
    Cc: Jerome Glisse
    Cc: John Stultz
    Cc: KAMEZAWA Hiroyuki
    Cc: Kent Overstreet
    Cc: Kirill A. Shutemov
    Cc: Marcelo Tosatti
    Cc: Mel Gorman
    Cc: Steven Whitehouse
    Cc: Thomas Hellstrom
    Cc: Trond Myklebust
    Signed-off-by: Andrew Morton

    Signed-off-by: Al Viro

    Dave Chinner