summaryrefslogtreecommitdiffstats
path: root/mm/workingset.c
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2016-12-12 19:43:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-12 21:55:08 -0500
commitb53889987862b69179560e50992f7ea8a5eb61ed (patch)
treefa95a579897d329549fd013cc63e516a1dcfb58c /mm/workingset.c
parentdbc446b88e7041cb1d076e51726ccee497cb6ee3 (diff)
mm: workingset: update shadow limit to reflect bigger active list
Since commit 59dc76b0d4df ("mm: vmscan: reduce size of inactive file list") the size of the active file list is no longer limited to half of memory. Increase the shadow node limit accordingly to avoid throwing out shadow entries that might still result in eligible refaults. The exact size of the active list now depends on the overall size of the page cache, but converges toward taking up most of the space: In mm/vmscan.c::inactive_list_is_low(), * total target max * memory ratio inactive * ------------------------------------- * 10MB 1 5MB * 100MB 1 50MB * 1GB 3 250MB * 10GB 10 0.9GB * 100GB 31 3GB * 1TB 101 10GB * 10TB 320 32GB It would be possible to apply the same precise ratios when determining the limit for radix tree nodes containing shadow entries, but since it is merely an approximation of the oldest refault distances in the wild and the code also makes assumptions about the node population density, keep it simple and always target the full cache size. While at it, clarify the comment and the formula for memory footprint. Link: http://lkml.kernel.org/r/20161117214701.29000-1-hannes@cmpxchg.org Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/workingset.c')
-rw-r--r--mm/workingset.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/mm/workingset.c b/mm/workingset.c
index ef556bf1323d..241fa5d6b3b2 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -369,40 +369,46 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker,
369{ 369{
370 unsigned long max_nodes; 370 unsigned long max_nodes;
371 unsigned long nodes; 371 unsigned long nodes;
372 unsigned long pages; 372 unsigned long cache;
373 373
374 /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ 374 /* list_lru lock nests inside IRQ-safe mapping->tree_lock */
375 local_irq_disable(); 375 local_irq_disable();
376 nodes = list_lru_shrink_count(&shadow_nodes, sc); 376 nodes = list_lru_shrink_count(&shadow_nodes, sc);
377 local_irq_enable(); 377 local_irq_enable();
378 378
379 if (sc->memcg) {
380 pages = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid,
381 LRU_ALL_FILE);
382 } else {
383 pages = node_page_state(NODE_DATA(sc->nid), NR_ACTIVE_FILE) +
384 node_page_state(NODE_DATA(sc->nid), NR_INACTIVE_FILE);
385 }
386
387 /* 379 /*
388 * Active cache pages are limited to 50% of memory, and shadow 380 * Approximate a reasonable limit for the radix tree nodes
389 * entries that represent a refault distance bigger than that 381 * containing shadow entries. We don't need to keep more
390 * do not have any effect. Limit the number of shadow nodes 382 * shadow entries than possible pages on the active list,
391 * such that shadow entries do not exceed the number of active 383 * since refault distances bigger than that are dismissed.
392 * cache pages, assuming a worst-case node population density 384 *
393 * of 1/8th on average. 385 * The size of the active list converges toward 100% of
386 * overall page cache as memory grows, with only a tiny
387 * inactive list. Assume the total cache size for that.
388 *
389 * Nodes might be sparsely populated, with only one shadow
390 * entry in the extreme case. Obviously, we cannot keep one
391 * node for every eligible shadow entry, so compromise on a
392 * worst-case density of 1/8th. Below that, not all eligible
393 * refaults can be detected anymore.
394 * 394 *
395 * On 64-bit with 7 radix_tree_nodes per page and 64 slots 395 * On 64-bit with 7 radix_tree_nodes per page and 64 slots
396 * each, this will reclaim shadow entries when they consume 396 * each, this will reclaim shadow entries when they consume
397 * ~2% of available memory: 397 * ~1.8% of available memory:
398 * 398 *
399 * PAGE_SIZE / radix_tree_nodes / node_entries / PAGE_SIZE 399 * PAGE_SIZE / radix_tree_nodes / node_entries * 8 / PAGE_SIZE
400 */ 400 */
401 max_nodes = pages >> (1 + RADIX_TREE_MAP_SHIFT - 3); 401 if (sc->memcg) {
402 cache = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid,
403 LRU_ALL_FILE);
404 } else {
405 cache = node_page_state(NODE_DATA(sc->nid), NR_ACTIVE_FILE) +
406 node_page_state(NODE_DATA(sc->nid), NR_INACTIVE_FILE);
407 }
408 max_nodes = cache >> (RADIX_TREE_MAP_SHIFT - 3);
402 409
403 if (nodes <= max_nodes) 410 if (nodes <= max_nodes)
404 return 0; 411 return 0;
405
406 return nodes - max_nodes; 412 return nodes - max_nodes;
407} 413}
408 414