aboutsummaryrefslogtreecommitdiffstats
path: root/mm/compaction.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@techsingularity.net>2016-07-28 18:47:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-28 19:07:41 -0400
commitbca6759258dbef378bcf5b872177bcd2259ceb68 (patch)
tree17b2a1307ab70e4fb6f8f2cf4b535240b2433d5d /mm/compaction.c
parente2ecc8a79ed49f7838b4fdf352c4c48cec9424ac (diff)
mm, vmstat: remove zone and node double accounting by approximating retries
The number of LRU pages, dirty pages and writeback pages must be accounted for on both zones and nodes because of the reclaim retry logic, compaction retry logic and highmem calculations all depending on per-zone stats. Many lowmem allocations are immune from OOM kill due to a check in __alloc_pages_may_oom for (ac->high_zoneidx < ZONE_NORMAL) since commit 03668b3ceb0c ("oom: avoid oom killer for lowmem allocations"). The exception is costly high-order allocations or allocations that cannot fail. If the __alloc_pages_may_oom avoids OOM-kill for low-order lowmem allocations then it would fall through to __alloc_pages_direct_compact. This patch will blindly retry reclaim for zone-constrained allocations in should_reclaim_retry up to MAX_RECLAIM_RETRIES. This is not ideal but without per-zone stats there are not many alternatives. The impact it that zone-constrained allocations may delay before considering the OOM killer. As there is no guarantee enough memory can ever be freed to satisfy compaction, this patch avoids retrying compaction for zone-contrained allocations. In combination, that means that the per-node stats can be used when deciding whether to continue reclaim using a rough approximation. While it is possible this will make the wrong decision on occasion, it will not infinite loop as the number of reclaim attempts is capped by MAX_RECLAIM_RETRIES. The final step is calculating the number of dirtyable highmem pages. As those calculations only care about the global count of file pages in highmem. This patch uses a global counter used instead of per-zone stats as it is sufficient. In combination, this allows the per-zone LRU and dirty state counters to be removed. [mgorman@techsingularity.net: fix acct_highmem_file_pages()] Link: http://lkml.kernel.org/r/1468853426-12858-4-git-send-email-mgorman@techsingularity.netLink: http://lkml.kernel.org/r/1467970510-21195-35-git-send-email-mgorman@techsingularity.net Signed-off-by: Mel Gorman <mgorman@techsingularity.net> Suggested by: Michal Hocko <mhocko@kernel.org> Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com> Cc: Johannes Weiner <hannes@cmpxchg.org> 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> Cc: Vlastimil Babka <vbabka@suse.cz> 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.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index e5995f38d677..cd93ea24c565 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1438,6 +1438,11 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
1438{ 1438{
1439 struct zone *zone; 1439 struct zone *zone;
1440 struct zoneref *z; 1440 struct zoneref *z;
1441 pg_data_t *last_pgdat = NULL;
1442
1443 /* Do not retry compaction for zone-constrained allocations */
1444 if (ac->high_zoneidx < ZONE_NORMAL)
1445 return false;
1441 1446
1442 /* 1447 /*
1443 * Make sure at least one zone would pass __compaction_suitable if we continue 1448 * Make sure at least one zone would pass __compaction_suitable if we continue
@@ -1448,14 +1453,27 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
1448 unsigned long available; 1453 unsigned long available;
1449 enum compact_result compact_result; 1454 enum compact_result compact_result;
1450 1455
1456 if (last_pgdat == zone->zone_pgdat)
1457 continue;
1458
1459 /*
1460 * This over-estimates the number of pages available for
1461 * reclaim/compaction but walking the LRU would take too
1462 * long. The consequences are that compaction may retry
1463 * longer than it should for a zone-constrained allocation
1464 * request.
1465 */
1466 last_pgdat = zone->zone_pgdat;
1467 available = pgdat_reclaimable_pages(zone->zone_pgdat) / order;
1468
1451 /* 1469 /*
1452 * Do not consider all the reclaimable memory because we do not 1470 * Do not consider all the reclaimable memory because we do not
1453 * want to trash just for a single high order allocation which 1471 * want to trash just for a single high order allocation which
1454 * is even not guaranteed to appear even if __compaction_suitable 1472 * is even not guaranteed to appear even if __compaction_suitable
1455 * is happy about the watermark check. 1473 * is happy about the watermark check.
1456 */ 1474 */
1457 available = zone_reclaimable_pages(zone) / order;
1458 available += zone_page_state_snapshot(zone, NR_FREE_PAGES); 1475 available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
1476 available = min(zone->managed_pages, available);
1459 compact_result = __compaction_suitable(zone, order, alloc_flags, 1477 compact_result = __compaction_suitable(zone, order, alloc_flags,
1460 ac_classzone_idx(ac), available); 1478 ac_classzone_idx(ac), available);
1461 if (compact_result != COMPACT_SKIPPED && 1479 if (compact_result != COMPACT_SKIPPED &&