From: Paul Mackerras <paulus@ozlabs.org>
To: Matthew Wilcox <mawilcox@microsoft.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
lkml@vger.kernel.org
Cc: linuxppc-dev@ozlabs.org, linux-s390@vger.kernel.org
Subject: [PATCH] bitmap: Fix optimization of bitmap_set/clear for big-endian machines
Date: Wed, 25 Oct 2017 17:57:26 +1100 [thread overview]
Message-ID: <20171025065726.GA25140@fergus.ozlabs.ibm.com> (raw)
Commit 2a98dc028f91 ("include/linux/bitmap.h: turn bitmap_set and
bitmap_clear into memset when possible", 2017-07-10) added an
optimization which effectively assumes that a contiguous set of
bits in a bitmap will be stored in a contiguous set of bytes of
the bitmap, in the case where the starting bit number and number of
bits are multiples of 8. This is true for a little-endian
representation, but not for a big-endian representation, because we
number the bits of a long from right to left for both little-endian
and big-endian representations.
The optimization can still be done for big-endian platforms, but
only if the starting bit number and number of bits are multiples
of BITS_PER_LONG. This adjusts the code to use 8 for little-endian
and BITS_PER_LONG for big-endian platforms.
Cc: stable@vger.kernel.org # v4.13
Fixes: 2a98dc028f91 ("include/linux/bitmap.h: turn bitmap_set and bitmap_clear into memset when possible")
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
This was found by inspection.
I'm pretty sure commit 2c6deb01525a is wrong as well on big-endian
machines.
include/linux/bitmap.h | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 700cf5f..44e2eb4 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -174,8 +174,10 @@ extern unsigned int bitmap_to_u32array(u32 *buf,
unsigned int nbits);
#ifdef __BIG_ENDIAN
extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
+#define BITMAP_MIN_UNIT BITS_PER_LONG /* have to access as longs */
#else
#define bitmap_copy_le bitmap_copy
+#define BITMAP_MIN_UNIT 8 /* can access as bytes if desired */
#endif
extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int ord, unsigned int nbits);
extern int bitmap_print_to_pagebuf(bool list, char *buf,
@@ -317,8 +319,10 @@ static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
{
if (__builtin_constant_p(nbits) && nbits == 1)
__set_bit(start, map);
- else if (__builtin_constant_p(start & 7) && IS_ALIGNED(start, 8) &&
- __builtin_constant_p(nbits & 7) && IS_ALIGNED(nbits, 8))
+ else if (__builtin_constant_p(start & (BITMAP_MIN_UNIT-1)) &&
+ IS_ALIGNED(start, BITMAP_MIN_UNIT) &&
+ __builtin_constant_p(nbits & (BITMAP_MIN_UNIT-1)) &&
+ IS_ALIGNED(nbits, BITMAP_MIN_UNIT))
memset((char *)map + start / 8, 0xff, nbits / 8);
else
__bitmap_set(map, start, nbits);
@@ -329,8 +333,10 @@ static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
{
if (__builtin_constant_p(nbits) && nbits == 1)
__clear_bit(start, map);
- else if (__builtin_constant_p(start & 7) && IS_ALIGNED(start, 8) &&
- __builtin_constant_p(nbits & 7) && IS_ALIGNED(nbits, 8))
+ else if (__builtin_constant_p(start & (BITMAP_MIN_UNIT-1)) &&
+ IS_ALIGNED(start, BITMAP_MIN_UNIT) &&
+ __builtin_constant_p(nbits & (BITMAP_MIN_UNIT-1)) &&
+ IS_ALIGNED(nbits, BITMAP_MIN_UNIT))
memset((char *)map + start / 8, 0, nbits / 8);
else
__bitmap_clear(map, start, nbits);
--
2.7.4
next reply other threads:[~2017-10-25 6:57 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-25 6:57 Paul Mackerras [this message]
2017-10-25 7:39 ` [PATCH] bitmap: Fix optimization of bitmap_set/clear for big-endian machines Matthew Wilcox
2017-10-25 8:46 ` Paul Mackerras
2017-10-25 9:11 ` Matthew Wilcox
2017-10-25 10:30 ` Michael Ellerman
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=20171025065726.GA25140@fergus.ozlabs.ibm.com \
--to=paulus@ozlabs.org \
--cc=linux-s390@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=lkml@vger.kernel.org \
--cc=mawilcox@microsoft.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;
as well as URLs for NNTP newsgroup(s).