@@ -1055,12 +1055,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone,
10551055 struct mem_cgroup * memcg )
10561056{
10571057 struct mem_cgroup_per_zone * mz ;
1058+ struct lruvec * lruvec ;
10581059
1059- if (mem_cgroup_disabled ())
1060- return & zone -> lruvec ;
1060+ if (mem_cgroup_disabled ()) {
1061+ lruvec = & zone -> lruvec ;
1062+ goto out ;
1063+ }
10611064
10621065 mz = mem_cgroup_zoneinfo (memcg , zone_to_nid (zone ), zone_idx (zone ));
1063- return & mz -> lruvec ;
1066+ lruvec = & mz -> lruvec ;
1067+ out :
1068+ /*
1069+ * Since a node can be onlined after the mem_cgroup was created,
1070+ * we have to be prepared to initialize lruvec->zone here;
1071+ * and if offlined then reonlined, we need to reinitialize it.
1072+ */
1073+ if (unlikely (lruvec -> zone != zone ))
1074+ lruvec -> zone = zone ;
1075+ return lruvec ;
10641076}
10651077
10661078/*
@@ -1087,9 +1099,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
10871099 struct mem_cgroup_per_zone * mz ;
10881100 struct mem_cgroup * memcg ;
10891101 struct page_cgroup * pc ;
1102+ struct lruvec * lruvec ;
10901103
1091- if (mem_cgroup_disabled ())
1092- return & zone -> lruvec ;
1104+ if (mem_cgroup_disabled ()) {
1105+ lruvec = & zone -> lruvec ;
1106+ goto out ;
1107+ }
10931108
10941109 pc = lookup_page_cgroup (page );
10951110 memcg = pc -> mem_cgroup ;
@@ -1107,7 +1122,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
11071122 pc -> mem_cgroup = memcg = root_mem_cgroup ;
11081123
11091124 mz = page_cgroup_zoneinfo (memcg , page );
1110- return & mz -> lruvec ;
1125+ lruvec = & mz -> lruvec ;
1126+ out :
1127+ /*
1128+ * Since a node can be onlined after the mem_cgroup was created,
1129+ * we have to be prepared to initialize lruvec->zone here;
1130+ * and if offlined then reonlined, we need to reinitialize it.
1131+ */
1132+ if (unlikely (lruvec -> zone != zone ))
1133+ lruvec -> zone = zone ;
1134+ return lruvec ;
11111135}
11121136
11131137/**
@@ -1452,17 +1476,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg)
14521476static u64 mem_cgroup_get_limit (struct mem_cgroup * memcg )
14531477{
14541478 u64 limit ;
1455- u64 memsw ;
14561479
14571480 limit = res_counter_read_u64 (& memcg -> res , RES_LIMIT );
1458- limit += total_swap_pages << PAGE_SHIFT ;
14591481
1460- memsw = res_counter_read_u64 (& memcg -> memsw , RES_LIMIT );
14611482 /*
1462- * If memsw is finite and limits the amount of swap space available
1463- * to this memcg, return that limit.
1483+ * Do not consider swap space if we cannot swap due to swappiness
14641484 */
1465- return min (limit , memsw );
1485+ if (mem_cgroup_swappiness (memcg )) {
1486+ u64 memsw ;
1487+
1488+ limit += total_swap_pages << PAGE_SHIFT ;
1489+ memsw = res_counter_read_u64 (& memcg -> memsw , RES_LIMIT );
1490+
1491+ /*
1492+ * If memsw is finite and limits the amount of swap space
1493+ * available to this memcg, return that limit.
1494+ */
1495+ limit = min (limit , memsw );
1496+ }
1497+
1498+ return limit ;
14661499}
14671500
14681501void mem_cgroup_out_of_memory (struct mem_cgroup * memcg , gfp_t gfp_mask ,
@@ -3688,17 +3721,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
36883721static bool mem_cgroup_force_empty_list (struct mem_cgroup * memcg ,
36893722 int node , int zid , enum lru_list lru )
36903723{
3691- struct mem_cgroup_per_zone * mz ;
3724+ struct lruvec * lruvec ;
36923725 unsigned long flags , loop ;
36933726 struct list_head * list ;
36943727 struct page * busy ;
36953728 struct zone * zone ;
36963729
36973730 zone = & NODE_DATA (node )-> node_zones [zid ];
3698- mz = mem_cgroup_zoneinfo ( memcg , node , zid );
3699- list = & mz -> lruvec . lists [lru ];
3731+ lruvec = mem_cgroup_zone_lruvec ( zone , memcg );
3732+ list = & lruvec -> lists [lru ];
37003733
3701- loop = mz -> lru_size [ lru ] ;
3734+ loop = mem_cgroup_get_lru_size ( lruvec , lru ) ;
37023735 /* give some margin against EBUSY etc...*/
37033736 loop += 256 ;
37043737 busy = NULL ;
@@ -4736,7 +4769,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
47364769
47374770 for (zone = 0 ; zone < MAX_NR_ZONES ; zone ++ ) {
47384771 mz = & pn -> zoneinfo [zone ];
4739- lruvec_init (& mz -> lruvec , & NODE_DATA ( node ) -> node_zones [ zone ] );
4772+ lruvec_init (& mz -> lruvec );
47404773 mz -> usage_in_excess = 0 ;
47414774 mz -> on_tree = false;
47424775 mz -> memcg = memcg ;
0 commit comments