Blame SOURCES/0014-sbitmapq-Fix-for-sbitmap_word-without-cleared-member.patch

d67611
From 0d3e86fee5eead93b521a0e20a0e099ede4ab72b Mon Sep 17 00:00:00 2001
d67611
From: Kazuhito Hagio <k-hagio-ab@nec.com>
d67611
Date: Fri, 10 Jun 2022 11:49:47 +0900
d67611
Subject: [PATCH 14/18] sbitmapq: Fix for sbitmap_word without cleared member
d67611
d67611
The sbitmap_word.cleared member was added by kernel commit ea86ea2cdced
d67611
("sbitmap: ammortize cost of clearing bits") at Linux 5.0.  Without the
d67611
patch, on earlier kernels the "sbitmapq" command fails with the
d67611
following error:
d67611
d67611
  crash> sbitmapq ffff8f1a3611cf10
d67611
d67611
  sbitmapq: invalid structure member offset: sbitmap_word_cleared
d67611
            FILE: sbitmap.c  LINE: 92  FUNCTION: __sbitmap_weight()
d67611
d67611
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
d67611
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
d67611
---
d67611
 sbitmap.c | 26 ++++++++++++++++++--------
d67611
 1 file changed, 18 insertions(+), 8 deletions(-)
d67611
d67611
diff --git a/sbitmap.c b/sbitmap.c
d67611
index 152c28e6875f..c9f7209f9e3e 100644
d67611
--- a/sbitmap.c
d67611
+++ b/sbitmap.c
d67611
@@ -89,7 +89,6 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
d67611
 {
d67611
 	const ulong sbitmap_word_size = SIZE(sbitmap_word);
d67611
 	const ulong w_word_off = OFFSET(sbitmap_word_word);
d67611
-	const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
d67611
 
d67611
 	unsigned int weight = 0;
d67611
 	ulong addr = sc->map_addr;
d67611
@@ -111,7 +110,10 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
d67611
 			word = ULONG(sbitmap_word_buf + w_word_off);
d67611
 			weight += bitmap_weight(word, depth);
d67611
 		} else {
d67611
-			cleared = ULONG(sbitmap_word_buf + w_cleared_off);
d67611
+			if (VALID_MEMBER(sbitmap_word_cleared))
d67611
+				cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
d67611
+			else
d67611
+				cleared = 0;
d67611
 			weight += bitmap_weight(cleared, depth);
d67611
 		}
d67611
 
d67611
@@ -130,7 +132,10 @@ static unsigned int sbitmap_weight(const struct sbitmap_context *sc)
d67611
 
d67611
 static unsigned int sbitmap_cleared(const struct sbitmap_context *sc)
d67611
 {
d67611
-	return __sbitmap_weight(sc, false);
d67611
+	if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
d67611
+		return __sbitmap_weight(sc, false);
d67611
+
d67611
+	return 0;
d67611
 }
d67611
 
d67611
 static void sbitmap_emit_byte(unsigned int offset, uint8_t byte)
d67611
@@ -149,7 +154,6 @@ static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
d67611
 {
d67611
 	const ulong sbitmap_word_size = SIZE(sbitmap_word);
d67611
 	const ulong w_word_off = OFFSET(sbitmap_word_word);
d67611
-	const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
d67611
 
d67611
 	uint8_t byte = 0;
d67611
 	unsigned int byte_bits = 0;
d67611
@@ -169,7 +173,10 @@ static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
d67611
 		}
d67611
 
d67611
 		word = ULONG(sbitmap_word_buf + w_word_off);
d67611
-		cleared = ULONG(sbitmap_word_buf + w_cleared_off);
d67611
+		if (VALID_MEMBER(sbitmap_word_cleared))
d67611
+			cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
d67611
+		else
d67611
+			cleared = 0;
d67611
 		word_bits = __map_depth(sc, i);
d67611
 
d67611
 		word &= ~cleared;
d67611
@@ -219,7 +226,6 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
d67611
 {
d67611
 	const ulong sbitmap_word_size = SIZE(sbitmap_word);
d67611
 	const ulong w_word_off = OFFSET(sbitmap_word_word);
d67611
-	const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
d67611
 
d67611
 	unsigned int index;
d67611
 	unsigned int nr;
d67611
@@ -245,7 +251,10 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
d67611
 		}
d67611
 
d67611
 		w_word = ULONG(sbitmap_word_buf + w_word_off);
d67611
-		w_cleared = ULONG(sbitmap_word_buf + w_cleared_off);
d67611
+		if (VALID_MEMBER(sbitmap_word_cleared))
d67611
+			w_cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
d67611
+		else
d67611
+			w_cleared = 0;
d67611
 
d67611
 		depth = min(__map_depth(sc, index) - nr, sc->depth - scanned);
d67611
 
d67611
@@ -297,7 +306,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
d67611
 
d67611
 	fprintf(fp, "depth = %u\n", sc->depth);
d67611
 	fprintf(fp, "busy = %u\n", sbitmap_weight(sc) - sbitmap_cleared(sc));
d67611
-	fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
d67611
+	if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
d67611
+		fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
d67611
 	fprintf(fp, "bits_per_word = %u\n", 1U << sc->shift);
d67611
 	fprintf(fp, "map_nr = %u\n", sc->map_nr);
d67611
 
d67611
-- 
d67611
2.30.2
d67611