}
 
 static inline struct list_lru_one *
-list_lru_from_memcg_idx(struct list_lru_node *nlru, int idx)
+list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx)
 {
-       struct list_lru_memcg *memcg_lrus;
+       struct list_lru_memcg *mlrus;
+       struct list_lru_node *nlru = &lru->node[nid];
+
        /*
         * Either lock or RCU protects the array of per cgroup lists
-        * from relocation (see memcg_update_list_lru_node).
+        * from relocation (see memcg_update_list_lru).
         */
-       memcg_lrus = rcu_dereference_check(nlru->memcg_lrus,
-                                          lockdep_is_held(&nlru->lock));
-       if (memcg_lrus && idx >= 0)
-               return memcg_lrus->lru[idx];
+       mlrus = rcu_dereference_check(lru->mlrus, lockdep_is_held(&nlru->lock));
+       if (mlrus && idx >= 0)
+               return &mlrus->mlru[idx]->node[nid];
        return &nlru->lru;
 }
 
 static inline struct list_lru_one *
-list_lru_from_kmem(struct list_lru_node *nlru, void *ptr,
+list_lru_from_kmem(struct list_lru *lru, int nid, void *ptr,
                   struct mem_cgroup **memcg_ptr)
 {
+       struct list_lru_node *nlru = &lru->node[nid];
        struct list_lru_one *l = &nlru->lru;
        struct mem_cgroup *memcg = NULL;
 
-       if (!nlru->memcg_lrus)
+       if (!lru->mlrus)
                goto out;
 
        memcg = mem_cgroup_from_obj(ptr);
        if (!memcg)
                goto out;
 
-       l = list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg));
+       l = list_lru_from_memcg_idx(lru, nid, memcg_cache_id(memcg));
 out:
        if (memcg_ptr)
                *memcg_ptr = memcg;
 }
 
 static inline struct list_lru_one *
-list_lru_from_memcg_idx(struct list_lru_node *nlru, int idx)
+list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx)
 {
-       return &nlru->lru;
+       return &lru->node[nid].lru;
 }
 
 static inline struct list_lru_one *
-list_lru_from_kmem(struct list_lru_node *nlru, void *ptr,
+list_lru_from_kmem(struct list_lru *lru, int nid, void *ptr,
                   struct mem_cgroup **memcg_ptr)
 {
        if (memcg_ptr)
                *memcg_ptr = NULL;
-       return &nlru->lru;
+       return &lru->node[nid].lru;
 }
 #endif /* CONFIG_MEMCG_KMEM */
 
 
        spin_lock(&nlru->lock);
        if (list_empty(item)) {
-               l = list_lru_from_kmem(nlru, item, &memcg);
+               l = list_lru_from_kmem(lru, nid, item, &memcg);
                list_add_tail(item, &l->list);
                /* Set shrinker bit if the first element was added */
                if (!l->nr_items++)
 
        spin_lock(&nlru->lock);
        if (!list_empty(item)) {
-               l = list_lru_from_kmem(nlru, item, NULL);
+               l = list_lru_from_kmem(lru, nid, item, NULL);
                list_del_init(item);
                l->nr_items--;
                nlru->nr_items--;
 unsigned long list_lru_count_one(struct list_lru *lru,
                                 int nid, struct mem_cgroup *memcg)
 {
-       struct list_lru_node *nlru = &lru->node[nid];
        struct list_lru_one *l;
        long count;
 
        rcu_read_lock();
-       l = list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg));
+       l = list_lru_from_memcg_idx(lru, nid, memcg_cache_id(memcg));
        count = READ_ONCE(l->nr_items);
        rcu_read_unlock();
 
 EXPORT_SYMBOL_GPL(list_lru_count_node);
 
 static unsigned long
-__list_lru_walk_one(struct list_lru_node *nlru, int memcg_idx,
+__list_lru_walk_one(struct list_lru *lru, int nid, int memcg_idx,
                    list_lru_walk_cb isolate, void *cb_arg,
                    unsigned long *nr_to_walk)
 {
-
+       struct list_lru_node *nlru = &lru->node[nid];
        struct list_lru_one *l;
        struct list_head *item, *n;
        unsigned long isolated = 0;
 
-       l = list_lru_from_memcg_idx(nlru, memcg_idx);
+       l = list_lru_from_memcg_idx(lru, nid, memcg_idx);
 restart:
        list_for_each_safe(item, n, &l->list) {
                enum lru_status ret;
        unsigned long ret;
 
        spin_lock(&nlru->lock);
-       ret = __list_lru_walk_one(nlru, memcg_cache_id(memcg), isolate, cb_arg,
-                                 nr_to_walk);
+       ret = __list_lru_walk_one(lru, nid, memcg_cache_id(memcg), isolate,
+                                 cb_arg, nr_to_walk);
        spin_unlock(&nlru->lock);
        return ret;
 }
        unsigned long ret;
 
        spin_lock_irq(&nlru->lock);
-       ret = __list_lru_walk_one(nlru, memcg_cache_id(memcg), isolate, cb_arg,
-                                 nr_to_walk);
+       ret = __list_lru_walk_one(lru, nid, memcg_cache_id(memcg), isolate,
+                                 cb_arg, nr_to_walk);
        spin_unlock_irq(&nlru->lock);
        return ret;
 }
                        struct list_lru_node *nlru = &lru->node[nid];
 
                        spin_lock(&nlru->lock);
-                       isolated += __list_lru_walk_one(nlru, memcg_idx,
+                       isolated += __list_lru_walk_one(lru, nid, memcg_idx,
                                                        isolate, cb_arg,
                                                        nr_to_walk);
                        spin_unlock(&nlru->lock);
 }
 
 #ifdef CONFIG_MEMCG_KMEM
-static void __memcg_destroy_list_lru_node(struct list_lru_memcg *memcg_lrus,
-                                         int begin, int end)
+static void memcg_destroy_list_lru_range(struct list_lru_memcg *mlrus,
+                                        int begin, int end)
 {
        int i;
 
        for (i = begin; i < end; i++)
-               kfree(memcg_lrus->lru[i]);
+               kfree(mlrus->mlru[i]);
 }
 
-static int __memcg_init_list_lru_node(struct list_lru_memcg *memcg_lrus,
-                                     int begin, int end)
+static int memcg_init_list_lru_range(struct list_lru_memcg *mlrus,
+                                    int begin, int end)
 {
        int i;
 
        for (i = begin; i < end; i++) {
-               struct list_lru_one *l;
+               int nid;
+               struct list_lru_per_memcg *mlru;
 
-               l = kmalloc(sizeof(struct list_lru_one), GFP_KERNEL);
-               if (!l)
+               mlru = kmalloc(struct_size(mlru, node, nr_node_ids), GFP_KERNEL);
+               if (!mlru)
                        goto fail;
 
-               init_one_lru(l);
-               memcg_lrus->lru[i] = l;
+               for_each_node(nid)
+                       init_one_lru(&mlru->node[nid]);
+               mlrus->mlru[i] = mlru;
        }
        return 0;
 fail:
-       __memcg_destroy_list_lru_node(memcg_lrus, begin, i);
+       memcg_destroy_list_lru_range(mlrus, begin, i);
        return -ENOMEM;
 }
 
-static int memcg_init_list_lru_node(struct list_lru_node *nlru)
+static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
 {
-       struct list_lru_memcg *memcg_lrus;
+       struct list_lru_memcg *mlrus;
        int size = memcg_nr_cache_ids;
 
-       memcg_lrus = kvmalloc(struct_size(memcg_lrus, lru, size), GFP_KERNEL);
-       if (!memcg_lrus)
+       lru->memcg_aware = memcg_aware;
+       if (!memcg_aware)
+               return 0;
+
+       mlrus = kvmalloc(struct_size(mlrus, mlru, size), GFP_KERNEL);
+       if (!mlrus)
                return -ENOMEM;
 
-       if (__memcg_init_list_lru_node(memcg_lrus, 0, size)) {
-               kvfree(memcg_lrus);
+       if (memcg_init_list_lru_range(mlrus, 0, size)) {
+               kvfree(mlrus);
                return -ENOMEM;
        }
-       RCU_INIT_POINTER(nlru->memcg_lrus, memcg_lrus);
+       RCU_INIT_POINTER(lru->mlrus, mlrus);
 
        return 0;
 }
 
-static void memcg_destroy_list_lru_node(struct list_lru_node *nlru)
+static void memcg_destroy_list_lru(struct list_lru *lru)
 {
-       struct list_lru_memcg *memcg_lrus;
+       struct list_lru_memcg *mlrus;
+
+       if (!list_lru_memcg_aware(lru))
+               return;
+
        /*
         * This is called when shrinker has already been unregistered,
         * and nobody can use it. So, there is no need to use kvfree_rcu().
         */
-       memcg_lrus = rcu_dereference_protected(nlru->memcg_lrus, true);
-       __memcg_destroy_list_lru_node(memcg_lrus, 0, memcg_nr_cache_ids);
-       kvfree(memcg_lrus);
+       mlrus = rcu_dereference_protected(lru->mlrus, true);
+       memcg_destroy_list_lru_range(mlrus, 0, memcg_nr_cache_ids);
+       kvfree(mlrus);
 }
 
-static int memcg_update_list_lru_node(struct list_lru_node *nlru,
-                                     int old_size, int new_size)
+static int memcg_update_list_lru(struct list_lru *lru, int old_size, int new_size)
 {
        struct list_lru_memcg *old, *new;
 
        BUG_ON(old_size > new_size);
 
-       old = rcu_dereference_protected(nlru->memcg_lrus,
+       old = rcu_dereference_protected(lru->mlrus,
                                        lockdep_is_held(&list_lrus_mutex));
-       new = kvmalloc(struct_size(new, lru, new_size), GFP_KERNEL);
+       new = kvmalloc(struct_size(new, mlru, new_size), GFP_KERNEL);
        if (!new)
                return -ENOMEM;
 
-       if (__memcg_init_list_lru_node(new, old_size, new_size)) {
+       if (memcg_init_list_lru_range(new, old_size, new_size)) {
                kvfree(new);
                return -ENOMEM;
        }
 
-       memcpy(&new->lru, &old->lru, flex_array_size(new, lru, old_size));
-       rcu_assign_pointer(nlru->memcg_lrus, new);
+       memcpy(&new->mlru, &old->mlru, flex_array_size(new, mlru, old_size));
+       rcu_assign_pointer(lru->mlrus, new);
        kvfree_rcu(old, rcu);
        return 0;
 }
 
-static void memcg_cancel_update_list_lru_node(struct list_lru_node *nlru,
-                                             int old_size, int new_size)
-{
-       struct list_lru_memcg *memcg_lrus;
-
-       memcg_lrus = rcu_dereference_protected(nlru->memcg_lrus,
-                                              lockdep_is_held(&list_lrus_mutex));
-       /* do not bother shrinking the array back to the old size, because we
-        * cannot handle allocation failures here */
-       __memcg_destroy_list_lru_node(memcg_lrus, old_size, new_size);
-}
-
-static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
-{
-       int i;
-
-       lru->memcg_aware = memcg_aware;
-
-       if (!memcg_aware)
-               return 0;
-
-       for_each_node(i) {
-               if (memcg_init_list_lru_node(&lru->node[i]))
-                       goto fail;
-       }
-       return 0;
-fail:
-       for (i = i - 1; i >= 0; i--) {
-               if (!lru->node[i].memcg_lrus)
-                       continue;
-               memcg_destroy_list_lru_node(&lru->node[i]);
-       }
-       return -ENOMEM;
-}
-
-static void memcg_destroy_list_lru(struct list_lru *lru)
-{
-       int i;
-
-       if (!list_lru_memcg_aware(lru))
-               return;
-
-       for_each_node(i)
-               memcg_destroy_list_lru_node(&lru->node[i]);
-}
-
-static int memcg_update_list_lru(struct list_lru *lru,
-                                int old_size, int new_size)
-{
-       int i;
-
-       for_each_node(i) {
-               if (memcg_update_list_lru_node(&lru->node[i],
-                                              old_size, new_size))
-                       goto fail;
-       }
-       return 0;
-fail:
-       for (i = i - 1; i >= 0; i--) {
-               if (!lru->node[i].memcg_lrus)
-                       continue;
-
-               memcg_cancel_update_list_lru_node(&lru->node[i],
-                                                 old_size, new_size);
-       }
-       return -ENOMEM;
-}
-
 static void memcg_cancel_update_list_lru(struct list_lru *lru,
                                         int old_size, int new_size)
 {
-       int i;
+       struct list_lru_memcg *mlrus;
 
-       for_each_node(i)
-               memcg_cancel_update_list_lru_node(&lru->node[i],
-                                                 old_size, new_size);
+       mlrus = rcu_dereference_protected(lru->mlrus,
+                                         lockdep_is_held(&list_lrus_mutex));
+       /*
+        * Do not bother shrinking the array back to the old size, because we
+        * cannot handle allocation failures here.
+        */
+       memcg_destroy_list_lru_range(mlrus, old_size, new_size);
 }
 
 int memcg_update_all_list_lrus(int new_size)
         */
        spin_lock_irq(&nlru->lock);
 
-       src = list_lru_from_memcg_idx(nlru, src_idx);
-       dst = list_lru_from_memcg_idx(nlru, dst_idx);
+       src = list_lru_from_memcg_idx(lru, nid, src_idx);
+       dst = list_lru_from_memcg_idx(lru, nid, dst_idx);
 
        list_splice_init(&src->list, &dst->list);