Skip to contentSkip to conversation

bitmap: Add bitmap_zero()/bitmap_clear() test cases

PATCH Applied Andy Shevchenko 2 participants 12 messages Jan 9, 2018 – Jan 11, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 bitmap: Add bitmap_zero()/bitmap_clear() test cases

Explicitly test bitmap_zero() and bitmap_clear() functions.

---
 lib/test_bitmap.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
lib/test_bitmap.c +30 -0
index de7ef2996a07..9734af711816 100644
@@ -105,6 +105,35 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
 #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
 #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
 
+static void __init test_zero_clear(void)
+{
+	DECLARE_BITMAP(bmap, 1024);
+
+	/* Known way to set all bits */
+	memset(bmap, 0xff, 128);
+
+	expect_eq_pbl("0-22", bmap, 23);
+	expect_eq_pbl("0-1023", bmap, 1024);
+
+	/* single-word bitmaps */
+	bitmap_clear(bmap, 0, 9);
+	expect_eq_pbl("9-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 35);
+	expect_eq_pbl("64-1023", bmap, 1024);
+
+	/* cross boundaries operations */
+	bitmap_clear(bmap, 79, 19);
+	expect_eq_pbl("64-78,98-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 115);
+	expect_eq_pbl("128-1023", bmap, 1024);
+
+	/* Zeroing entire area */
+	bitmap_zero(bmap, 1024);
+	expect_eq_pbl("", bmap, 1024);
+}
+
 static void __init test_zero_fill_copy(void)
 {
 	DECLARE_BITMAP(bmap1, 1024);
@@ -309,6 +338,7 @@ static void noinline __init test_mem_optimisations(void)
 
 static int __init test_bitmap_init(void)
 {
+	test_zero_clear();
 	test_zero_fill_copy();
 	test_bitmap_arr32();
 	test_bitmap_parselist();
Signature · 1 line
2.15.1
#1 lore raw

PATCH 2/4 bitmap: Add bitmap_fill()/bitmap_set() test cases

Explicitly test bitmap_fill() and bitmap_set() functions.

For bitmap_fill() we expect a consistent behaviour as in bitmap_zero(), i.e. the trailing bits will be set up to unsigned long boundary.

---
 lib/test_bitmap.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
lib/test_bitmap.c +30 -0
index 9734af711816..6889fcc0e1f4 100644
@@ -134,6 +134,35 @@ static void __init test_zero_clear(void)
 	expect_eq_pbl("", bmap, 1024);
 }
 
+static void __init test_fill_set(void)
+{
+	DECLARE_BITMAP(bmap, 1024);
+
+	/* Known way to clear all bits */
+	memset(bmap, 0x00, 128);
+
+	expect_eq_pbl("", bmap, 23);
+	expect_eq_pbl("", bmap, 1024);
+
+	/* single-word bitmaps */
+	bitmap_set(bmap, 0, 9);
+	expect_eq_pbl("0-8", bmap, 1024);
+
+	bitmap_fill(bmap, 35);
+	expect_eq_pbl("0-63", bmap, 1024);
+
+	/* cross boundaries operations */
+	bitmap_set(bmap, 79, 19);
+	expect_eq_pbl("0-63,79-97", bmap, 1024);
+
+	bitmap_fill(bmap, 115);
+	expect_eq_pbl("0-127", bmap, 1024);
+
+	/* Zeroing entire area */
+	bitmap_fill(bmap, 1024);
+	expect_eq_pbl("0-1023", bmap, 1024);
+}
+
 static void __init test_zero_fill_copy(void)
 {
 	DECLARE_BITMAP(bmap1, 1024);
@@ -339,6 +368,7 @@ static void noinline __init test_mem_optimisations(void)
 static int __init test_bitmap_init(void)
 {
 	test_zero_clear();
+	test_fill_set();
 	test_zero_fill_copy();
 	test_bitmap_arr32();
 	test_bitmap_parselist();
Signature · 1 line
2.15.1
#2 lore raw

PATCH 3/4 bitmap: Clean up test_zero_fill_copy() test case and rename

In reply to Andy Shevchenko

Since we have separate explicit test cases for bitmap_zero() / bitmap_clear() and bitmap_fill() / bitmap_set(), clean up test_zero_fill_copy() to only test bitmap_copy() functionality and thus rename a function to reflect the changes.

While here, replace bitmap_fill() by bitmap_set() with proper values.

---
 lib/test_bitmap.c | 29 +++++------------------------
 1 file changed, 5 insertions(+), 24 deletions(-)
lib/test_bitmap.c +5 -24
index 6889fcc0e1f4..b3f235baa05d 100644
@@ -163,7 +163,7 @@ static void __init test_fill_set(void)
 	expect_eq_pbl("0-1023", bmap, 1024);
 }
 
-static void __init test_zero_fill_copy(void)
+static void __init test_copy(void)
 {
 	DECLARE_BITMAP(bmap1, 1024);
 	DECLARE_BITMAP(bmap2, 1024);
@@ -172,36 +172,20 @@ static void __init test_zero_fill_copy(void)
 	bitmap_zero(bmap2, 1024);
 
 	/* single-word bitmaps */
-	expect_eq_pbl("", bmap1, 23);
-
-	bitmap_fill(bmap1, 19);
-	expect_eq_pbl("0-18", bmap1, 1024);
-
+	bitmap_set(bmap1, 0, 19);
 	bitmap_copy(bmap2, bmap1, 23);
 	expect_eq_pbl("0-18", bmap2, 1024);
 
-	bitmap_fill(bmap2, 23);
-	expect_eq_pbl("0-22", bmap2, 1024);
-
+	bitmap_set(bmap2, 0, 23);
 	bitmap_copy(bmap2, bmap1, 23);
 	expect_eq_pbl("0-18", bmap2, 1024);
 
-	bitmap_zero(bmap1, 23);
-	expect_eq_pbl("", bmap1, 1024);
-
 	/* multi-word bitmaps */
-	bitmap_zero(bmap1, 1024);
-	expect_eq_pbl("", bmap1, 1024);
-
-	bitmap_fill(bmap1, 109);
-	expect_eq_pbl("0-108", bmap1, 1024);
-
+	bitmap_set(bmap1, 0, 109);
 	bitmap_copy(bmap2, bmap1, 1024);
 	expect_eq_pbl("0-108", bmap2, 1024);
 
 	bitmap_fill(bmap2, 1024);
-	expect_eq_pbl("0-1023", bmap2, 1024);
-
 	bitmap_copy(bmap2, bmap1, 1024);
 	expect_eq_pbl("0-108", bmap2, 1024);
 
@@ -216,9 +200,6 @@ static void __init test_zero_fill_copy(void)
 	bitmap_fill(bmap2, 1024);
 	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
-
-	bitmap_zero(bmap2, 97);  /* ... but 0-padded til word length */
-	expect_eq_pbl("128-1023", bmap2, 1024);
 }
 
 #define PARSE_TIME 0x1
@@ -369,7 +350,7 @@ static int __init test_bitmap_init(void)
 {
 	test_zero_clear();
 	test_fill_set();
-	test_zero_fill_copy();
+	test_copy();
 	test_bitmap_arr32();
 	test_bitmap_parselist();
 	test_mem_optimisations();
Signature · 1 line
2.15.1
#3 lore raw

PATCH 4/4 bitmap: Make bitmap_fill() and bitmap_zero() consistent

In reply to Andy Shevchenko

Behaviour of bitmap_fill() differs from bitmap_zero() in a way how bits behind bitmap are handed. bitmap_zero() clears entire bitmap by unsigned long boundary, while bitmap_fill() mimics bitmap_set().

Here we change bitmap_fill() behaviour to be consistent with bitmap_zero() and add a note to documentation.

The change might reveal some bugs in the code where unused bits handled differently and in such cases bitmap_set() has to be used.

---
 include/linux/bitmap.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
include/linux/bitmap.h +10 -5
index a17b5121d4f5..49aea0b37994 100644
@@ -67,6 +67,11 @@
  *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
  *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
  *
+ * Note, bitmap_zero() and bitmap_fill() operate over the region of
+ * unsigned longs, that is, bits behind bitmap till the unsigned long
+ * boundary will be zeroed or filled as well. Consider to use
+ * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
+ * respectively.
  */
 
 /**
@@ -206,12 +211,12 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
 
 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
 {
-	unsigned int nlongs = BITS_TO_LONGS(nbits);
-	if (!small_const_nbits(nbits)) {
-		unsigned int len = (nlongs - 1) * sizeof(unsigned long);
-		memset(dst, 0xff,  len);
+	if (small_const_nbits(nbits))
+		*dst = ~0UL;
+	else {
+		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+		memset(dst, 0xff, len);
 	}
-	dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
 }
 
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
Signature · 1 line
2.15.1
#4 lore raw

Re: [PATCH v1 4/4] bitmap: Make bitmap_fill() and bitmap_zero() consistent

Quoted 9 lines · Andy Shevchenko

Behaviour of bitmap_fill() differs from bitmap_zero() in a way how bits behind bitmap are handed. bitmap_zero() clears entire bitmap by unsigned long boundary, while bitmap_fill() mimics bitmap_set().

Here we change bitmap_fill() behaviour to be consistent with bitmap_zero() and add a note to documentation.

The change might reveal some bugs in the code where unused bits handled differently and in such cases bitmap_set() has to be used.

There is only 51 users of bitmap_fill() in the kernel, including tests. If you propose this change, I think you'd check them all manually. Sorry that.

Also, there's tools/include/linux/bitmap.h which has a copy of bitmap_fill(), and should be consistent with main kernel sources.

Quoted 42 lines
---
 include/linux/bitmap.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
include/linux/bitmap.h +10 -5
index a17b5121d4f5..49aea0b37994 100644
@@ -67,6 +67,11 @@
  *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
  *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
  *
+ * Note, bitmap_zero() and bitmap_fill() operate over the region of
+ * unsigned longs, that is, bits behind bitmap till the unsigned long
+ * boundary will be zeroed or filled as well. Consider to use
+ * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
+ * respectively.
  */
 
 /**
@@ -206,12 +211,12 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
 
 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
 {
-	unsigned int nlongs = BITS_TO_LONGS(nbits);
-	if (!small_const_nbits(nbits)) {
-		unsigned int len = (nlongs - 1) * sizeof(unsigned long);
-		memset(dst, 0xff,  len);
+	if (small_const_nbits(nbits))
+		*dst = ~0UL;
+	else {
+		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+		memset(dst, 0xff, len);
 	}
-	dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
 }
 
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
Signature · 1 line
2.15.1
#5 lore raw

Re: [PATCH v1 4/4] bitmap: Make bitmap_fill() and bitmap_zero() consistent

Quoted 10 lines · Yury Norov
Quoted 9 lines · Andy Shevchenko

Behaviour of bitmap_fill() differs from bitmap_zero() in a way how bits behind bitmap are handed. bitmap_zero() clears entire bitmap
by unsigned long boundary, while bitmap_fill() mimics bitmap_set().

Here we change bitmap_fill() behaviour to be consistent with bitmap_zero()
and add a note to documentation.

Quoted 7 lines
Quoted 3 lines

The change might reveal some bugs in the code where unused bits handled
differently and in such cases bitmap_set() has to be used.

There is only 51 users of bitmap_fill() in the kernel, including tests. If you propose this change, I think you'd check them all manually.

Some of them might require 5 minutes to check while others (especially in the areas I don't know much about) 5+ hours. I rely on Rasmus assumption that there _were_ bugs, though they assumed to be fixed by now.

In any case I'm ready to take responsibility of possible breakage and fully into provide fixes by demand.

Quoted 1 line

Sorry that.

I lost your thought here. What did you mean by this?

Quoted 3 lines

Also, there's tools/include/linux/bitmap.h which has a copy of bitmap_fill(), and should be consistent with main kernel sources.

tools is independent, although quite related, project to the kernel itself. They will decide by themselves how to proceed, I suppose.

At least what I see in the history of changes in the tools/ they usually follow the changes in main library after while.

Thanks for review!

Signature · 2 lines
Andy Shevchenko <[email protected]>
Intel Finland Oy
#6 lore raw

Re: [PATCH v1 4/4] bitmap: Make bitmap_fill() and bitmap_zero() consistent

Quoted 19 lines · Andy Shevchenko
Quoted 10 lines · Yury Norov
Quoted 9 lines · Andy Shevchenko

Behaviour of bitmap_fill() differs from bitmap_zero() in a way how bits behind bitmap are handed. bitmap_zero() clears entire bitmap
by unsigned long boundary, while bitmap_fill() mimics bitmap_set().

Here we change bitmap_fill() behaviour to be consistent with bitmap_zero()
and add a note to documentation.

Quoted 7 lines
Quoted 3 lines

The change might reveal some bugs in the code where unused bits handled
differently and in such cases bitmap_set() has to be used.

There is only 51 users of bitmap_fill() in the kernel, including tests. If you propose this change, I think you'd check them all manually.

Quoted 7 lines

Some of them might require 5 minutes to check while others (especially in the areas I don't know much about) 5+ hours. I rely on Rasmus assumption that there _were_ bugs, though they assumed to be fixed by now.

In any case I'm ready to take responsibility of possible breakage and fully into provide fixes by demand.

Is my understanding correct that you need almost a working day to decide what function to use - bitmap_set() or bitmap_fill() in some cases, and there are at least 2 cases like that?

If so, there's quite realistic chance that bug will hit us 6 month after upstreaming the patch when affected kernel will be delivered to end users by distro developers.

This is not acceptable scenario. If you have willing to take responsibility, please do it now and don't wait when things go broken.

Quoted 3 lines
Quoted 1 line

Sorry that.

I lost your thought here. What did you mean by this?

I only mean that I realize that I ask you to do big amount of boring mechanical work, and I'm not happy with that.

Quoted 8 lines
Quoted 2 lines

Also, there's tools/include/linux/bitmap.h which has a copy of bitmap_fill(), and should be consistent with main kernel sources.

tools is independent, although quite related, project to the kernel itself. They will decide by themselves how to proceed, I suppose.

At least what I see in the history of changes in the tools/ they usually follow the changes in main library after while.

[CC Arnaldo Carvalho de Melo <[email protected]>]

You can always ask tools/* maintainers what is better for them. For me, people simply forget about tools/* and that's why maintainers have to sync sources periodically. Anyway, if you think that your change is good enough for Linux kernel, why don't you think so for tools?

Yury

#7 lore raw

Re: [PATCH v1 4/4] bitmap: Make bitmap_fill() and bitmap_zero() consistent

Quoted 19 lines · Yury Norov
Quoted 18 lines · Andy Shevchenko
Quoted 9 lines · Yury Norov
Quoted 3 lines · Andy Shevchenko

The change might reveal some bugs in the code where unused bits handled
differently and in such cases bitmap_set() has to be used.

There is only 51 users of bitmap_fill() in the kernel, including tests. If you propose this change, I think you'd check them all manually.

Some of them might require 5 minutes to check while others (especially
in the areas I don't know much about) 5+ hours. I rely on Rasmus assumption that there _were_ bugs, though they assumed to be fixed by
now.

Quoted 7 lines
Quoted 3 lines

In any case I'm ready to take responsibility of possible breakage and
fully into provide fixes by demand.

Is my understanding correct that you need almost a working day to decide what function to use - bitmap_set() or bitmap_fill() in some cases,

I don't know. There are like you said 51 user of the bitmap_fill().

If we lucky that developers are not so-o-o dumb to use bitmap_fill() as a replacement of bitmap_set(..., 0, ...), nothing will need to be fixed.

Quoted 1 line

and there are at least 2 cases like that?

Where this come from?

Quoted 3 lines

If so, there's quite realistic chance that bug will hit us 6 month after upstreaming the patch when affected kernel will be delivered to end users by distro developers.

It would be found much earlier in the core code, otherwise it's business as usual.

Quoted 3 lines

This is not acceptable scenario. If you have willing to take responsibility, please do it now and don't wait when things go broken.

So, instead of beating the air you can help to check the places, right?

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Sorry that.

I lost your thought here. What did you mean by this?

I only mean that I realize that I ask you to do big amount of boring mechanical work, and I'm not happy with that.

It's not mechanical, that is the point. (Incorrect) usage of bitmap_fill() is a bug. Fix that helps to reveal it earlier is a good one.

Quoted 6 lines
Quoted 6 lines
Quoted 2 lines

Also, there's tools/include/linux/bitmap.h which has a copy of bitmap_fill(), and should be consistent with main kernel sources.

tools is independent, although quite related, project to the kernel itself. They will decide by themselves how to proceed, I suppose.

Quoted 7 lines
Quoted 3 lines

At least what I see in the history of changes in the tools/ they usually
follow the changes in main library after while.

[CC Arnaldo Carvalho de Melo <[email protected]>]

You can always ask tools/* maintainers what is better for them.

Yeah, notification is a good thing.

Quoted 3 lines

For me,
people simply forget about tools/* and that's why maintainers have to sync sources periodically.

Might be, my at least one patch (and few pings) to tools code at the end is left neither commented not applied for years, so, I gave up on them, sorry @acme et al. OTOH fixes for Makefiles are usually go in quickly.

Quoted 2 lines

Anyway, if you think that your change is good
enough for Linux kernel, why don't you think so for tools?

I didn't tell that.

Signature · 2 lines
Andy Shevchenko <[email protected]>
Intel Finland Oy
Reviewed-by on v1 1/4
#8 lore raw
In reply to Andy Shevchenko

Hi Andy,

Quoted 12 lines · Andy Shevchenko

Explicitly test bitmap_zero() and bitmap_clear() functions.

---
 lib/test_bitmap.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
lib/test_bitmap.c +0 -0
index de7ef2996a07..9734af711816 100644

lib/test_bitmap.c __check_eq_u32_array(const char *srcfile, unsigned int line, · line 112

Quoted 8 lines
lib/test_bitmap.c +5 -0
@@ -105,6 +105,35 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
 #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
 #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
 
+static void __init test_zero_clear(void)
+{
+	DECLARE_BITMAP(bmap, 1024);
+
+	/* Known way to set all bits */

Nit: if you start your comments with capital, proceed that way till the end.

Quoted 28 lines
lib/test_bitmap.c +24 -0
+	memset(bmap, 0xff, 128);
+
+	expect_eq_pbl("0-22", bmap, 23);
+	expect_eq_pbl("0-1023", bmap, 1024);
+
+	/* single-word bitmaps */
+	bitmap_clear(bmap, 0, 9);
+	expect_eq_pbl("9-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 35);
+	expect_eq_pbl("64-1023", bmap, 1024);
+
+	/* cross boundaries operations */
+	bitmap_clear(bmap, 79, 19);
+	expect_eq_pbl("64-78,98-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 115);
+	expect_eq_pbl("128-1023", bmap, 1024);
+
+	/* Zeroing entire area */
+	bitmap_zero(bmap, 1024);
+	expect_eq_pbl("", bmap, 1024);
+}
+
 static void __init test_zero_fill_copy(void)
 {
 	DECLARE_BITMAP(bmap1, 1024);

lib/test_bitmap.c static void noinline __init test_mem_optimisations(void) · line 344

Quoted 7 lines
lib/test_bitmap.c +1 -0
@@ -309,6 +338,7 @@ static void noinline __init test_mem_optimisations(void)
 
 static int __init test_bitmap_init(void)
 {
+	test_zero_clear();
 	test_zero_fill_copy();
 	test_bitmap_arr32();
 	test_bitmap_parselist();

I don't understand what patch #4 is doing in this series. At the first glance, it may be applied separately.

The rest is looking fine. For 1-3,

#9 lore raw
Quoted 9 lines · Yury Norov

Hi Andy,

lib/test_bitmap.c __check_eq_u32_array(const char *srcfile, unsigned int line, · line 112

Quoted 3 lines · Andy Shevchenko

Explicitly test bitmap_zero() and bitmap_clear() functions.

lib/test_bitmap.c +1 -0
+	/* Known way to set all bits */

Nit: if you start your comments with capital, proceed that way till the end.

Right, I have to keep the original style. I'll check this.

Quoted 2 lines

I don't understand what patch #4 is doing in this series. At the first glance, it may be applied separately.

It fixes test failures found by patch 2 in the series. The idea is similar to TDD.

Quoted 2 lines

The rest is looking fine. For 1-3,

Thanks.

Signature · 2 lines
Andy Shevchenko <[email protected]>
Intel Finland Oy
#10 lore raw
Quoted 11 lines · Andy Shevchenko
Quoted 9 lines · Yury Norov

Hi Andy,

lib/test_bitmap.c __check_eq_u32_array(const char *srcfile, unsigned int line, · line 112

Quoted 3 lines · Andy Shevchenko

Explicitly test bitmap_zero() and bitmap_clear() functions.

lib/test_bitmap.c +1 -0
+	/* Known way to set all bits */

Nit: if you start your comments with capital, proceed that way till the end.

Quoted 7 lines

Right, I have to keep the original style. I'll check this.

Quoted 2 lines

I don't understand what patch #4 is doing in this series. At the first glance, it may be applied separately.

It fixes test failures found by patch 2 in the series. The idea is similar to TDD.

So with current order, patch 2 introduces regression that is fixed in patch 4, is my understanding correct?

This is not the best idea because it will break bisectability. I would recommend you to change the order and move patch #4 to the begin.

Also it would be reasonable to leave a note in patch 2 comment that it causes regression if applied alone.

Yury

#11 lore raw
Quoted 8 lines · Yury Norov
Quoted 7 lines · Andy Shevchenko
Quoted 5 lines · Yury Norov

I don't understand what patch #4 is doing in this series. At the first
glance, it may be applied separately.

Quoted 5 lines
Quoted 2 lines

It fixes test failures found by patch 2 in the series. The idea is similar to TDD.

So with current order, patch 2 introduces regression that is fixed in patch 4, is my understanding correct?

I'm sorry to ask, but do you call new test cases "a regression" for real?!

Quoted 1 line

This is not the best idea because it will break bisectability.

Huh?

Signature · 2 lines
Andy Shevchenko <[email protected]>
Intel Finland Oy