Patch "bitmap: fix memset optimization on big-endian systems" has been added to the 4.15-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
bitmap: fix memset optimization on big-endian systems
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
bitmap-fix-memset-optimization-on-big-endian-systems.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
21035965f60b0502fc6537b232839389bb4ce664Mon Sep 17 00:00:00 2001
From: Omar Sandoval <[email protected]>
Date: Mon, 2 Apr 2018 15:58:31 -0700
Subject: bitmap: fix memset optimization on big-endian systems
From: Omar Sandoval <[email protected]>
commit 21035965f60b0502fc6537b232839389bb4ce664 upstream.
Commit 2a98dc028f91 ("include/linux/bitmap.h: turn bitmap_set and bitmap_clear into memset when possible") introduced an optimization to bitmap_{set,clear}() which uses memset() when the start and length are constants aligned to a byte.
This is wrong on big-endian systems; our bitmaps are arrays of unsigned long, so bit n is not at byte n / 8 in memory. This was caught by the Btrfs selftests, but the bitmap selftests also fail when run on a big-endian machine.
We can still use memset if the start and length are aligned to an unsigned long, so do that on big-endian. The same problem applies to the memcmp in bitmap_equal(), so fix it there, too.
--- include/linux/bitmap.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
include/linux/bitmap.h +17 -5
@@ -271,12 +271,20 @@ static inline void bitmap_complement(uns__bitmap_complement (dst, src, nbits); } +#ifdef __LITTLE_ENDIAN +#define BITMAP_MEM_ALIGNMENT 8 +#else +#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long)) +#endif +#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1) +static inline int bitmap_equal (const unsigned long *src1,const unsigned long *src2,unsigned int nbits) {if (small_const_nbits (nbits))return !((*src1 ^ *src2) &BITMAP_LAST_WORD_MASK (nbits)); -if (__builtin_constant_p (nbits &7 ) &&IS_ALIGNED (nbits,8 )) +if (__builtin_constant_p (nbits &BITMAP_MEM_MASK ) && +IS_ALIGNED (nbits,BITMAP_MEM_ALIGNMENT ))return !memcmp (src1, src2, nbits /8 );return __bitmap_equal (src1, src2, nbits); }
@@ -327,8 +335,10 @@ static __always_inline void bitmap_set(u {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_MEM_MASK ) && +IS_ALIGNED (start,BITMAP_MEM_ALIGNMENT ) && +__builtin_constant_p (nbits &BITMAP_MEM_MASK ) && +IS_ALIGNED (nbits,BITMAP_MEM_ALIGNMENT ))memset ((char *)map + start /8 ,0xff , nbits /8 );else __bitmap_set (map, start, nbits);
@@ -339,8 +349,10 @@ static __always_inline void bitmap_clear {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_MEM_MASK ) && +IS_ALIGNED (start,BITMAP_MEM_ALIGNMENT ) && +__builtin_constant_p (nbits &BITMAP_MEM_MASK ) && +IS_ALIGNED (nbits,BITMAP_MEM_ALIGNMENT ))memset ((char *)map + start /8 ,0 , nbits /8 );else __bitmap_clear (map, start, nbits);
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/bitmap-fix-memset-optimization-on-big-endian-systems.patch