From: "George Spelvin" <linux@horizon.com>
To: linux@horizon.com, mingo@kernel.org
Cc: dave@sr71.net, linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux@rasmusvillemoes.dk, peterz@infradead.org, riel@redhat.com,
rientjes@google.com, torvalds@linux-foundation.org
Subject: Re: [PATCH 3/3 v5] mm/vmalloc: Cache the vmalloc memory info
Date: 24 Aug 2015 08:54:02 -0400 [thread overview]
Message-ID: <20150824125402.28806.qmail@ns.horizon.com> (raw)
In-Reply-To: <20150824075018.GB20106@gmail.com>
(I hope I'm not annoying you by bikeshedding this too much, although I
think this is improving.)
You've sort of re-invented spinlocks, but after thinking a bit,
it all works.
Rather than using a single word, which is incremented to an odd number
at the start of an update and an even number at the end, there are
two. An update is in progress when they're unequal.
vmap_info_gen is incremented early, when the cache needs updating, and
read late (after the cache is copied).
vmap_info_cache_gen is incremented after the cache is updated, and read
early (before the cache is copied).
This is logically equivalent to my complicated scheme with atomic updates
to various bits in a single generation word, but greatly simplified by
having two separate words. In particular, there's no longer a need to
distinguish "vmap has updated list" from "calc_vmalloc_info in progress".
I particularly like the "gen - vmap_info_cache_gen > 0" test.
You *must* test for inequality to prevent tearing of a valid cache
(...grr...English heteronyms...), and given that, might as well
require it be fresher.
Anyway, suggested changes for v6 (sigh...):
First: you do a second read of vmap_info_gen to optimize out the copy
of vmalloc_info if it's easily seen as pointless, but given how small
vmalloc_info is (two words!), i'd be inclined to omit that optimization.
Copy always, *then* see if it's worth keeping. Smaller code, faster
fast path, and is barely noticeable on the slow path.
Second, and this is up to you, I'd be inclined to go fully non-blocking and
only spin_trylock(). If that fails, just skip the cache update.
Third, ANSI C rules allow a compiler to assume that signed integer
overflow does not occur. That means that gcc is allowed to optimize
"if (x - y > 0)" to "if (x > y)".
Given that gcc has annoyed us by using this optimization in other
contexts, It might be safer to make them unsigned (which is required to
wrap properly) and cast to integer after subtraction.
Basically, the following (untested, but pretty damn simple):
+/*
+ * Return a consistent snapshot of the current vmalloc allocation
+ * statistics, for /proc/meminfo:
+ */
+void get_vmalloc_info(struct vmalloc_info *vmi)
+{
+ unsigned gen, cache_gen = READ_ONCE(vmap_info_cache_gen);
+
+ /*
+ * The two read barriers make sure that we read
+ * 'cache_gen', 'vmap_info_cache' and 'gen' in
+ * precisely that order:
+ */
+ smp_rmb();
+ *vmi = vmap_info_cache;
+
+ smp_rmb();
+ gen = READ_ONCE(vmap_info_gen);
+
+ /*
+ * If the generation counter of the cache matches that of
+ * the vmalloc generation counter then return the cache:
+ */
+ if (gen == cache_gen)
+ return;
+
+ /* Make sure 'gen' is read before the vmalloc info */
+ smp_rmb();
+ calc_vmalloc_info(vmi);
+
+ /*
+ * All updates to vmap_info_cache_gen go through this spinlock,
+ * so when the cache got invalidated, we'll only mark it valid
+ * again if we first fully write the new vmap_info_cache.
+ *
+ * This ensures that partial results won't be used.
+ */
+ if (spin_trylock(&vmap_info_lock)) {
+ if ((int)(gen - vmap_info_cache_gen) > 0) {
+ vmap_info_cache = *vmi;
+ /*
+ * Make sure the new cached data is visible before
+ * the generation counter update:
+ */
+ smp_wmb();
+ WRITE_ONCE(vmap_info_cache_gen, gen);
+ }
+ spin_unlock(&vmap_info_lock);
+ }
+}
+
+#endif /* CONFIG_PROC_FS */
The only remaining *very small* nit is that this function is a mix of
"return early" and "wrap it in an if()" style. If you want to make that
"if (!spin_trylock(...)) return;", I leave that you your esthetic judgement.
--
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:[~2015-08-24 12:54 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-23 4:48 [PATCH 0/3] mm/vmalloc: Cache the /proc/meminfo vmalloc statistics George Spelvin
2015-08-23 6:04 ` Ingo Molnar
2015-08-23 6:46 ` George Spelvin
2015-08-23 8:17 ` [PATCH 3/3 v3] mm/vmalloc: Cache the vmalloc memory info Ingo Molnar
2015-08-23 20:53 ` Rasmus Villemoes
2015-08-24 6:58 ` Ingo Molnar
2015-08-24 8:39 ` Rasmus Villemoes
2015-08-23 21:56 ` Rasmus Villemoes
2015-08-24 7:00 ` Ingo Molnar
2015-08-25 16:39 ` Linus Torvalds
2015-08-25 17:03 ` Linus Torvalds
2015-08-24 1:04 ` George Spelvin
2015-08-24 7:34 ` [PATCH 3/3 v4] " Ingo Molnar
2015-08-24 7:47 ` Ingo Molnar
2015-08-24 7:50 ` [PATCH 3/3 v5] " Ingo Molnar
2015-08-24 12:54 ` George Spelvin [this message]
2015-08-25 9:56 ` [PATCH 3/3 v6] " Ingo Molnar
2015-08-25 10:36 ` George Spelvin
2015-08-25 12:59 ` Peter Zijlstra
2015-08-25 14:19 ` Rasmus Villemoes
2015-08-25 15:11 ` George Spelvin
2015-08-24 13:11 ` [PATCH 3/3 v4] " John Stoffel
2015-08-24 15:11 ` George Spelvin
2015-08-24 15:55 ` John Stoffel
2015-08-25 12:46 ` [PATCH 3/3 v3] " Peter Zijlstra
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=20150824125402.28806.qmail@ns.horizon.com \
--to=linux@horizon.com \
--cc=dave@sr71.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux@rasmusvillemoes.dk \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--cc=rientjes@google.com \
--cc=torvalds@linux-foundation.org \
/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