Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1316989

[PATCH 2/3] mm: workingset: separate shadow unpacking and refault calculation

From Johannes Weiner <hannes@cmpxchg.org>
Newsgroups linux.kernel
Subject [PATCH 2/3] mm: workingset: separate shadow unpacking and refault calculation
Date 2016-01-25 17:50 +0100
Message-ID <qUSv0-6M7-25@gated-at.bofh.it> (permalink)
References <qUwb8-7Bw-5@gated-at.bofh.it> <qUSv0-6M7-7@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


used to be alright, but we're gonna add memcg and then the difference
between unpacking static data from the radix entry and dealing with
dynamic objects and doing calculations becomes more pronounced and
would make things awkward.

keep unpacking simple, move the higher-level stuff to _refault().

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
 mm/workingset.c | 55 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/mm/workingset.c b/mm/workingset.c
index 6f3ba184ffb2..ac6eb7bc1faa 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -176,13 +176,10 @@ static void *pack_shadow(unsigned long eviction, struct zone *zone)
 	return (void *)(eviction | RADIX_TREE_EXCEPTIONAL_ENTRY);
 }
 
-static void unpack_shadow(void *shadow,
-			  struct zone **zone,
-			  unsigned long *distance)
+static void unpack_shadow(void *shadow, struct zone **zonep,
+			  unsigned long *evictionp)
 {
 	unsigned long entry = (unsigned long)shadow;
-	unsigned long eviction;
-	unsigned long refault;
 	int zid, nid;
 
 	entry >>= RADIX_TREE_EXCEPTIONAL_SHIFT;
@@ -190,29 +187,10 @@ static void unpack_shadow(void *shadow,
 	entry >>= ZONES_SHIFT;
 	nid = entry & ((1UL << NODES_SHIFT) - 1);
 	entry >>= NODES_SHIFT;
-	eviction = entry << bucket_order;
-
-	*zone = NODE_DATA(nid)->node_zones + zid;
 
-	refault = atomic_long_read(&(*zone)->inactive_age);
+	*zonep = NODE_DATA(nid)->node_zones + zid;
+	*evictionp = entry << bucket_order;
 
-	/*
-	 * The unsigned subtraction here gives an accurate distance
-	 * across inactive_age overflows in most cases.
-	 *
-	 * There is a special case: usually, shadow entries have a
-	 * short lifetime and are either refaulted or reclaimed along
-	 * with the inode before they get too old.  But it is not
-	 * impossible for the inactive_age to lap a shadow entry in
-	 * the field, which can then can result in a false small
-	 * refault distance, leading to a false activation should this
-	 * old entry actually refault again.  However, earlier kernels
-	 * used to deactivate unconditionally with *every* reclaim
-	 * invocation for the longest time, so the occasional
-	 * inappropriate activation leading to pressure on the active
-	 * list is not a problem.
-	 */
-	*distance = (refault - eviction) & EVICTION_MASK;
 }
 
 /**
@@ -244,9 +222,32 @@ void *workingset_eviction(struct address_space *mapping, struct page *page)
 bool workingset_refault(void *shadow)
 {
 	unsigned long refault_distance;
+	unsigned long eviction;
+	unsigned long refault;
 	struct zone *zone;
 
-	unpack_shadow(shadow, &zone, &refault_distance);
+	unpack_shadow(shadow, &zone, &eviction);
+
+	refault = atomic_long_read(&zone->inactive_age);
+
+	/*
+	 * The unsigned subtraction here gives an accurate distance
+	 * across inactive_age overflows in most cases.
+	 *
+	 * There is a special case: usually, shadow entries have a
+	 * short lifetime and are either refaulted or reclaimed along
+	 * with the inode before they get too old.  But it is not
+	 * impossible for the inactive_age to lap a shadow entry in
+	 * the field, which can then can result in a false small
+	 * refault distance, leading to a false activation should this
+	 * old entry actually refault again.  However, earlier kernels
+	 * used to deactivate unconditionally with *every* reclaim
+	 * invocation for the longest time, so the occasional
+	 * inappropriate activation leading to pressure on the active
+	 * list is not a problem.
+	 */
+	refault_distance = (refault - eviction) & EVICTION_MASK;
+
 	inc_zone_state(zone, WORKINGSET_REFAULT);
 
 	if (refault_distance <= zone_page_state(zone, NR_ACTIVE_FILE)) {
-- 
2.7.0

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v2] mm: workingset: make workingset detection logic memcg aware Vladimir Davydov <vdavydov@virtuozzo.com> - 2016-01-24 18:00 +0100
  [PATCH 1/3] mm: workingset: eviction buckets for bigmem/lowbit  machines Johannes Weiner <hannes@cmpxchg.org> - 2016-01-25 17:50 +0100
  [PATCH 2/3] mm: workingset: separate shadow unpacking and refault  calculation Johannes Weiner <hannes@cmpxchg.org> - 2016-01-25 17:50 +0100
  Re: [PATCH v2] mm: workingset: make workingset detection logic memcg  aware Johannes Weiner <hannes@cmpxchg.org> - 2016-01-25 17:50 +0100
    [PATCH 3/3] mm: workingset: cgroup-aware Johannes Weiner <hannes@cmpxchg.org> - 2016-01-25 17:50 +0100
    Re: [PATCH v2] mm: workingset: make workingset detection logic memcg  aware Vladimir Davydov <vdavydov@virtuozzo.com> - 2016-01-26 09:30 +0100

csiph-web