Hi, Kazu
On Fri, Jun 10, 2022 at 10:55 AM Kazuhito Hagio <[email protected]> wrote:

> The sbitmap_word.cleared member was added by kernel commit ea86ea2cdced
> ("sbitmap: ammortize cost of clearing bits") at Linux 5.0.  Without the
> patch, on earlier kernels the "sbitmapq" command fails with the
> following error:
>
>   crash> sbitmapq ffff8f1a3611cf10
>
>   sbitmapq: invalid structure member offset: sbitmap_word_cleared
>             FILE: sbitmap.c  LINE: 92  FUNCTION: __sbitmap_weight()
>
> Signed-off-by: Kazuhito Hagio <[email protected]>
> ---
>  sbitmap.c | 26 ++++++++++++++++++--------
>  1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/sbitmap.c b/sbitmap.c
> index 37db21d15219..c8c9f2b6d003 100644
> --- a/sbitmap.c
> +++ b/sbitmap.c
> @@ -89,7 +89,6 @@ static unsigned int __sbitmap_weight(const struct
> sbitmap_context *sc, bool set)
>  {
>         const ulong sbitmap_word_size = SIZE(sbitmap_word);
>         const ulong w_word_off = OFFSET(sbitmap_word_word);
> -       const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
>
>         unsigned int weight = 0;
>         ulong addr = sc->map_addr;
> @@ -111,7 +110,10 @@ static unsigned int __sbitmap_weight(const struct
> sbitmap_context *sc, bool set)
>                         word = ULONG(sbitmap_word_buf + w_word_off);
>                         weight += bitmap_weight(word, depth);
>                 } else {
> -                       cleared = ULONG(sbitmap_word_buf + w_cleared_off);
> +                       if (VALID_MEMBER(sbitmap_word_cleared))
> +                               cleared = ULONG(sbitmap_word_buf +
> OFFSET(sbitmap_word_cleared));
> +                       else
> +                               cleared = 0;
>                         weight += bitmap_weight(cleared, depth);
>                 }
>
> @@ -130,7 +132,10 @@ static unsigned int sbitmap_weight(const struct
> sbitmap_context *sc)
>
>  static unsigned int sbitmap_cleared(const struct sbitmap_context *sc)
>  {
> -       return __sbitmap_weight(sc, false);
> +       if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
> +               return __sbitmap_weight(sc, false);
> +       else
>

The above "else" can be removed, and the result is the same.

Other changes look good to me, for these three patches:
Acked-by: Lianbo Jiang <[email protected]>

Thanks.

+               return 0;
>  }
>
>  static void sbitmap_emit_byte(unsigned int offset, uint8_t byte)
> @@ -149,7 +154,6 @@ static void sbitmap_bitmap_show(const struct
> sbitmap_context *sc)
>  {
>         const ulong sbitmap_word_size = SIZE(sbitmap_word);
>         const ulong w_word_off = OFFSET(sbitmap_word_word);
> -       const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
>
>         uint8_t byte = 0;
>         unsigned int byte_bits = 0;
> @@ -169,7 +173,10 @@ static void sbitmap_bitmap_show(const struct
> sbitmap_context *sc)
>                 }
>
>                 word = ULONG(sbitmap_word_buf + w_word_off);
> -               cleared = ULONG(sbitmap_word_buf + w_cleared_off);
> +               if (VALID_MEMBER(sbitmap_word_cleared))
> +                       cleared = ULONG(sbitmap_word_buf +
> OFFSET(sbitmap_word_cleared));
> +               else
> +                       cleared = 0;
>                 word_bits = __map_depth(sc, i);
>
>                 word &= ~cleared;
> @@ -219,7 +226,6 @@ static void __sbitmap_for_each_set(const struct
> sbitmap_context *sc,
>  {
>         const ulong sbitmap_word_size = SIZE(sbitmap_word);
>         const ulong w_word_off = OFFSET(sbitmap_word_word);
> -       const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
>
>         unsigned int index;
>         unsigned int nr;
> @@ -245,7 +251,10 @@ static void __sbitmap_for_each_set(const struct
> sbitmap_context *sc,
>                 }
>
>                 w_word = ULONG(sbitmap_word_buf + w_word_off);
> -               w_cleared = ULONG(sbitmap_word_buf + w_cleared_off);
> +               if (VALID_MEMBER(sbitmap_word_cleared))
> +                       w_cleared = ULONG(sbitmap_word_buf +
> OFFSET(sbitmap_word_cleared));
> +               else
> +                       w_cleared = 0;
>
>                 depth = min(__map_depth(sc, index) - nr, sc->depth -
> scanned);
>
> @@ -297,7 +306,8 @@ static void sbitmap_queue_show(const struct
> sbitmap_queue_context *sqc,
>
>         fprintf(fp, "depth = %u\n", sc->depth);
>         fprintf(fp, "busy = %u\n", sbitmap_weight(sc) -
> sbitmap_cleared(sc));
> -       fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
> +       if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
> +               fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
>         fprintf(fp, "bits_per_word = %u\n", 1U << sc->shift);
>         fprintf(fp, "map_nr = %u\n", sc->map_nr);
>
> --
> 2.27.0
>
>
--
Crash-utility mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to