From: Yury Norov <ynorov@caviumnetworks.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Noam Camus <noamca@mellanox.com>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Matthew Wilcox <mawilcox@microsoft.com>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
linux-kernel@vger.kernel.org,
Yury Norov <ynorov@caviumnetworks.com>
Subject: [PATCH 1/2] lib: make bitmap_parselist thread-safe and much faster
Date: Tue, 8 Aug 2017 01:54:37 +0300 [thread overview]
Message-ID: <20170807225438.16161-1-ynorov@caviumnetworks.com> (raw)
Current implementation of bitmap_parselist() uses the static variable to save
local state while setting bits in the bitmap. It is obviously wrong if we assume
execution in multiprocessor environment. Fortunately, it's possible to rewrite
this portion of code to avoid using the static variable.
It is also possible to set bits in the mask per-range with bitmap_set(), not
per-bit, as it is implemented now, with set_bit(); which is way faster.
The important side effect of this changes is that setting bits in this function
from now is not per-bit atomic and less memory-ordered. This is because set_bit()
guaranties the order of memory accesses, while bitmap_set() does not. I think
that it is the advantage of the new approach, because the bitmap_parselist() is
intended to initialise bit arrays, and user should protect the whole bitmap
during initialisation if needed. So protecting individual bits looks expensive
and useless. Also, other range-oriented functions in lib/bitmap.c don't worry
much about atomicity.
With all that, setting 2k bits in map with the pattern like 0-2047:128/256
becomes ~50 times faster after applying the patch in my testing environment
(arm64 hosted on qemu).
The second patch of the series adds the test for bitmap_parselist(). It's not
intended to cover all tricky cases, just to make sure that I didn't screw up
during rework.
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
lib/bitmap.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 9a532805364b..c82c61b66e16 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -513,7 +513,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
int nmaskbits)
{
unsigned int a, b, old_a, old_b;
- unsigned int group_size, used_size;
+ unsigned int group_size, used_size, off;
int c, old_c, totaldigits, ndigits;
const char __user __force *ubuf = (const char __user __force *)buf;
int at_start, in_range, in_partial_range;
@@ -599,6 +599,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
a = old_a;
b = old_b;
old_a = old_b = 0;
+ } else {
+ used_size = group_size = b - a + 1;
}
/* if no digit is after '-', it's wrong*/
if (at_start && in_range)
@@ -608,17 +610,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
if (b >= nmaskbits)
return -ERANGE;
while (a <= b) {
- if (in_partial_range) {
- static int pos_in_group = 1;
-
- if (pos_in_group <= used_size)
- set_bit(a, maskp);
-
- if (a == b || ++pos_in_group > group_size)
- pos_in_group = 1;
- } else
- set_bit(a, maskp);
- a++;
+ off = min(b - a + 1, used_size);
+ bitmap_set(maskp, a, off);
+ a += group_size;
}
} while (buflen && c == ',');
return 0;
--
2.11.0
next reply other threads:[~2017-08-07 22:55 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-07 22:54 Yury Norov [this message]
2017-08-07 22:54 ` [PATCH 2/2] lib: add test for bitmap_parselist() Yury Norov
2017-08-09 3:28 ` kbuild test robot
2017-08-09 20:33 ` Andrew Morton
2017-08-09 22:52 ` Yury Norov
2017-08-10 7:30 ` Rasmus Villemoes
2017-08-10 10:37 ` Yury Norov
2017-08-09 4:11 ` kbuild test robot
2017-08-09 20:28 ` Andrew Morton
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=20170807225438.16161-1-ynorov@caviumnetworks.com \
--to=ynorov@caviumnetworks.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=mawilcox@microsoft.com \
--cc=mchehab@kernel.org \
--cc=noamca@mellanox.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
all inboxes | Powered by JetHome®