aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memcontrol.h19
-rw-r--r--include/linux/mmzone.h4
-rw-r--r--include/linux/swap.h2
-rw-r--r--mm/memcontrol.c4
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/vmscan.c61
-rw-r--r--mm/workingset.c6
7 files changed, 54 insertions, 44 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 6d2321c148cd..f4963ee4fdbc 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -324,22 +324,23 @@ mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone)
324} 324}
325 325
326/** 326/**
327 * mem_cgroup_zone_lruvec - get the lru list vector for a zone and memcg 327 * mem_cgroup_lruvec - get the lru list vector for a node or a memcg zone
328 * @node: node of the wanted lruvec
328 * @zone: zone of the wanted lruvec 329 * @zone: zone of the wanted lruvec
329 * @memcg: memcg of the wanted lruvec 330 * @memcg: memcg of the wanted lruvec
330 * 331 *
331 * Returns the lru list vector holding pages for the given @zone and 332 * Returns the lru list vector holding pages for a given @node or a given
332 * @mem. This can be the global zone lruvec, if the memory controller 333 * @memcg and @zone. This can be the node lruvec, if the memory controller
333 * is disabled. 334 * is disabled.
334 */ 335 */
335static inline struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, 336static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat,
336 struct mem_cgroup *memcg) 337 struct zone *zone, struct mem_cgroup *memcg)
337{ 338{
338 struct mem_cgroup_per_zone *mz; 339 struct mem_cgroup_per_zone *mz;
339 struct lruvec *lruvec; 340 struct lruvec *lruvec;
340 341
341 if (mem_cgroup_disabled()) { 342 if (mem_cgroup_disabled()) {
342 lruvec = zone_lruvec(zone); 343 lruvec = node_lruvec(pgdat);
343 goto out; 344 goto out;
344 } 345 }
345 346
@@ -609,10 +610,10 @@ static inline void mem_cgroup_migrate(struct page *old, struct page *new)
609{ 610{
610} 611}
611 612
612static inline struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, 613static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat,
613 struct mem_cgroup *memcg) 614 struct zone *zone, struct mem_cgroup *memcg)
614{ 615{
615 return zone_lruvec(zone); 616 return node_lruvec(pgdat);
616} 617}
617 618
618static inline struct lruvec *mem_cgroup_page_lruvec(struct page *page, 619static inline struct lruvec *mem_cgroup_page_lruvec(struct page *page,
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 4062fa74526f..895c365e3259 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -739,9 +739,9 @@ static inline spinlock_t *zone_lru_lock(struct zone *zone)
739 return &zone->zone_pgdat->lru_lock; 739 return &zone->zone_pgdat->lru_lock;
740} 740}
741 741
742static inline struct lruvec *zone_lruvec(struct zone *zone) 742static inline struct lruvec *node_lruvec(struct pglist_data *pgdat)
743{ 743{
744 return &zone->zone_pgdat->lruvec; 744 return &pgdat->lruvec;
745} 745}
746 746
747static inline unsigned long pgdat_end_pfn(pg_data_t *pgdat) 747static inline unsigned long pgdat_end_pfn(pg_data_t *pgdat)
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 916e2eddecd6..0ad616d7c381 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -316,7 +316,7 @@ extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
316 unsigned long nr_pages, 316 unsigned long nr_pages,
317 gfp_t gfp_mask, 317 gfp_t gfp_mask,
318 bool may_swap); 318 bool may_swap);
319extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, 319extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem,
320 gfp_t gfp_mask, bool noswap, 320 gfp_t gfp_mask, bool noswap,
321 struct zone *zone, 321 struct zone *zone,
322 unsigned long *nr_scanned); 322 unsigned long *nr_scanned);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 50c86ad121bc..c9ebec98e92a 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1432,8 +1432,8 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg,
1432 } 1432 }
1433 continue; 1433 continue;
1434 } 1434 }
1435 total += mem_cgroup_shrink_node_zone(victim, gfp_mask, false, 1435 total += mem_cgroup_shrink_node(victim, gfp_mask, false,
1436 zone, &nr_scanned); 1436 zone, &nr_scanned);
1437 *total_scanned += nr_scanned; 1437 *total_scanned += nr_scanned;
1438 if (!soft_limit_excess(root_memcg)) 1438 if (!soft_limit_excess(root_memcg))
1439 break; 1439 break;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 81586410c59c..749b3c358ead 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5911,6 +5911,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
5911#endif 5911#endif
5912 pgdat_page_ext_init(pgdat); 5912 pgdat_page_ext_init(pgdat);
5913 spin_lock_init(&pgdat->lru_lock); 5913 spin_lock_init(&pgdat->lru_lock);
5914 lruvec_init(node_lruvec(pgdat));
5914 5915
5915 for (j = 0; j < MAX_NR_ZONES; j++) { 5916 for (j = 0; j < MAX_NR_ZONES; j++) {
5916 struct zone *zone = pgdat->node_zones + j; 5917 struct zone *zone = pgdat->node_zones + j;
@@ -5973,7 +5974,6 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
5973 /* For bootup, initialized properly in watermark setup */ 5974 /* For bootup, initialized properly in watermark setup */
5974 mod_zone_page_state(zone, NR_ALLOC_BATCH, zone->managed_pages); 5975 mod_zone_page_state(zone, NR_ALLOC_BATCH, zone->managed_pages);
5975 5976
5976 lruvec_init(zone_lruvec(zone));
5977 if (!size) 5977 if (!size)
5978 continue; 5978 continue;
5979 5979
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b7a276f4b1b0..46f7a71ed13b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2224,12 +2224,13 @@ static inline void init_tlb_ubc(void)
2224#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ 2224#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
2225 2225
2226/* 2226/*
2227 * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. 2227 * This is a basic per-node page freer. Used by both kswapd and direct reclaim.
2228 */ 2228 */
2229static void shrink_zone_memcg(struct zone *zone, struct mem_cgroup *memcg, 2229static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memcg,
2230 struct scan_control *sc, unsigned long *lru_pages) 2230 struct scan_control *sc, unsigned long *lru_pages)
2231{ 2231{
2232 struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone, memcg); 2232 struct zone *zone = &pgdat->node_zones[sc->reclaim_idx];
2233 struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, zone, memcg);
2233 unsigned long nr[NR_LRU_LISTS]; 2234 unsigned long nr[NR_LRU_LISTS];
2234 unsigned long targets[NR_LRU_LISTS]; 2235 unsigned long targets[NR_LRU_LISTS];
2235 unsigned long nr_to_scan; 2236 unsigned long nr_to_scan;
@@ -2362,13 +2363,14 @@ static bool in_reclaim_compaction(struct scan_control *sc)
2362 * calls try_to_compact_zone() that it will have enough free pages to succeed. 2363 * calls try_to_compact_zone() that it will have enough free pages to succeed.
2363 * It will give up earlier than that if there is difficulty reclaiming pages. 2364 * It will give up earlier than that if there is difficulty reclaiming pages.
2364 */ 2365 */
2365static inline bool should_continue_reclaim(struct zone *zone, 2366static inline bool should_continue_reclaim(struct pglist_data *pgdat,
2366 unsigned long nr_reclaimed, 2367 unsigned long nr_reclaimed,
2367 unsigned long nr_scanned, 2368 unsigned long nr_scanned,
2368 struct scan_control *sc) 2369 struct scan_control *sc)
2369{ 2370{
2370 unsigned long pages_for_compaction; 2371 unsigned long pages_for_compaction;
2371 unsigned long inactive_lru_pages; 2372 unsigned long inactive_lru_pages;
2373 int z;
2372 2374
2373 /* If not in reclaim/compaction mode, stop */ 2375 /* If not in reclaim/compaction mode, stop */
2374 if (!in_reclaim_compaction(sc)) 2376 if (!in_reclaim_compaction(sc))
@@ -2402,21 +2404,29 @@ static inline bool should_continue_reclaim(struct zone *zone,
2402 * inactive lists are large enough, continue reclaiming 2404 * inactive lists are large enough, continue reclaiming
2403 */ 2405 */
2404 pages_for_compaction = (2UL << sc->order); 2406 pages_for_compaction = (2UL << sc->order);
2405 inactive_lru_pages = node_page_state(zone->zone_pgdat, NR_INACTIVE_FILE); 2407 inactive_lru_pages = node_page_state(pgdat, NR_INACTIVE_FILE);
2406 if (get_nr_swap_pages() > 0) 2408 if (get_nr_swap_pages() > 0)
2407 inactive_lru_pages += node_page_state(zone->zone_pgdat, NR_INACTIVE_ANON); 2409 inactive_lru_pages += node_page_state(pgdat, NR_INACTIVE_ANON);
2408 if (sc->nr_reclaimed < pages_for_compaction && 2410 if (sc->nr_reclaimed < pages_for_compaction &&
2409 inactive_lru_pages > pages_for_compaction) 2411 inactive_lru_pages > pages_for_compaction)
2410 return true; 2412 return true;
2411 2413
2412 /* If compaction would go ahead or the allocation would succeed, stop */ 2414 /* If compaction would go ahead or the allocation would succeed, stop */
2413 switch (compaction_suitable(zone, sc->order, 0, 0)) { 2415 for (z = 0; z <= sc->reclaim_idx; z++) {
2414 case COMPACT_PARTIAL: 2416 struct zone *zone = &pgdat->node_zones[z];
2415 case COMPACT_CONTINUE: 2417 if (!populated_zone(zone))
2416 return false; 2418 continue;
2417 default: 2419
2418 return true; 2420 switch (compaction_suitable(zone, sc->order, 0, sc->reclaim_idx)) {
2421 case COMPACT_PARTIAL:
2422 case COMPACT_CONTINUE:
2423 return false;
2424 default:
2425 /* check next zone */
2426 ;
2427 }
2419 } 2428 }
2429 return true;
2420} 2430}
2421 2431
2422static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc, 2432static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
@@ -2425,15 +2435,14 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
2425 struct reclaim_state *reclaim_state = current->reclaim_state; 2435 struct reclaim_state *reclaim_state = current->reclaim_state;
2426 unsigned long nr_reclaimed, nr_scanned; 2436 unsigned long nr_reclaimed, nr_scanned;
2427 bool reclaimable = false; 2437 bool reclaimable = false;
2428 struct zone *zone = &pgdat->node_zones[classzone_idx];
2429 2438
2430 do { 2439 do {
2431 struct mem_cgroup *root = sc->target_mem_cgroup; 2440 struct mem_cgroup *root = sc->target_mem_cgroup;
2432 struct mem_cgroup_reclaim_cookie reclaim = { 2441 struct mem_cgroup_reclaim_cookie reclaim = {
2433 .zone = zone, 2442 .zone = &pgdat->node_zones[classzone_idx],
2434 .priority = sc->priority, 2443 .priority = sc->priority,
2435 }; 2444 };
2436 unsigned long zone_lru_pages = 0; 2445 unsigned long node_lru_pages = 0;
2437 struct mem_cgroup *memcg; 2446 struct mem_cgroup *memcg;
2438 2447
2439 nr_reclaimed = sc->nr_reclaimed; 2448 nr_reclaimed = sc->nr_reclaimed;
@@ -2454,11 +2463,11 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
2454 reclaimed = sc->nr_reclaimed; 2463 reclaimed = sc->nr_reclaimed;
2455 scanned = sc->nr_scanned; 2464 scanned = sc->nr_scanned;
2456 2465
2457 shrink_zone_memcg(zone, memcg, sc, &lru_pages); 2466 shrink_node_memcg(pgdat, memcg, sc, &lru_pages);
2458 zone_lru_pages += lru_pages; 2467 node_lru_pages += lru_pages;
2459 2468
2460 if (!global_reclaim(sc)) 2469 if (!global_reclaim(sc))
2461 shrink_slab(sc->gfp_mask, zone_to_nid(zone), 2470 shrink_slab(sc->gfp_mask, pgdat->node_id,
2462 memcg, sc->nr_scanned - scanned, 2471 memcg, sc->nr_scanned - scanned,
2463 lru_pages); 2472 lru_pages);
2464 2473
@@ -2470,7 +2479,7 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
2470 /* 2479 /*
2471 * Direct reclaim and kswapd have to scan all memory 2480 * Direct reclaim and kswapd have to scan all memory
2472 * cgroups to fulfill the overall scan target for the 2481 * cgroups to fulfill the overall scan target for the
2473 * zone. 2482 * node.
2474 * 2483 *
2475 * Limit reclaim, on the other hand, only cares about 2484 * Limit reclaim, on the other hand, only cares about
2476 * nr_to_reclaim pages to be reclaimed and it will 2485 * nr_to_reclaim pages to be reclaimed and it will
@@ -2489,9 +2498,9 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
2489 * the eligible LRU pages were scanned. 2498 * the eligible LRU pages were scanned.
2490 */ 2499 */
2491 if (global_reclaim(sc)) 2500 if (global_reclaim(sc))
2492 shrink_slab(sc->gfp_mask, zone_to_nid(zone), NULL, 2501 shrink_slab(sc->gfp_mask, pgdat->node_id, NULL,
2493 sc->nr_scanned - nr_scanned, 2502 sc->nr_scanned - nr_scanned,
2494 zone_lru_pages); 2503 node_lru_pages);
2495 2504
2496 if (reclaim_state) { 2505 if (reclaim_state) {
2497 sc->nr_reclaimed += reclaim_state->reclaimed_slab; 2506 sc->nr_reclaimed += reclaim_state->reclaimed_slab;
@@ -2506,7 +2515,7 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc,
2506 if (sc->nr_reclaimed - nr_reclaimed) 2515 if (sc->nr_reclaimed - nr_reclaimed)
2507 reclaimable = true; 2516 reclaimable = true;
2508 2517
2509 } while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed, 2518 } while (should_continue_reclaim(pgdat, sc->nr_reclaimed - nr_reclaimed,
2510 sc->nr_scanned - nr_scanned, sc)); 2519 sc->nr_scanned - nr_scanned, sc));
2511 2520
2512 return reclaimable; 2521 return reclaimable;
@@ -2906,7 +2915,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
2906 2915
2907#ifdef CONFIG_MEMCG 2916#ifdef CONFIG_MEMCG
2908 2917
2909unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg, 2918unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
2910 gfp_t gfp_mask, bool noswap, 2919 gfp_t gfp_mask, bool noswap,
2911 struct zone *zone, 2920 struct zone *zone,
2912 unsigned long *nr_scanned) 2921 unsigned long *nr_scanned)
@@ -2931,11 +2940,11 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg,
2931 /* 2940 /*
2932 * NOTE: Although we can get the priority field, using it 2941 * NOTE: Although we can get the priority field, using it
2933 * here is not a good idea, since it limits the pages we can scan. 2942 * here is not a good idea, since it limits the pages we can scan.
2934 * if we don't reclaim here, the shrink_zone from balance_pgdat 2943 * if we don't reclaim here, the shrink_node from balance_pgdat
2935 * will pick up pages from other mem cgroup's as well. We hack 2944 * will pick up pages from other mem cgroup's as well. We hack
2936 * the priority and make it zero. 2945 * the priority and make it zero.
2937 */ 2946 */
2938 shrink_zone_memcg(zone, memcg, &sc, &lru_pages); 2947 shrink_node_memcg(zone->zone_pgdat, memcg, &sc, &lru_pages);
2939 2948
2940 trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); 2949 trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed);
2941 2950
@@ -2994,7 +3003,7 @@ static void age_active_anon(struct pglist_data *pgdat,
2994 3003
2995 memcg = mem_cgroup_iter(NULL, NULL, NULL); 3004 memcg = mem_cgroup_iter(NULL, NULL, NULL);
2996 do { 3005 do {
2997 struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone, memcg); 3006 struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, zone, memcg);
2998 3007
2999 if (inactive_list_is_low(lruvec, false)) 3008 if (inactive_list_is_low(lruvec, false))
3000 shrink_active_list(SWAP_CLUSTER_MAX, lruvec, 3009 shrink_active_list(SWAP_CLUSTER_MAX, lruvec,
diff --git a/mm/workingset.c b/mm/workingset.c
index 7820a7e1ca98..df0dacaf54ee 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -218,7 +218,7 @@ void *workingset_eviction(struct address_space *mapping, struct page *page)
218 VM_BUG_ON_PAGE(page_count(page), page); 218 VM_BUG_ON_PAGE(page_count(page), page);
219 VM_BUG_ON_PAGE(!PageLocked(page), page); 219 VM_BUG_ON_PAGE(!PageLocked(page), page);
220 220
221 lruvec = mem_cgroup_zone_lruvec(zone, memcg); 221 lruvec = mem_cgroup_lruvec(zone->zone_pgdat, zone, memcg);
222 eviction = atomic_long_inc_return(&lruvec->inactive_age); 222 eviction = atomic_long_inc_return(&lruvec->inactive_age);
223 return pack_shadow(memcgid, zone, eviction); 223 return pack_shadow(memcgid, zone, eviction);
224} 224}
@@ -267,7 +267,7 @@ bool workingset_refault(void *shadow)
267 rcu_read_unlock(); 267 rcu_read_unlock();
268 return false; 268 return false;
269 } 269 }
270 lruvec = mem_cgroup_zone_lruvec(zone, memcg); 270 lruvec = mem_cgroup_lruvec(zone->zone_pgdat, zone, memcg);
271 refault = atomic_long_read(&lruvec->inactive_age); 271 refault = atomic_long_read(&lruvec->inactive_age);
272 active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE); 272 active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE);
273 rcu_read_unlock(); 273 rcu_read_unlock();
@@ -319,7 +319,7 @@ void workingset_activation(struct page *page)
319 memcg = page_memcg_rcu(page); 319 memcg = page_memcg_rcu(page);
320 if (!mem_cgroup_disabled() && !memcg) 320 if (!mem_cgroup_disabled() && !memcg)
321 goto out; 321 goto out;
322 lruvec = mem_cgroup_zone_lruvec(page_zone(page), memcg); 322 lruvec = mem_cgroup_lruvec(page_pgdat(page), page_zone(page), memcg);
323 atomic_long_inc(&lruvec->inactive_age); 323 atomic_long_inc(&lruvec->inactive_age);
324out: 324out:
325 rcu_read_unlock(); 325 rcu_read_unlock();