From a295cb40cd5d24fb5995cc78d29c5def3843d285 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Mon, 23 May 2022 18:04:14 +0800 Subject: [PATCH 02/15] sbitmapq: fix invalid offset for "sbitmap_queue_alloc_hint" on Linux v5.13-rc1 Kernel commit c548e62bcf6a ("scsi: sbitmap: Move allocation hint into sbitmap") moved the alloc_hint member from struct sbitmap_queue to struct sbitmap. Without the patch, the sbitmapq will fail: crash> sbitmapq 0xffff8e99d0dc8010 sbitmapq: invalid structure member offset: sbitmap_queue_alloc_hint FILE: sbitmap.c LINE: 365 FUNCTION: sbitmap_queue_context_load() Signed-off-by: Lianbo Jiang --- defs.h | 2 ++ sbitmap.c | 14 ++++++++++++-- symbols.c | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/defs.h b/defs.h index a6735d07b32f..0aeb98c4f654 100644 --- a/defs.h +++ b/defs.h @@ -2168,6 +2168,7 @@ struct offset_table { /* stash of commonly-used offsets */ long sbitmap_queue_min_shallow_depth; long sbq_wait_state_wait_cnt; long sbq_wait_state_wait; + long sbitmap_alloc_hint; }; struct size_table { /* stash of commonly-used sizes */ @@ -5907,6 +5908,7 @@ struct sbitmap_context { unsigned shift; unsigned map_nr; ulong map_addr; + ulong alloc_hint; }; typedef bool (*sbitmap_for_each_fn)(unsigned int idx, void *p); diff --git a/sbitmap.c b/sbitmap.c index 7693eef6cebd..2921d5447c65 100644 --- a/sbitmap.c +++ b/sbitmap.c @@ -285,6 +285,7 @@ void sbitmap_for_each_set(const struct sbitmap_context *sc, static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc, const struct sbitmap_context *sc) { + ulong alloc_hint_addr = 0; int cpus = get_cpus_possible(); int sbq_wait_state_size, wait_cnt_off, wait_off, list_head_off; char *sbq_wait_state_buf; @@ -297,6 +298,11 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc, fprintf(fp, "bits_per_word = %u\n", 1U << sc->shift); fprintf(fp, "map_nr = %u\n", sc->map_nr); + if (VALID_MEMBER(sbitmap_queue_alloc_hint)) + alloc_hint_addr = sqc->alloc_hint; + else if (VALID_MEMBER(sbitmap_alloc_hint)) /* 5.13 and later */ + alloc_hint_addr = sc->alloc_hint; + fputs("alloc_hint = {", fp); first = true; for (i = 0; i < cpus; i++) { @@ -307,7 +313,7 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc, fprintf(fp, ", "); first = false; - ptr = kt->__per_cpu_offset[i] + sqc->alloc_hint; + ptr = kt->__per_cpu_offset[i] + alloc_hint_addr; readmem(ptr, KVADDR, &val, sizeof(val), "alloc_hint", FAULT_ON_ERROR); fprintf(fp, "%u", val); @@ -362,7 +368,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context error(FATAL, "cannot read sbitmap_queue\n"); } - sqc->alloc_hint = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_alloc_hint)); + if (VALID_MEMBER(sbitmap_queue_alloc_hint)) + sqc->alloc_hint = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_alloc_hint)); sqc->wake_batch = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_batch)); sqc->wake_index = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_index)); sqc->ws_addr = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws)); @@ -387,6 +394,8 @@ void sbitmap_context_load(ulong addr, struct sbitmap_context *sc) sc->shift = UINT(sbitmap_buf + OFFSET(sbitmap_shift)); sc->map_nr = UINT(sbitmap_buf + OFFSET(sbitmap_map_nr)); sc->map_addr = ULONG(sbitmap_buf + OFFSET(sbitmap_map)); + if (VALID_MEMBER(sbitmap_alloc_hint)) + sc->alloc_hint = ULONG(sbitmap_buf + OFFSET(sbitmap_alloc_hint)); FREEBUF(sbitmap_buf); } @@ -512,6 +521,7 @@ void sbitmapq_init(void) MEMBER_OFFSET_INIT(sbitmap_shift, "sbitmap", "shift"); MEMBER_OFFSET_INIT(sbitmap_map_nr, "sbitmap", "map_nr"); MEMBER_OFFSET_INIT(sbitmap_map, "sbitmap", "map"); + MEMBER_OFFSET_INIT(sbitmap_alloc_hint, "sbitmap", "alloc_hint"); MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb"); MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint"); diff --git a/symbols.c b/symbols.c index ba5e2741347d..fd0eb06899f0 100644 --- a/symbols.c +++ b/symbols.c @@ -10708,6 +10708,8 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(sbitmap_map_nr)); fprintf(fp, " sbitmap_map: %ld\n", OFFSET(sbitmap_map)); + fprintf(fp, " sbitmap_alloc_hint: %ld\n", + OFFSET(sbitmap_alloc_hint)); fprintf(fp, " sbitmap_queue_sb: %ld\n", OFFSET(sbitmap_queue_sb)); fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n", -- 2.30.2