From: Johannes Weiner <hannes@cmpxchg.org>
To: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Michal Hocko <mhocko@kernel.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/3] mm: workingset: separate shadow unpacking and refault calculation
Date: Mon, 25 Jan 2016 11:41:52 -0500 [thread overview]
Message-ID: <20160125164152.GC29291@cmpxchg.org> (raw)
In-Reply-To: <20160125163907.GA29291@cmpxchg.org>
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
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2016-01-25 16:42 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-24 16:56 [PATCH v2] mm: workingset: make workingset detection logic memcg aware Vladimir Davydov
2016-01-25 16:39 ` Johannes Weiner
2016-01-25 16:41 ` [PATCH 1/3] mm: workingset: eviction buckets for bigmem/lowbit machines Johannes Weiner
2016-01-25 16:41 ` Johannes Weiner [this message]
2016-01-25 16:42 ` [PATCH 3/3] mm: workingset: cgroup-aware Johannes Weiner
2016-01-26 8:27 ` [PATCH v2] mm: workingset: make workingset detection logic memcg aware Vladimir Davydov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160125164152.GC29291@cmpxchg.org \
--to=hannes@cmpxchg.org \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@kernel.org \
--cc=vdavydov@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox