All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Improve bitmap_empty and bitmap_full
@ 2015-11-19  6:48 Jia He
  2015-11-19  6:48 ` [PATCH v2 1/3] linux/bitmap: Move 2 mask macro from bitmap.h to bitops.h Jia He
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Jia He @ 2015-11-19  6:48 UTC (permalink / raw)
  To: linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann, Jia He

find_fisrt_{zero_}bit are too heavy for bitmap_{full,empty}. We don't 
need to calculate and compare the position of bitmap. This set of patch
instroduces lightweight api and replaces the heavy one.

v2: Move the declarations to linux/bitops.h for compilation

Jia He (3):
  Move 2 mask macro from bitmap.h to bitops.h
  Introduce 2 bit ops api: all_is_bit_{one,zero}
  Replace find_fisrt_{zero_}bit with the new lightweight api

 include/linux/bitmap.h |  7 ++-----
 include/linux/bitops.h |  7 +++++++
 lib/find_bit.c         | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 5 deletions(-)

-- 
2.5.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/3] linux/bitmap: Move 2 mask macro from bitmap.h to bitops.h
  2015-11-19  6:48 [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Jia He
@ 2015-11-19  6:48 ` Jia He
  2015-11-19  6:48 ` [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero} Jia He
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Jia He @ 2015-11-19  6:48 UTC (permalink / raw)
  To: linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann, Jia He

This patch moves the mask macro to bitops.h and then the new introduced
api in find_bit.c can use it.

Signed-off-by: Jia He <hejianet@gmail.com>
---
 include/linux/bitmap.h | 3 ---
 include/linux/bitops.h | 4 ++++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 9653fdb..15524f6 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -172,9 +172,6 @@ extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int
 extern int bitmap_print_to_pagebuf(bool list, char *buf,
 				   const unsigned long *maskp, int nmaskbits);
 
-#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
-#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
-
 #define small_const_nbits(nbits) \
 	(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
 
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 2b8ed12..b881028 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -24,6 +24,10 @@
 #define GENMASK_ULL(h, l) \
 	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
+/* For bitmap ops*/
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
+#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
+
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
 extern unsigned int __sw_hweight32(unsigned int w);
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero}
  2015-11-19  6:48 [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Jia He
  2015-11-19  6:48 ` [PATCH v2 1/3] linux/bitmap: Move 2 mask macro from bitmap.h to bitops.h Jia He
@ 2015-11-19  6:48 ` Jia He
  2015-11-19  8:40   ` xinhui
  2015-11-19  8:49   ` yalin wang
  2015-11-19  6:48 ` [PATCH v3 3/3] linux/bitmap: Replace find_fisrt_{zero_}bit with the new lightweight api Jia He
  2015-11-19  9:01 ` [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Rasmus Villemoes
  3 siblings, 2 replies; 8+ messages in thread
From: Jia He @ 2015-11-19  6:48 UTC (permalink / raw)
  To: linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann, Jia He

This patch introduces 2 lightweight bit api.
all_bit_is_zero return 1 if the bit string is all zero.
The addr is the start address, the size is the bit size of the bit string.
all_bit_is_one is the opposite.

Signed-off-by: Jia He <hejianet@gmail.com>
---
 lib/find_bit.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/lib/find_bit.c b/lib/find_bit.c
index 18072ea..1d56d8d 100644
--- a/lib/find_bit.c
+++ b/lib/find_bit.c
@@ -131,6 +131,56 @@ unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
 EXPORT_SYMBOL(find_last_bit);
 #endif
 
+#ifndef all_bit_is_zero
+/*
+ * return val: 1 means all bit is zero
+ */
+unsigned int all_bit_is_zero(const unsigned long *addr, unsigned size)
+{
+	unsigned long idx;
+	unsigned long mask = size;
+
+	if (unlikely(size == 0))
+		return 1;
+
+	if (size > BITS_PER_LONG) {
+		for (idx = 0; idx * BITS_PER_LONG < size; idx++)
+			if (addr[idx])
+				return 0;
+
+		mask = size - (idx - 1) * BITS_PER_LONG;
+	}
+
+	return !(*addr & BITMAP_LAST_WORD_MASK(mask));
+}
+EXPORT_SYMBOL(all_bit_is_zero);
+#endif
+
+#ifndef all_bit_is_one
+/*
+ * return val: 1 means all bit is one
+ */
+unsigned int all_bit_is_one(const unsigned long *addr, unsigned size)
+{
+	unsigned long idx;
+	unsigned long mask = size;
+
+	if (unlikely(size == 0))
+		return 1;
+
+	if (size > BITS_PER_LONG) {
+		for (idx = 0; idx * BITS_PER_LONG < size; idx++)
+			if (~addr[idx])
+				return 0;
+
+		mask = size - (idx - 1) * BITS_PER_LONG;
+	}
+
+	return !(~(*addr) & BITMAP_LAST_WORD_MASK(mask));
+}
+EXPORT_SYMBOL(all_bit_is_one);
+#endif
+
 #ifdef __BIG_ENDIAN
 
 /* include/linux/byteorder does not support "unsigned long" type */
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] linux/bitmap: Replace find_fisrt_{zero_}bit with the new lightweight api
  2015-11-19  6:48 [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Jia He
  2015-11-19  6:48 ` [PATCH v2 1/3] linux/bitmap: Move 2 mask macro from bitmap.h to bitops.h Jia He
  2015-11-19  6:48 ` [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero} Jia He
@ 2015-11-19  6:48 ` Jia He
  2015-11-19  9:01 ` [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Rasmus Villemoes
  3 siblings, 0 replies; 8+ messages in thread
From: Jia He @ 2015-11-19  6:48 UTC (permalink / raw)
  To: linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann, Jia He

This is to replace find_fisrt_{zero_}bit with the new lightweight api 
all_bit_is_{one,zero} in bitmap_{full,empty}

Signed-off-by: Jia He <hejianet@gmail.com>
---
 include/linux/bitmap.h | 4 ++--
 include/linux/bitops.h | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 15524f6..8877a68 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -281,7 +281,7 @@ static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
 	if (small_const_nbits(nbits))
 		return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
 
-	return find_first_bit(src, nbits) == nbits;
+	return all_bit_is_zero(src, nbits);
 }
 
 static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
@@ -289,7 +289,7 @@ static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
 	if (small_const_nbits(nbits))
 		return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
 
-	return find_first_zero_bit(src, nbits) == nbits;
+	return all_bit_is_one(src, nbits);
 }
 
 static __always_inline int bitmap_weight(const unsigned long *src, unsigned int nbits)
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index b881028..e34f2ff 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -214,6 +214,9 @@ static inline unsigned long __ffs64(u64 word)
 	return __ffs((unsigned long)word);
 }
 
+extern unsigned int all_bit_is_one(const unsigned long *addr, unsigned size);
+extern unsigned int all_bit_is_zero(const unsigned long *addr, unsigned size);
+
 #ifdef __KERNEL__
 
 #ifndef set_mask_bits
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero}
  2015-11-19  6:48 ` [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero} Jia He
@ 2015-11-19  8:40   ` xinhui
  2015-11-19  8:55     ` hejianet
  2015-11-19  8:49   ` yalin wang
  1 sibling, 1 reply; 8+ messages in thread
From: xinhui @ 2015-11-19  8:40 UTC (permalink / raw)
  To: Jia He, linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann

hi, jia
	Nice patch. But I have one minor question. see inline comments.

On 2015/11/19 14:48, Jia He wrote:
> This patch introduces 2 lightweight bit api.
> all_bit_is_zero return 1 if the bit string is all zero.
> The addr is the start address, the size is the bit size of the bit string.
> all_bit_is_one is the opposite.
>
> Signed-off-by: Jia He <hejianet@gmail.com>
> ---
>   lib/find_bit.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 50 insertions(+)
>
> diff --git a/lib/find_bit.c b/lib/find_bit.c
> index 18072ea..1d56d8d 100644
> --- a/lib/find_bit.c
> +++ b/lib/find_bit.c
> @@ -131,6 +131,56 @@ unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
>   EXPORT_SYMBOL(find_last_bit);
>   #endif
>
> +#ifndef all_bit_is_zero
> +/*
> + * return val: 1 means all bit is zero
> + */
> +unsigned int all_bit_is_zero(const unsigned long *addr, unsigned size)
> +{
  Seems better that size should be type of "unsigned long". Otherwise I'm afraid when we compare idx * BITS_PER_LONG with size, there might be overflow issue.

> +	unsigned long idx;
> +	unsigned long mask = size;
> +
> +	if (unlikely(size == 0))
> +		return 1;
> +
> +	if (size > BITS_PER_LONG) {
> +		for (idx = 0; idx * BITS_PER_LONG < size; idx++)
> +			if (addr[idx])
> +				return 0;
> +
> +		mask = size - (idx - 1) * BITS_PER_LONG;
> +	}
> +
> +	return !(*addr & BITMAP_LAST_WORD_MASK(mask));
> +}
> +EXPORT_SYMBOL(all_bit_is_zero);
> +#endif
> +
> +#ifndef all_bit_is_one
> +/*
> + * return val: 1 means all bit is one
> + */
> +unsigned int all_bit_is_one(const unsigned long *addr, unsigned size)
> +{
this argc of size should be type of "unsigned long", too.

thanks
xinhui

> +	unsigned long idx;
> +	unsigned long mask = size;
> +
> +	if (unlikely(size == 0))
> +		return 1;
> +
> +	if (size > BITS_PER_LONG) {
> +		for (idx = 0; idx * BITS_PER_LONG < size; idx++)
> +			if (~addr[idx])
> +				return 0;
> +
> +		mask = size - (idx - 1) * BITS_PER_LONG;
> +	}
> +
> +	return !(~(*addr) & BITMAP_LAST_WORD_MASK(mask));
> +}
> +EXPORT_SYMBOL(all_bit_is_one);
> +#endif
> +
>   #ifdef __BIG_ENDIAN
>
>   /* include/linux/byteorder does not support "unsigned long" type */
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero}
  2015-11-19  6:48 ` [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero} Jia He
  2015-11-19  8:40   ` xinhui
@ 2015-11-19  8:49   ` yalin wang
  1 sibling, 0 replies; 8+ messages in thread
From: yalin wang @ 2015-11-19  8:49 UTC (permalink / raw)
  To: Jia He
  Cc: linux-kernel, Linux-Arch, Andrew Morton, Rasmus Villemoes,
	Denys Vlasenko, Kyungmin Park, Michal Nazarewicz, Yury Norov,
	Tejun Heo, Martin Kepplinger, George Spelvin, Ingo Molnar,
	Arnd Bergmann


> On Nov 19, 2015, at 14:48, Jia He <hejianet@gmail.com> wrote:
> 
> 
why not use memcmp() to compare with  0x0000000 or 0xffffffff  ?
memcmp() have better performance on some platforms .

Thanks


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero}
  2015-11-19  8:40   ` xinhui
@ 2015-11-19  8:55     ` hejianet
  0 siblings, 0 replies; 8+ messages in thread
From: hejianet @ 2015-11-19  8:55 UTC (permalink / raw)
  To: xinhui, linux-kernel, linux-arch
  Cc: Andrew Morton, Rasmus Villemoes, Denys Vlasenko, Kyungmin Park,
	Michal Nazarewicz, Yury Norov, Tejun Heo, Martin Kepplinger,
	George Spelvin, Ingo Molnar, Arnd Bergmann

Thanks, I will add it in next verison
B.R.
Justin

在 11/19/15 4:40 PM, xinhui 写道:
> hi, jia
>     Nice patch. But I have one minor question. see inline comments.
>
> On 2015/11/19 14:48, Jia He wrote:
>> This patch introduces 2 lightweight bit api.
>> all_bit_is_zero return 1 if the bit string is all zero.
>> The addr is the start address, the size is the bit size of the bit 
>> string.
>> all_bit_is_one is the opposite.
>>
>> Signed-off-by: Jia He <hejianet@gmail.com>
>> ---
>>   lib/find_bit.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 50 insertions(+)
>>
>> diff --git a/lib/find_bit.c b/lib/find_bit.c
>> index 18072ea..1d56d8d 100644
>> --- a/lib/find_bit.c
>> +++ b/lib/find_bit.c
>> @@ -131,6 +131,56 @@ unsigned long find_last_bit(const unsigned long 
>> *addr, unsigned long size)
>>   EXPORT_SYMBOL(find_last_bit);
>>   #endif
>>
>> +#ifndef all_bit_is_zero
>> +/*
>> + * return val: 1 means all bit is zero
>> + */
>> +unsigned int all_bit_is_zero(const unsigned long *addr, unsigned size)
>> +{
>  Seems better that size should be type of "unsigned long". Otherwise 
> I'm afraid when we compare idx * BITS_PER_LONG with size, there might 
> be overflow issue.
>
>> +    unsigned long idx;
>> +    unsigned long mask = size;
>> +
>> +    if (unlikely(size == 0))
>> +        return 1;
>> +
>> +    if (size > BITS_PER_LONG) {
>> +        for (idx = 0; idx * BITS_PER_LONG < size; idx++)
>> +            if (addr[idx])
>> +                return 0;
>> +
>> +        mask = size - (idx - 1) * BITS_PER_LONG;
>> +    }
>> +
>> +    return !(*addr & BITMAP_LAST_WORD_MASK(mask));
>> +}
>> +EXPORT_SYMBOL(all_bit_is_zero);
>> +#endif
>> +
>> +#ifndef all_bit_is_one
>> +/*
>> + * return val: 1 means all bit is one
>> + */
>> +unsigned int all_bit_is_one(const unsigned long *addr, unsigned size)
>> +{
> this argc of size should be type of "unsigned long", too.
>
> thanks
> xinhui
>
>> +    unsigned long idx;
>> +    unsigned long mask = size;
>> +
>> +    if (unlikely(size == 0))
>> +        return 1;
>> +
>> +    if (size > BITS_PER_LONG) {
>> +        for (idx = 0; idx * BITS_PER_LONG < size; idx++)
>> +            if (~addr[idx])
>> +                return 0;
>> +
>> +        mask = size - (idx - 1) * BITS_PER_LONG;
>> +    }
>> +
>> +    return !(~(*addr) & BITMAP_LAST_WORD_MASK(mask));
>> +}
>> +EXPORT_SYMBOL(all_bit_is_one);
>> +#endif
>> +
>>   #ifdef __BIG_ENDIAN
>>
>>   /* include/linux/byteorder does not support "unsigned long" type */
>>
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe 
> linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/3] Improve bitmap_empty and bitmap_full
  2015-11-19  6:48 [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Jia He
                   ` (2 preceding siblings ...)
  2015-11-19  6:48 ` [PATCH v3 3/3] linux/bitmap: Replace find_fisrt_{zero_}bit with the new lightweight api Jia He
@ 2015-11-19  9:01 ` Rasmus Villemoes
  3 siblings, 0 replies; 8+ messages in thread
From: Rasmus Villemoes @ 2015-11-19  9:01 UTC (permalink / raw)
  To: Jia He
  Cc: linux-kernel, linux-arch, Andrew Morton, Denys Vlasenko,
	Kyungmin Park, Michal Nazarewicz, Yury Norov, Tejun Heo,
	Martin Kepplinger, George Spelvin, Ingo Molnar, Arnd Bergmann

On Thu, Nov 19 2015, Jia He <hejianet@gmail.com> wrote:

> find_fisrt_{zero_}bit are too heavy for bitmap_{full,empty}. We don't 
> need to calculate and compare the position of bitmap. This set of patch
> instroduces lightweight api and replaces the heavy one.
>

Please check the history of the code you're modifying. git blame
include/linux/bitmap.h would immediately point you to 2afe27c718b
"lib/bitmap.c: bitmap_[empty,full]: remove code duplication". While it's
obviously true that find_first_bit does slightly more work than strictly
necessary to establish whether the bitmap is empty, it does the same
number of memory accesses, so I wouldn't consider it particularly
heavy-weight. Getting rid of .text as 2afe27c718b did is a good thing,
so you'd have to explain why we should reintroduce specialized functions
for this.

Your code is also buggy :-(

Rasmus

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-19  9:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-19  6:48 [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Jia He
2015-11-19  6:48 ` [PATCH v2 1/3] linux/bitmap: Move 2 mask macro from bitmap.h to bitops.h Jia He
2015-11-19  6:48 ` [PATCH v2 2/3] lib: Introduce 2 bit ops api: all_is_bit_{one,zero} Jia He
2015-11-19  8:40   ` xinhui
2015-11-19  8:55     ` hejianet
2015-11-19  8:49   ` yalin wang
2015-11-19  6:48 ` [PATCH v3 3/3] linux/bitmap: Replace find_fisrt_{zero_}bit with the new lightweight api Jia He
2015-11-19  9:01 ` [PATCH v2 0/3] Improve bitmap_empty and bitmap_full Rasmus Villemoes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.