Thread (7 messages) 7 messages, 2 authors, 2018-11-30

Re: [PATCH 1/2] sbitmap: ammortize cost of clearing bits

From: Omar Sandoval <osandov@osandov.com>
Date: 2018-11-30 21:41:40

On Fri, Nov 30, 2018 at 01:10:47PM -0700, Jens Axboe wrote:
On 11/30/18 1:03 PM, Omar Sandoval wrote:
quoted
On Fri, Nov 30, 2018 at 09:01:17AM -0700, Jens Axboe wrote:
quoted
sbitmap maintains a set of words that we use to set and clear bits, with
each bit representing a tag for blk-mq. Even though we spread the bits
out and maintain a hint cache, one particular bit allocated will end up
being cleared in the exact same spot.

This introduces batched clearing of bits. Instead of clearing a given
bit, the same bit is set in a cleared/free mask instead. If we fail
allocating a bit from a given word, then we check the free mask, and
batch move those cleared bits at that time. This trades 64 atomic bitops
for 2 cmpxchg().

In a threaded poll test case, half the overhead of getting and clearing
tags is removed with this change. On another poll test case with a
single thread, performance is unchanged.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 include/linux/sbitmap.h | 31 +++++++++++++---
 lib/sbitmap.c           | 80 +++++++++++++++++++++++++++++++++++++----
 2 files changed, 100 insertions(+), 11 deletions(-)
diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 804a50983ec5..07f117ee19dc 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -30,14 +30,24 @@ struct seq_file;
  */
 struct sbitmap_word {
 	/**
-	 * @word: The bitmap word itself.
+	 * @depth: Number of bits being used in @word/@cleared
 	 */
-	unsigned long word;
+	unsigned long depth;
 
 	/**
-	 * @depth: Number of bits being used in @word.
+	 * @word: word holding free bits
 	 */
-	unsigned long depth;
+	unsigned long word ____cacheline_aligned_in_smp;
Still splitting up word and depth in separate cachelines?
Yeah, I mentioned that in one of the other postings, there's still a
definite win to doing that.
quoted
Okay, I couldn't find any holes in this one :)
Good to hear that :-)
quoted
quoted
-unsigned int sbitmap_weight(const struct sbitmap *sb)
+static unsigned int __sbitmap_weight(const struct sbitmap *sb, bool set)
 {
 	unsigned int i, weight = 0;
 
 	for (i = 0; i < sb->map_nr; i++) {
 		const struct sbitmap_word *word = &sb->map[i];
 
-		weight += bitmap_weight(&word->word, word->depth);
+		if (set)
+			weight += bitmap_weight(&word->word, word->depth);
Should probably do
			weight -= bitmap_weight(&word->cleared, word->depth);

too, right?
We only use these for the debugfs stuff, how about I just make it static
instead?
Yeah, with that,

Reviewed-by: Omar Sandoval <redacted>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help