summaryrefslogtreecommitdiffstats
path: root/mm/compaction.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@techsingularity.net>2016-07-28 18:45:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-28 19:07:41 -0400
commit599d0c954f91d0689c9bb421b5bc04ea02437a41 (patch)
treee863ce685841e494bcb63e458739e0939ac684f6 /mm/compaction.c
parenta52633d8e9c35832f1409dc5fa166019048a3f1f (diff)
mm, vmscan: move LRU lists to node
This moves the LRU lists from the zone to the node and related data such as counters, tracing, congestion tracking and writeback tracking. Unfortunately, due to reclaim and compaction retry logic, it is necessary to account for the number of LRU pages on both zone and node logic. Most reclaim logic is based on the node counters but the retry logic uses the zone counters which do not distinguish inactive and active sizes. It would be possible to leave the LRU counters on a per-zone basis but it's a heavier calculation across multiple cache lines that is much more frequent than the retry checks. Other than the LRU counters, this is mostly a mechanical patch but note that it introduces a number of anomalies. For example, the scans are per-zone but using per-node counters. We also mark a node as congested when a zone is congested. This causes weird problems that are fixed later but is easier to review. In the event that there is excessive overhead on 32-bit systems due to the nodes being on LRU then there are two potential solutions 1. Long-term isolation of highmem pages when reclaim is lowmem When pages are skipped, they are immediately added back onto the LRU list. If lowmem reclaim persisted for long periods of time, the same highmem pages get continually scanned. The idea would be that lowmem keeps those pages on a separate list until a reclaim for highmem pages arrives that splices the highmem pages back onto the LRU. It potentially could be implemented similar to the UNEVICTABLE list. That would reduce the skip rate with the potential corner case is that highmem pages have to be scanned and reclaimed to free lowmem slab pages. 2. Linear scan lowmem pages if the initial LRU shrink fails This will break LRU ordering but may be preferable and faster during memory pressure than skipping LRU pages. Link: http://lkml.kernel.org/r/1467970510-21195-4-git-send-email-mgorman@techsingularity.net Signed-off-by: Mel Gorman <mgorman@techsingularity.net> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Hillf Danton <hillf.zj@alibaba-inc.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Minchan Kim <minchan@kernel.org> Cc: Rik van Riel <riel@surriel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/compaction.c')
-rw-r--r--mm/compaction.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index 5c65fad3f330..e5995f38d677 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -646,8 +646,8 @@ static void acct_isolated(struct zone *zone, struct compact_control *cc)
646 list_for_each_entry(page, &cc->migratepages, lru) 646 list_for_each_entry(page, &cc->migratepages, lru)
647 count[!!page_is_file_cache(page)]++; 647 count[!!page_is_file_cache(page)]++;
648 648
649 mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]); 649 mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_ANON, count[0]);
650 mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]); 650 mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE, count[1]);
651} 651}
652 652
653/* Similar to reclaim, but different enough that they don't share logic */ 653/* Similar to reclaim, but different enough that they don't share logic */
@@ -655,12 +655,12 @@ static bool too_many_isolated(struct zone *zone)
655{ 655{
656 unsigned long active, inactive, isolated; 656 unsigned long active, inactive, isolated;
657 657
658 inactive = zone_page_state(zone, NR_INACTIVE_FILE) + 658 inactive = node_page_state(zone->zone_pgdat, NR_INACTIVE_FILE) +
659 zone_page_state(zone, NR_INACTIVE_ANON); 659 node_page_state(zone->zone_pgdat, NR_INACTIVE_ANON);
660 active = zone_page_state(zone, NR_ACTIVE_FILE) + 660 active = node_page_state(zone->zone_pgdat, NR_ACTIVE_FILE) +
661 zone_page_state(zone, NR_ACTIVE_ANON); 661 node_page_state(zone->zone_pgdat, NR_ACTIVE_ANON);
662 isolated = zone_page_state(zone, NR_ISOLATED_FILE) + 662 isolated = node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE) +
663 zone_page_state(zone, NR_ISOLATED_ANON); 663 node_page_state(zone->zone_pgdat, NR_ISOLATED_ANON);
664 664
665 return isolated > (inactive + active) / 2; 665 return isolated > (inactive + active) / 2;
666} 666}
@@ -856,7 +856,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
856 } 856 }
857 } 857 }
858 858
859 lruvec = mem_cgroup_page_lruvec(page, zone); 859 lruvec = mem_cgroup_page_lruvec(page, zone->zone_pgdat);
860 860
861 /* Try isolate the page */ 861 /* Try isolate the page */
862 if (__isolate_lru_page(page, isolate_mode) != 0) 862 if (__isolate_lru_page(page, isolate_mode) != 0)