struct mem_cgroup *memcg)
 {
        struct mem_cgroup_per_zone *mz;
+       struct lruvec *lruvec;
 
-       if (mem_cgroup_disabled())
-               return &zone->lruvec;
+       if (mem_cgroup_disabled()) {
+               lruvec = &zone->lruvec;
+               goto out;
+       }
 
        mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone));
-       return &mz->lruvec;
+       lruvec = &mz->lruvec;
+out:
+       /*
+        * Since a node can be onlined after the mem_cgroup was created,
+        * we have to be prepared to initialize lruvec->zone here;
+        * and if offlined then reonlined, we need to reinitialize it.
+        */
+       if (unlikely(lruvec->zone != zone))
+               lruvec->zone = zone;
+       return lruvec;
 }
 
 /*
        struct mem_cgroup_per_zone *mz;
        struct mem_cgroup *memcg;
        struct page_cgroup *pc;
+       struct lruvec *lruvec;
 
-       if (mem_cgroup_disabled())
-               return &zone->lruvec;
+       if (mem_cgroup_disabled()) {
+               lruvec = &zone->lruvec;
+               goto out;
+       }
 
        pc = lookup_page_cgroup(page);
        memcg = pc->mem_cgroup;
                pc->mem_cgroup = memcg = root_mem_cgroup;
 
        mz = page_cgroup_zoneinfo(memcg, page);
-       return &mz->lruvec;
+       lruvec = &mz->lruvec;
+out:
+       /*
+        * Since a node can be onlined after the mem_cgroup was created,
+        * we have to be prepared to initialize lruvec->zone here;
+        * and if offlined then reonlined, we need to reinitialize it.
+        */
+       if (unlikely(lruvec->zone != zone))
+               lruvec->zone = zone;
+       return lruvec;
 }
 
 /**
 static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
                                int node, int zid, enum lru_list lru)
 {
-       struct mem_cgroup_per_zone *mz;
+       struct lruvec *lruvec;
        unsigned long flags, loop;
        struct list_head *list;
        struct page *busy;
        struct zone *zone;
 
        zone = &NODE_DATA(node)->node_zones[zid];
-       mz = mem_cgroup_zoneinfo(memcg, node, zid);
-       list = &mz->lruvec.lists[lru];
+       lruvec = mem_cgroup_zone_lruvec(zone, memcg);
+       list = &lruvec->lists[lru];
 
-       loop = mz->lru_size[lru];
+       loop = mem_cgroup_get_lru_size(lruvec, lru);
        /* give some margin against EBUSY etc...*/
        loop += 256;
        busy = NULL;
 
        for (zone = 0; zone < MAX_NR_ZONES; zone++) {
                mz = &pn->zoneinfo[zone];
-               lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]);
+               lruvec_init(&mz->lruvec);
                mz->usage_in_excess = 0;
                mz->on_tree = false;
                mz->memcg = memcg;