Merge branch 'c9' into a9

This commit is contained in:
eabdullin 2022-11-15 10:27:31 +00:00 committed by Stepan Oksanichenko
commit 4cf0624999
38 changed files with 1691 additions and 1498 deletions

View File

@ -1,2 +1,2 @@
692a903aa3cae47cf2c5dbb7fe79ae6e774e3641 SOURCES/crash-8.0.0.tar.gz
c5511a10f2be0d44a74d7d832663a5567befad3f SOURCES/crash-8.0.1.tar.gz
6bf5ee7877a4740835745ed97ce525a00bb2232c SOURCES/gdb-10.2.tar.gz

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/crash-8.0.0.tar.gz
SOURCES/crash-8.0.1.tar.gz
SOURCES/gdb-10.2.tar.gz

View File

@ -1,59 +0,0 @@
From 70a27ae9f2b45d6dba56ee4240b6adf79c544ee1 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 6 Jan 2022 22:34:26 +0800
Subject: [PATCH 01/10] Fix for "timer -r" option to display all the per-CPU
clocks
Currently, the hrtimer_max_clock_bases is hard-coded to 3, which
makes that crash only prints three clocks, and the rest of clocks
are not displayed.
Without the patch:
crash> timer -r -C 11
CPU: 11 HRTIMER_CPU_BASE: ffff9a775f95ee00
CLOCK: 0 HRTIMER_CLOCK_BASE: ffff9a775f95ee80 [ktime_get]
(empty)
CLOCK: 1 HRTIMER_CLOCK_BASE: ffff9a775f95ef00 [ktime_get_real]
(empty)
CLOCK: 2 HRTIMER_CLOCK_BASE: ffff9a775f95ef80 [ktime_get_boottime]
(empty)
With the patch:
crash> timer -r -C 11
CPU: 11 HRTIMER_CPU_BASE: ffff9a775f95ee00
CLOCK: 0 HRTIMER_CLOCK_BASE: ffff9a775f95ee80 [ktime_get]
(empty)
CLOCK: 1 HRTIMER_CLOCK_BASE: ffff9a775f95ef00 [ktime_get_real]
(empty)
CLOCK: 2 HRTIMER_CLOCK_BASE: ffff9a775f95ef80 [ktime_get_boottime]
(empty)
...
CLOCK: 7 HRTIMER_CLOCK_BASE: ffff9a775f95f200 [ktime_get_clocktai]
(empty)
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel.c b/kernel.c
index 37b7af74ed2e..36c57ed501ad 100644
--- a/kernel.c
+++ b/kernel.c
@@ -7675,7 +7675,8 @@ dump_hrtimer_data(const ulong *cpus)
if (VALID_STRUCT(hrtimer_clock_base)) {
hrtimer_max_clock_bases = 2;
if (symbol_exists("ktime_get_boottime"))
- hrtimer_max_clock_bases = 3;
+ hrtimer_max_clock_bases = MEMBER_SIZE("hrtimer_cpu_base", "clock_base") /
+ SIZE(hrtimer_clock_base);
} else if (VALID_STRUCT(hrtimer_base)) {
max_hrtimer_bases = 2;
} else
--
2.20.1

View File

@ -1,69 +0,0 @@
From 7eba220e1a7d443cad6716dd83d4953ffd62d566 Mon Sep 17 00:00:00 2001
From: Qi Zheng <zhengqi.arch@bytedance.com>
Date: Tue, 21 Dec 2021 15:40:31 +0800
Subject: [PATCH 1/2] Fix pvops Xen detection for arm machine
Since the xen_start_info on the arm/arm64 platform points to a static
variable '_xen_start_info'(see its definition as below), which makes
that the address of xen_start_info will never be null.
arch/arm/xen/enlighten.c:40:static struct start_info _xen_start_info;
arch/arm/xen/enlighten.c:41:struct start_info *xen_start_info = &_xen_start_info;
arch/arm/xen/enlighten.c:42:EXPORT_SYMBOL(xen_start_info);
As a result, the is_pvops_xen() in commit 4badc6229c69 ("Fix pvops
Xen detection for kernels >= v4.20") always returns TRUE because it
can always read out the non-null address of xen_start_info, finally
the following error will be reported on arm/arm64 platform(non-Xen
environment) because p2m_mid_missing and xen_p2m_addr are not defined:
crash: cannot resolve "p2m_top"
For the arm/arm64 platform, fix it by using xen_vcpu_info instead of
xen_start_info to detect Xen dumps.
In addition, also explicitly narrow the scope of the xen_start_info
check to x86 with the machine_type(), there is no need to check it on
other architectures.
Fixes: 4badc6229c69 ("Fix pvops Xen detection for kernels >= v4.20")
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
kernel.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/kernel.c b/kernel.c
index f4598ea217a3..37b7af74ed2e 100644
--- a/kernel.c
+++ b/kernel.c
@@ -10757,11 +10757,21 @@ is_pvops_xen(void)
STREQ(sym, "paravirt_patch_default")))
return TRUE;
- if (symbol_exists("xen_start_info") &&
- readmem(symbol_value("xen_start_info"), KVADDR, &addr,
- sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
- addr != 0)
- return TRUE;
+ if (machine_type("X86") || machine_type("X86_64")) {
+ if (symbol_exists("xen_start_info") &&
+ readmem(symbol_value("xen_start_info"), KVADDR, &addr,
+ sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
+ addr != 0)
+ return TRUE;
+ }
+
+ if (machine_type("ARM") || machine_type("ARM64")) {
+ if (symbol_exists("xen_vcpu_info") &&
+ readmem(symbol_value("xen_vcpu_info"), KVADDR, &addr,
+ sizeof(void *), "xen_vcpu_info", RETURN_ON_ERROR) &&
+ addr != 0)
+ return TRUE;
+ }
return FALSE;
}
--
2.20.1

View File

@ -1,379 +0,0 @@
From 995db8ab88916b6397676b67be98c0a4f82cca49 Mon Sep 17 00:00:00 2001
From: Hong YANG <hong.yang3@nio.com>
Date: Mon, 15 Nov 2021 15:41:01 +0800
Subject: [PATCH 1/3] arm64: Support overflow stack panic
Kernel commit <872d8327ce89> ("arm64: add VMAP_STACK overflow detection")
has supported the overflow stack exception handling. Without the patch, the
"bt" command will make crash generate a core dump because of segmentation
fault. With the patch, the "bt" command can display the overflow stack.
Before:
crash> bt
PID: 3607 TASK: ffffffcbf9a4da00 CPU: 2 COMMAND: "sh"
Segmentation fault (core dumped)
After:
crash> bt
PID: 3607 TASK: ffffffcbf9a4da00 CPU: 2 COMMAND: "sh"
#0 [ffffffccbfd85f50] __delay at ffffff8008ceded8
...
#5 [ffffffccbfd85fd0] emergency_restart at ffffff80080d49fc
#6 [ffffffccbfd86140] panic at ffffff80080af4c0
#7 [ffffffccbfd86150] nmi_panic at ffffff80080af150
#8 [ffffffccbfd86190] handle_bad_stack at ffffff800808b0b8
#9 [ffffffccbfd862d0] __bad_stack at ffffff800808285c
PC: ffffff8008082e80 [el1_sync]
LR: ffffff8000d6c214 [stack_overflow_demo+84]
SP: ffffff1a79930070 PSTATE: 204003c5
X29: ffffff8011b03d00 X28: ffffffcbf9a4da00 X27: ffffff8008e02000
X26: 0000000000000040 X25: 0000000000000124 X24: ffffffcbf9a4da00
X23: 0000007daec2e288 X22: ffffffcbfe03b800 X21: 0000007daec2e288
X20: 0000000000000002 X19: 0000000000000002 X18: 0000000000000002
X17: 00000000000003e7 X16: 0000000000000000 X15: 0000000000000000
X14: ffffffcc17facb00 X13: ffffffccb4c25c00 X12: 0000000000000000
X11: ffffffcc17fad660 X10: 0000000000000af0 X9: 0000000000000000
X8: ffffff1a799334f0 X7: 0000000000000000 X6: 000000000000003f
X5: 0000000000000040 X4: 0000000000000010 X3: 00000065981d07f0
X2: 00000065981d07f0 X1: 0000000000000000 X0: ffffff1a799334f0
Signed-off-by: Hong YANG <hong.yang3@nio.com>
---
arm64.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++------
defs.h | 6 ++
2 files changed, 159 insertions(+), 16 deletions(-)
diff --git a/arm64.c b/arm64.c
index 94681d1a37db..23c3d75d85aa 100644
--- a/arm64.c
+++ b/arm64.c
@@ -45,6 +45,7 @@ static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int);
static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int);
static ulong arm64_get_task_pgd(ulong);
static void arm64_irq_stack_init(void);
+static void arm64_overflow_stack_init(void);
static void arm64_stackframe_init(void);
static int arm64_eframe_search(struct bt_info *);
static int arm64_is_kernel_exception_frame(struct bt_info *, ulong);
@@ -63,6 +64,7 @@ static int arm64_get_dumpfile_stackframe(struct bt_info *, struct arm64_stackfra
static int arm64_in_kdump_text(struct bt_info *, struct arm64_stackframe *);
static int arm64_in_kdump_text_on_irq_stack(struct bt_info *);
static int arm64_switch_stack(struct bt_info *, struct arm64_stackframe *, FILE *);
+static int arm64_switch_stack_from_overflow(struct bt_info *, struct arm64_stackframe *, FILE *);
static int arm64_get_stackframe(struct bt_info *, struct arm64_stackframe *);
static void arm64_get_stack_frame(struct bt_info *, ulong *, ulong *);
static void arm64_gen_hidden_frame(struct bt_info *bt, ulong, struct arm64_stackframe *);
@@ -78,8 +80,11 @@ static int arm64_get_smp_cpus(void);
static void arm64_clear_machdep_cache(void);
static int arm64_on_process_stack(struct bt_info *, ulong);
static int arm64_in_alternate_stack(int, ulong);
+static int arm64_in_alternate_stackv(int cpu, ulong stkptr, ulong *stacks, ulong stack_size);
static int arm64_on_irq_stack(int, ulong);
+static int arm64_on_overflow_stack(int, ulong);
static void arm64_set_irq_stack(struct bt_info *);
+static void arm64_set_overflow_stack(struct bt_info *);
static void arm64_set_process_stack(struct bt_info *);
static int arm64_get_kvaddr_ranges(struct vaddr_range *);
static void arm64_get_crash_notes(void);
@@ -463,6 +468,7 @@ arm64_init(int when)
machdep->hz = 100;
arm64_irq_stack_init();
+ arm64_overflow_stack_init();
arm64_stackframe_init();
break;
@@ -1715,6 +1721,49 @@ arm64_irq_stack_init(void)
}
}
+/*
+ * Gather Overflow stack values.
+ *
+ * Overflow stack supported since 4.14, in commit 872d8327c
+ */
+static void
+arm64_overflow_stack_init(void)
+{
+ int i;
+ struct syment *sp;
+ struct gnu_request request, *req;
+ struct machine_specific *ms = machdep->machspec;
+ req = &request;
+
+ if (symbol_exists("overflow_stack") &&
+ (sp = per_cpu_symbol_search("overflow_stack")) &&
+ get_symbol_type("overflow_stack", NULL, req)) {
+ if (CRASHDEBUG(1)) {
+ fprintf(fp, "overflow_stack: \n");
+ fprintf(fp, " type: %x, %s\n",
+ (int)req->typecode,
+ (req->typecode == TYPE_CODE_ARRAY) ?
+ "TYPE_CODE_ARRAY" : "other");
+ fprintf(fp, " target_typecode: %x, %s\n",
+ (int)req->target_typecode,
+ req->target_typecode == TYPE_CODE_INT ?
+ "TYPE_CODE_INT" : "other");
+ fprintf(fp, " target_length: %ld\n",
+ req->target_length);
+ fprintf(fp, " length: %ld\n", req->length);
+ }
+
+ if (!(ms->overflow_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong)))))
+ error(FATAL, "cannot malloc overflow_stack addresses\n");
+
+ ms->overflow_stack_size = ARM64_OVERFLOW_STACK_SIZE;
+ machdep->flags |= OVERFLOW_STACKS;
+
+ for (i = 0; i < kt->cpus; i++)
+ ms->overflow_stacks[i] = kt->__per_cpu_offset[i] + sp->value;
+ }
+}
+
/*
* Gather and verify all of the backtrace requirements.
*/
@@ -1960,6 +2009,7 @@ static char *arm64_exception_functions[] = {
"do_mem_abort",
"do_el0_irq_bp_hardening",
"do_sp_pc_abort",
+ "handle_bad_stack",
NULL
};
@@ -1978,7 +2028,10 @@ arm64_in_exception_text(ulong ptr)
if ((ptr >= ms->__exception_text_start) &&
(ptr < ms->__exception_text_end))
return TRUE;
- } else if ((name = closest_symbol(ptr))) { /* Linux 5.5 and later */
+ }
+
+ name = closest_symbol(ptr);
+ if (name != NULL) { /* Linux 5.5 and later */
for (func = &arm64_exception_functions[0]; *func; func++) {
if (STREQ(name, *func))
return TRUE;
@@ -2252,15 +2305,14 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
if ((frame->fp == 0) && (frame->pc == 0))
return FALSE;
- if (!(machdep->flags & IRQ_STACKS))
- return TRUE;
-
- if (!(machdep->flags & IRQ_STACKS))
+ if (!(machdep->flags & (IRQ_STACKS | OVERFLOW_STACKS)))
return TRUE;
if (machdep->flags & UNW_4_14) {
- if ((bt->flags & BT_IRQSTACK) &&
- !arm64_on_irq_stack(bt->tc->processor, frame->fp)) {
+ if (((bt->flags & BT_IRQSTACK) &&
+ !arm64_on_irq_stack(bt->tc->processor, frame->fp)) ||
+ ((bt->flags & BT_OVERFLOW_STACK) &&
+ !arm64_on_overflow_stack(bt->tc->processor, frame->fp))) {
if (arm64_on_process_stack(bt, frame->fp)) {
arm64_set_process_stack(bt);
@@ -2677,6 +2729,9 @@ arm64_back_trace_cmd(struct bt_info *bt)
if (arm64_on_irq_stack(bt->tc->processor, bt->frameptr)) {
arm64_set_irq_stack(bt);
bt->flags |= BT_IRQSTACK;
+ } else if (arm64_on_overflow_stack(bt->tc->processor, bt->frameptr)) {
+ arm64_set_overflow_stack(bt);
+ bt->flags |= BT_OVERFLOW_STACK;
}
stackframe.sp = bt->stkptr;
stackframe.pc = bt->instptr;
@@ -2731,7 +2786,9 @@ arm64_back_trace_cmd(struct bt_info *bt)
break;
if (arm64_in_exception_text(bt->instptr) && INSTACK(stackframe.fp, bt)) {
- if (!(bt->flags & BT_IRQSTACK) ||
+ if (bt->flags & BT_OVERFLOW_STACK) {
+ exception_frame = stackframe.fp - KERN_EFRAME_OFFSET;
+ } else if (!(bt->flags & BT_IRQSTACK) ||
((stackframe.sp + SIZE(pt_regs)) < bt->stacktop)) {
if (arm64_is_kernel_exception_frame(bt, stackframe.fp - KERN_EFRAME_OFFSET))
exception_frame = stackframe.fp - KERN_EFRAME_OFFSET;
@@ -2745,6 +2802,12 @@ arm64_back_trace_cmd(struct bt_info *bt)
break;
}
+ if ((bt->flags & BT_OVERFLOW_STACK) &&
+ !arm64_on_overflow_stack(bt->tc->processor, stackframe.fp)) {
+ bt->flags &= ~BT_OVERFLOW_STACK;
+ if (arm64_switch_stack_from_overflow(bt, &stackframe, ofp) == USER_MODE)
+ break;
+ }
level++;
}
@@ -3131,6 +3194,43 @@ arm64_switch_stack(struct bt_info *bt, struct arm64_stackframe *frame, FILE *ofp
return KERNEL_MODE;
}
+static int
+arm64_switch_stack_from_overflow(struct bt_info *bt, struct arm64_stackframe *frame, FILE *ofp)
+{
+ int i;
+ ulong stacktop, words, addr;
+ ulong *stackbuf;
+ char buf[BUFSIZE];
+ struct machine_specific *ms = machdep->machspec;
+
+ if (bt->flags & BT_FULL) {
+ stacktop = ms->overflow_stacks[bt->tc->processor] + ms->overflow_stack_size;
+ words = (stacktop - bt->bptr) / sizeof(ulong);
+ stackbuf = (ulong *)GETBUF(words * sizeof(ulong));
+ readmem(bt->bptr, KVADDR, stackbuf, words * sizeof(long),
+ "top of overflow stack", FAULT_ON_ERROR);
+
+ addr = bt->bptr;
+ for (i = 0; i < words; i++) {
+ if (!(i & 1))
+ fprintf(ofp, "%s %lx: ", i ? "\n" : "", addr);
+ fprintf(ofp, "%s ", format_stack_entry(bt, buf, stackbuf[i], 0));
+ addr += sizeof(ulong);
+ }
+ fprintf(ofp, "\n");
+ FREEBUF(stackbuf);
+ }
+ fprintf(ofp, "--- <Overflow stack> ---\n");
+
+ if (frame->fp == 0)
+ return USER_MODE;
+
+ if (!(machdep->flags & UNW_4_14))
+ arm64_print_exception_frame(bt, frame->sp, KERNEL_MODE, ofp);
+
+ return KERNEL_MODE;
+}
+
static int
arm64_get_dumpfile_stackframe(struct bt_info *bt, struct arm64_stackframe *frame)
{
@@ -3682,6 +3782,16 @@ arm64_display_machine_stats(void)
machdep->machspec->irq_stacks[i]);
}
}
+ if (machdep->machspec->overflow_stack_size) {
+ fprintf(fp, "OVERFLOW STACK SIZE: %ld\n",
+ machdep->machspec->overflow_stack_size);
+ fprintf(fp, " OVERFLOW STACKS:\n");
+ for (i = 0; i < kt->cpus; i++) {
+ pad = (i < 10) ? 3 : (i < 100) ? 2 : (i < 1000) ? 1 : 0;
+ fprintf(fp, "%s CPU %d: %lx\n", space(pad), i,
+ machdep->machspec->overflow_stacks[i]);
+ }
+ }
}
static int
@@ -3875,24 +3985,41 @@ arm64_on_process_stack(struct bt_info *bt, ulong stkptr)
}
static int
-arm64_on_irq_stack(int cpu, ulong stkptr)
+arm64_in_alternate_stackv(int cpu, ulong stkptr, ulong *stacks, ulong stack_size)
{
- return arm64_in_alternate_stack(cpu, stkptr);
+ if ((cpu >= kt->cpus) || (stacks == NULL) || !stack_size)
+ return FALSE;
+
+ if ((stkptr >= stacks[cpu]) &&
+ (stkptr < (stacks[cpu] + stack_size)))
+ return TRUE;
+
+ return FALSE;
}
static int
arm64_in_alternate_stack(int cpu, ulong stkptr)
+{
+ return (arm64_on_irq_stack(cpu, stkptr) ||
+ arm64_on_overflow_stack(cpu, stkptr));
+}
+
+static int
+arm64_on_irq_stack(int cpu, ulong stkptr)
{
struct machine_specific *ms = machdep->machspec;
- if (!ms->irq_stack_size || (cpu >= kt->cpus))
- return FALSE;
+ return arm64_in_alternate_stackv(cpu, stkptr,
+ ms->irq_stacks, ms->irq_stack_size);
+}
- if ((stkptr >= ms->irq_stacks[cpu]) &&
- (stkptr < (ms->irq_stacks[cpu] + ms->irq_stack_size)))
- return TRUE;
+static int
+arm64_on_overflow_stack(int cpu, ulong stkptr)
+{
+ struct machine_specific *ms = machdep->machspec;
- return FALSE;
+ return arm64_in_alternate_stackv(cpu, stkptr,
+ ms->overflow_stacks, ms->overflow_stack_size);
}
static void
@@ -3905,6 +4032,16 @@ arm64_set_irq_stack(struct bt_info *bt)
alter_stackbuf(bt);
}
+static void
+arm64_set_overflow_stack(struct bt_info *bt)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ bt->stackbase = ms->overflow_stacks[bt->tc->processor];
+ bt->stacktop = bt->stackbase + ms->overflow_stack_size;
+ alter_stackbuf(bt);
+}
+
static void
arm64_set_process_stack(struct bt_info *bt)
{
diff --git a/defs.h b/defs.h
index a2f30853a4b1..7e2a16e34a59 100644
--- a/defs.h
+++ b/defs.h
@@ -3218,6 +3218,7 @@ typedef signed int s32;
#define UNW_4_14 (0x200)
#define FLIPPED_VM (0x400)
#define HAS_PHYSVIRT_OFFSET (0x800)
+#define OVERFLOW_STACKS (0x1000)
/*
* Get kimage_voffset from /dev/crash
@@ -3260,6 +3261,7 @@ typedef signed int s32;
#define ARM64_STACK_SIZE (16384)
#define ARM64_IRQ_STACK_SIZE ARM64_STACK_SIZE
+#define ARM64_OVERFLOW_STACK_SIZE (4096)
#define _SECTION_SIZE_BITS 30
#define _SECTION_SIZE_BITS_5_12 27
@@ -3332,6 +3334,9 @@ struct machine_specific {
char *irq_stackbuf;
ulong __irqentry_text_start;
ulong __irqentry_text_end;
+ ulong overflow_stack_size;
+ ulong *overflow_stacks;
+ char *overflow_stackbuf;
/* for exception vector code */
ulong exp_entry1_start;
ulong exp_entry1_end;
@@ -5770,6 +5775,7 @@ ulong cpu_map_addr(const char *type);
#define BT_CPUMASK (0x1000000000000ULL)
#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
+#define BT_OVERFLOW_STACK (0x8000000000000ULL)
#define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
#define BT_REF_HEXVAL (0x1)
--
2.30.2

View File

@ -1,34 +0,0 @@
From 6ecb8a23ca294de5ef92726c782f4c92fcb39d92 Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie@os.amperecomputing.com>
Date: Fri, 11 Feb 2022 09:46:42 +0000
Subject: [PATCH] arm64: Use CONFIG_ARM64_VA_BITS to initialize VA_BITS_ACTUAL
We can get VA_BITS_ACTUAL from CONFIG_ARM64_VA_BITS by guess.
Without this patch, we may need to use "--machdep vabits_actual=48" to
set the VA_BITS_ACTUAL.
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
---
arm64.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arm64.c b/arm64.c
index 4f2c2b5..de1038a 100644
--- a/arm64.c
+++ b/arm64.c
@@ -4170,6 +4170,11 @@ arm64_calc_VA_BITS(void)
} else if (machdep->machspec->VA_BITS_ACTUAL) {
machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
+ } else if (machdep->machspec->CONFIG_ARM64_VA_BITS) {
+ /* guess */
+ machdep->machspec->VA_BITS_ACTUAL = machdep->machspec->CONFIG_ARM64_VA_BITS;
+ machdep->machspec->VA_BITS = machdep->machspec->CONFIG_ARM64_VA_BITS;
+ machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
} else
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
--
2.31.1

View File

@ -1,69 +0,0 @@
From e3bdc32aab5d8fe09b679cf394da8ba8826e207f Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Thu, 24 Feb 2022 11:52:12 +0800
Subject: [PATCH] arm64: deduce the start address of kernel code, based on
kernel version
After kernel commit e2a073dde921 ("arm64: omit [_text, _stext) from
permanent kernel mapping"), the range [_text, _stext] is reclaimed. But
the current crash code still assumes kernel starting from "_text".
This change only affects the vmalloced area on arm64 and may result a
false in arm64_IS_VMALLOC_ADDR().
Since vmcore has no extra information about this trival change, it can
only be deduced from kernel version, which means ms->kimage_text can not
be correctly initialized until kernel_init() finishes. Here on arm64, it
can be done at the point machdep_init(POST_GDB). This is fine
since there is no access to vmalloced area at this stage.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
---
arm64.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arm64.c b/arm64.c
index de1038a..3ab8489 100644
--- a/arm64.c
+++ b/arm64.c
@@ -92,6 +92,20 @@ static void arm64_calc_VA_BITS(void);
static int arm64_is_uvaddr(ulong, struct task_context *);
static void arm64_calc_KERNELPACMASK(void);
+static void arm64_calc_kernel_start(void)
+{
+ struct machine_specific *ms = machdep->machspec;
+ struct syment *sp;
+
+ if (THIS_KERNEL_VERSION >= LINUX(5,11,0))
+ sp = kernel_symbol_search("_stext");
+ else
+ sp = kernel_symbol_search("_text");
+
+ ms->kimage_text = (sp ? sp->value : 0);
+ sp = kernel_symbol_search("_end");
+ ms->kimage_end = (sp ? sp->value : 0);
+}
/*
* Do all necessary machine-specific setup here. This is called several times
@@ -241,6 +255,7 @@ arm64_init(int when)
if (machdep->flags & NEW_VMEMMAP) {
struct syment *sp;
+ /* It is finally decided in arm64_calc_kernel_start() */
sp = kernel_symbol_search("_text");
ms->kimage_text = (sp ? sp->value : 0);
sp = kernel_symbol_search("_end");
@@ -387,6 +402,8 @@ arm64_init(int when)
break;
case POST_GDB:
+ /* Rely on kernel version to decide the kernel start address */
+ arm64_calc_kernel_start();
arm64_calc_virtual_memory_ranges();
arm64_get_section_size_bits();
--
2.31.1

View File

@ -0,0 +1,30 @@
From ae52398a13fa9a238279114ed671c7c514c154ee Mon Sep 17 00:00:00 2001
From: Sourabh Jain <sourabhjain@linux.ibm.com>
Date: Mon, 9 May 2022 12:49:56 +0530
Subject: [PATCH] ppc64: update the NR_CPUS to 8192
Since the kernel commit 2d8ae638bb86 ("powerpc: Make the NR_CPUS max 8192")
the NR_CPUS on Linux kernel ranges from 1-8192. So let's match NR_CPUS with
the max NR_CPUS count on the Linux kernel.
Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
---
defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 1e8360d65a3b..a6735d07b32f 100644
--- a/defs.h
+++ b/defs.h
@@ -136,7 +136,7 @@
#define NR_CPUS (4096)
#endif
#ifdef PPC64
-#define NR_CPUS (2048)
+#define NR_CPUS (8192)
#endif
#ifdef S390
#define NR_CPUS (512)
--
2.30.2

View File

@ -0,0 +1,62 @@
From 364b2e413c69daf189d2bc0238e3ba9b0dcbd937 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:13 +0800
Subject: [PATCH 01/15] sbitmapq: remove struct and member validation in
sbitmapq_init()
Let's remove the struct and member validation from sbitmapq_init(), which
will help the crash to display the actual error when the sbitmapq fails.
Without the patch:
crash> sbitmapq ffff8e99d0dc8010
sbitmapq: command not supported or applicable on this architecture or kernel
With the patch:
crash> sbitmapq ffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_queue_alloc_hint
FILE: sbitmap.c LINE: 365 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 96a61e6c2c71..7693eef6cebd 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -525,30 +525,6 @@ void sbitmapq_init(void)
MEMBER_OFFSET_INIT(sbq_wait_state_wait_cnt, "sbq_wait_state", "wait_cnt");
MEMBER_OFFSET_INIT(sbq_wait_state_wait, "sbq_wait_state", "wait");
- if (!VALID_SIZE(sbitmap_word) ||
- !VALID_SIZE(sbitmap) ||
- !VALID_SIZE(sbitmap_queue) ||
- !VALID_SIZE(sbq_wait_state) ||
- INVALID_MEMBER(sbitmap_word_depth) ||
- INVALID_MEMBER(sbitmap_word_word) ||
- INVALID_MEMBER(sbitmap_word_cleared) ||
- INVALID_MEMBER(sbitmap_depth) ||
- INVALID_MEMBER(sbitmap_shift) ||
- INVALID_MEMBER(sbitmap_map_nr) ||
- INVALID_MEMBER(sbitmap_map) ||
- INVALID_MEMBER(sbitmap_queue_sb) ||
- INVALID_MEMBER(sbitmap_queue_alloc_hint) ||
- INVALID_MEMBER(sbitmap_queue_wake_batch) ||
- INVALID_MEMBER(sbitmap_queue_wake_index) ||
- INVALID_MEMBER(sbitmap_queue_ws) ||
- INVALID_MEMBER(sbitmap_queue_ws_active) ||
- INVALID_MEMBER(sbitmap_queue_round_robin) ||
- INVALID_MEMBER(sbitmap_queue_min_shallow_depth) ||
- INVALID_MEMBER(sbq_wait_state_wait_cnt) ||
- INVALID_MEMBER(sbq_wait_state_wait)) {
- command_not_supported();
- }
-
sb_flags |= SB_FLAG_INIT;
}
--
2.30.2

View File

@ -1,69 +0,0 @@
From 0d3d80b47d69c5d303b48c0463a026e60633cae2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 6 Jan 2022 12:01:17 +0800
Subject: [PATCH 02/10] Fix for "bt -v" option to display the stack-end address
correctly
The "bt -v" command prints incorrect stack-end address when the
"CONFIG_THREAD_INFO_IN_TASK=y" is enabled in kernel, the "bt -v"
command output shows that the value stored at 0xffff8dee0312c198
is 0xffffffffc076400a, however, the value stored actually at
0xffff8dee0312c198 is NULL(0x0000000000000000), the stack-end
address is incorrect.
Without the patch:
crash> bt -v
PID: 28642 TASK: ffff8dee0312c180 CPU: 0 COMMAND: "insmod"
possible stack overflow: ffff8dee0312c198: ffffffffc076400a != STACK_END_MAGIC
^^^^^^^^^^^^^^^^
crash> rd 0xffff8dee0312c198
ffff8dee0312c198: 0000000000000000 ........
^^^^^^^^^^^^^^^^
With the patch:
crash> bt -v
PID: 28642 TASK: ffff8dee0312c180 CPU: 0 COMMAND: "insmod"
possible stack overflow: ffff991340bc0000: ffffffffc076400a != STACK_END_MAGIC
crash> rd 0xffff991340bc0000
ffff991340bc0000: ffffffffc076400a .@v.....
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
task.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/task.c b/task.c
index bb6a5da8ad33..b5ddc88e0acb 100644
--- a/task.c
+++ b/task.c
@@ -11202,7 +11202,7 @@ check_stack_overflow(void)
{
int i, overflow, cpu_size, cpu, total;
char buf[BUFSIZE];
- ulong magic, task, stackbase;
+ ulong magic, task, stackbase, location;
struct task_context *tc;
if (!tt->stack_end_magic &&
@@ -11286,9 +11286,15 @@ check_stack_end_magic:
if (magic != STACK_END_MAGIC) {
if (!overflow)
print_task_header(fp, tc, 0);
+
+ if (tt->flags & THREAD_INFO_IN_TASK)
+ location = task_to_stackbase(tc->task);
+ else
+ location = tc->thread_info + SIZE(thread_info);
+
fprintf(fp,
" possible stack overflow: %lx: %lx != STACK_END_MAGIC\n",
- tc->thread_info + SIZE(thread_info), magic);
+ location, magic);
overflow++, total++;
}
--
2.20.1

View File

@ -1,101 +0,0 @@
From 98b417fc63467339b919ef6d322c1893d6d55f86 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 24 Dec 2021 18:56:35 +0800
Subject: [PATCH 2/2] Handle blk_mq_ctx member changes for kernels 5.16-rc1 and
later
Kernel commit 9a14d6ce4135 ("block: remove debugfs blk_mq_ctx
dispatched/merged/completed attributes") removed the member
rq_dispatched and rq_completed from struct blk_mq_ctx. Without
the patch, "dev -d|-D" options will fail with the following error:
crash> dev -d
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL ASYNC SYNC
dev: invalid structure member offset: blk_mq_ctx_rq_dispatched
FILE: dev.c LINE: 4229 FUNCTION: get_one_mctx_diskio()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
dev.c | 57 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 18 deletions(-)
diff --git a/dev.c b/dev.c
index effe789f38d8..a493e51ac95c 100644
--- a/dev.c
+++ b/dev.c
@@ -4246,6 +4246,10 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
unsigned long mctx_addr;
struct diskio tmp;
+ if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
+ INVALID_MEMBER(blk_mq_ctx_rq_completed))
+ return;
+
memset(&tmp, 0x00, sizeof(struct diskio));
readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
@@ -4475,24 +4479,41 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
&& (io.read + io.write == 0))
return;
- fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
- mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
- space(MINSPACE),
- mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
- space(MINSPACE),
- mkstring(buf2, 10, LJUST, disk_name),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
- LJUST|LONG_HEX, (char *)queue_addr),
- space(MINSPACE),
- io.read + io.write,
- space(MINSPACE),
- mkstring(buf4, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.read),
- space(MINSPACE),
- mkstring(buf5, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.write),
- space(MINSPACE));
+ if (use_mq_interface(queue_addr) &&
+ (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
+ INVALID_MEMBER(blk_mq_ctx_rq_completed)))
+ fprintf(fp, "%s%s%s %s%s%s%s %s%s%s",
+ mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
+ space(MINSPACE),
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
+ space(MINSPACE),
+ mkstring(buf2, 10, LJUST, disk_name),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
+ LJUST|LONG_HEX, (char *)queue_addr),
+ space(MINSPACE),
+ mkstring(buf4, 17, RJUST, "(not supported)"),
+ space(MINSPACE));
+
+ else
+ fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
+ mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
+ space(MINSPACE),
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
+ space(MINSPACE),
+ mkstring(buf2, 10, LJUST, disk_name),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
+ LJUST|LONG_HEX, (char *)queue_addr),
+ space(MINSPACE),
+ io.read + io.write,
+ space(MINSPACE),
+ mkstring(buf4, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.read),
+ space(MINSPACE),
+ mkstring(buf5, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.write),
+ space(MINSPACE));
if (VALID_MEMBER(request_queue_in_flight)) {
if (!use_mq_interface(queue_addr)) {
--
2.20.1

View File

@ -1,41 +0,0 @@
From c477b04aee34d4f4784c326ed715e91b2c43eb3e Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 9 Dec 2021 01:05:07 +0000
Subject: [PATCH 2/3] defs.h: fix breakage of compatibility of struct
machdep_table for extension modules
Commit <2f967fb5ebd7> ("crash_taget: fetch_registers support") added new
member get_cpu_reg in the middle of struct machdep_table, which breaks
compatibility of struct machdep_table for extension modules. As the result,
crash gcore command results in unexpected behavior, furthermore may cause
segmentation fault.
Fixes: 2f967fb5ebd7 ("crash_taget: fetch_registers support")
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 7e2a16e34a59..7d3ed78fcd23 100644
--- a/defs.h
+++ b/defs.h
@@ -1013,7 +1013,6 @@ struct machdep_table {
ulong (*processor_speed)(void);
int (*uvtop)(struct task_context *, ulong, physaddr_t *, int);
int (*kvtop)(struct task_context *, ulong, physaddr_t *, int);
- int (*get_cpu_reg)(int, int, const char *, int, void *);
ulong (*get_task_pgd)(ulong);
void (*dump_irq)(int);
void (*get_stack_frame)(struct bt_info *, ulong *, ulong *);
@@ -1063,6 +1062,7 @@ struct machdep_table {
void (*get_irq_affinity)(int);
void (*show_interrupts)(int, ulong *);
int (*is_page_ptr)(ulong, physaddr_t *);
+ int (*get_cpu_reg)(int, int, const char *, int, void *);
};
/*
--
2.30.2

View File

@ -0,0 +1,118 @@
From a295cb40cd5d24fb5995cc78d29c5def3843d285 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
---
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

View File

@ -1,35 +0,0 @@
From b9dc76e232e0226a14ae3089e3be5c915f2bb981 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 10 Jan 2022 17:25:06 +0800
Subject: [PATCH 03/10] Fix for HZ calculation on Linux 5.14 and later
Kernel commit 3e9a99eba058 ("block/mq-deadline: Rename dd_init_queue()
and dd_exit_queue()") renamed dd_init_queue to dd_init_sched. Without
the patch, the 'help -m' may print incorrect hz value as follows:
crash> help -m | grep hz
hz: 1000 <---The correct hz value on ppc64le machine is 100.
^^^^
Fixes: b93027ce5c75 ("Add alternate HZ calculation using write_expire")
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
task.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/task.c b/task.c
index b5ddc88e0acb..76e184ae70b1 100644
--- a/task.c
+++ b/task.c
@@ -440,6 +440,8 @@ task_init(void)
}
} else if ((symbol_exists("dd_init_queue") &&
gdb_set_crash_scope(symbol_value("dd_init_queue"), "dd_init_queue")) ||
+ (symbol_exists("dd_init_sched") &&
+ gdb_set_crash_scope(symbol_value("dd_init_sched"), "dd_init_sched")) ||
(symbol_exists("deadline_init_queue") &&
gdb_set_crash_scope(symbol_value("deadline_init_queue"), "deadline_init_queue"))) {
char buf[BUFSIZE];
--
2.20.1

View File

@ -1,41 +0,0 @@
From 6968345893178d2750b8872055498d2a6010a861 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Wed, 8 Dec 2021 12:07:34 +0000
Subject: [PATCH 3/3] defs.h: fix breakage of compatibility of struct
symbol_table_data for extension modules
Commit <2fab8fbc0c4f> ("symbols: Implement install and remove operations
for mod_symname_hash") added new member variable mod_symname_hash in the
middle of struct symbol_table_date, which breaks compatibility of struct
symbol_table_data for extension modules. As the result, crash trace command
results in segmentation fault.
Fixes: 2fab8fbc0c4f ("symbols: Implement install and remove operations for mod_symname_hash")
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 7d3ed78fcd23..b63741c7d78b 100644
--- a/defs.h
+++ b/defs.h
@@ -2753,7 +2753,6 @@ struct symbol_table_data {
double val_hash_searches;
double val_hash_iterations;
struct syment *symname_hash[SYMNAME_HASH];
- struct syment *mod_symname_hash[SYMNAME_HASH];
struct symbol_namespace kernel_namespace;
struct syment *ext_module_symtable;
struct syment *ext_module_symend;
@@ -2780,6 +2779,7 @@ struct symbol_table_data {
ulong kaiser_init_vmlinux;
int kernel_symbol_type;
ulong linux_banner_vmlinux;
+ struct syment *mod_symname_hash[SYMNAME_HASH];
};
/* flags for st */
--
2.30.2

View File

@ -0,0 +1,103 @@
From 530fe6ad7e4d7ff6254596c1219d25ed929e3867 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:15 +0800
Subject: [PATCH 03/15] sbitmapq: fix invalid offset for
"sbitmap_queue_round_robin" on Linux v5.13-rc1
Kernel commit efe1f3a1d583 ("scsi: sbitmap: Maintain allocation
round_robin in sbitmap") moved the round_robin 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_round_robin
FILE: sbitmap.c LINE: 378 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
sbitmap.c | 12 ++++++++++--
symbols.c | 2 ++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 0aeb98c4f654..ecbced24d2e3 100644
--- a/defs.h
+++ b/defs.h
@@ -2169,6 +2169,7 @@ struct offset_table { /* stash of commonly-used offsets */
long sbq_wait_state_wait_cnt;
long sbq_wait_state_wait;
long sbitmap_alloc_hint;
+ long sbitmap_round_robin;
};
struct size_table { /* stash of commonly-used sizes */
@@ -5909,6 +5910,7 @@ struct sbitmap_context {
unsigned map_nr;
ulong map_addr;
ulong alloc_hint;
+ bool round_robin;
};
typedef bool (*sbitmap_for_each_fn)(unsigned int idx, void *p);
diff --git a/sbitmap.c b/sbitmap.c
index 2921d5447c65..7b318b533702 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -352,7 +352,11 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
FREEBUF(sbq_wait_state_buf);
- fprintf(fp, "round_robin = %d\n", sqc->round_robin);
+ if (VALID_MEMBER(sbitmap_queue_round_robin))
+ fprintf(fp, "round_robin = %d\n", sqc->round_robin);
+ else if (VALID_MEMBER(sbitmap_round_robin)) /* 5.13 and later */
+ fprintf(fp, "round_robin = %d\n", sc->round_robin);
+
fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
}
@@ -374,7 +378,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
sqc->wake_index = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_index));
sqc->ws_addr = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws));
sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
- sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
+ if (VALID_MEMBER(sbitmap_queue_round_robin))
+ sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
FREEBUF(sbitmap_queue_buf);
@@ -396,6 +401,8 @@ void sbitmap_context_load(ulong addr, struct sbitmap_context *sc)
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));
+ if (VALID_MEMBER(sbitmap_round_robin))
+ sc->round_robin = BOOL(sbitmap_buf + OFFSET(sbitmap_round_robin));
FREEBUF(sbitmap_buf);
}
@@ -522,6 +529,7 @@ void sbitmapq_init(void)
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_round_robin, "sbitmap", "round_robin");
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 fd0eb06899f0..5d12a021c769 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10710,6 +10710,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(sbitmap_map));
fprintf(fp, " sbitmap_alloc_hint: %ld\n",
OFFSET(sbitmap_alloc_hint));
+ fprintf(fp, " sbitmap_round_robin: %ld\n",
+ OFFSET(sbitmap_round_robin));
fprintf(fp, " sbitmap_queue_sb: %ld\n",
OFFSET(sbitmap_queue_sb));
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
--
2.30.2

View File

@ -1,39 +0,0 @@
From 14f8c460473c8613553b5defd174ca2af812ddcb Mon Sep 17 00:00:00 2001
From: Alexander Egorenkov <egorenar@linux.ibm.com>
Date: Mon, 6 Dec 2021 16:04:19 +0100
Subject: [PATCH 04/10] memory: Handle struct slab changes on Linux 5.17-rc1
and later
Since kernel commit d122019bf061 ("mm: Split slab into its own type"),
the struct slab is used for both SLAB and SLUB. Therefore, don't depend
on the non-presence of the struct slab to decide whether SLAB implementation
should be chosen and use the member variable "cpu_slab" of the struct
kmem_cache instead, it should be present only in SLUB.
Without the patch, crash fails to start with the error message:
crash: invalid structure member offset: kmem_cache_s_num
FILE: memory.c LINE: 9619 FUNCTION: kmem_cache_init()
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
---
memory.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/memory.c b/memory.c
index 86c02c132890..5af45fd7d834 100644
--- a/memory.c
+++ b/memory.c
@@ -576,7 +576,8 @@ vm_init(void)
STRUCT_SIZE_INIT(cpucache_s, "cpucache_s");
} else if (!VALID_STRUCT(kmem_slab_s) &&
- !VALID_STRUCT(slab_s) &&
+ !VALID_STRUCT(slab_s) &&
+ !MEMBER_EXISTS("kmem_cache", "cpu_slab") &&
(VALID_STRUCT(slab) || (vt->flags & SLAB_OVERLOAD_PAGE))) {
vt->flags |= PERCPU_KMALLOC_V2;
--
2.20.1

View File

@ -0,0 +1,101 @@
From 3750803f6ae5f5ad071f86ca916dbbb17b7a83a5 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:16 +0800
Subject: [PATCH 04/15] sbitmapq: fix invalid offset for "sbitmap_word_depth"
on Linux v5.18-rc1
Kernel commit 3301bc53358a ("lib/sbitmap: kill 'depth' from sbitmap_word")
removed the depth member from struct sbitmap_word. Without the patch, the
sbitmapq will fail:
crash> sbitmapq 0xffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_word_depth
FILE: sbitmap.c LINE: 84 FUNCTION: __sbitmap_weight()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 7b318b533702..e8ebd62fe01c 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -78,10 +78,16 @@ static unsigned long bitmap_weight(unsigned long bitmap, unsigned int bits)
return w;
}
+static inline unsigned int __map_depth(const struct sbitmap_context *sc, int index)
+{
+ if (index == sc->map_nr - 1)
+ return sc->depth - (index << sc->shift);
+ return 1U << sc->shift;
+}
+
static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -99,7 +105,7 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
error(FATAL, "cannot read sbitmap_word\n");
}
- depth = ULONG(sbitmap_word_buf + w_depth_off);
+ depth = __map_depth(sc, i);
if (set) {
word = ULONG(sbitmap_word_buf + w_word_off);
@@ -142,7 +148,6 @@ static void sbitmap_emit_byte(unsigned int offset, uint8_t byte)
static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -165,7 +170,7 @@ 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);
- word_bits = ULONG(sbitmap_word_buf + w_depth_off);
+ word_bits = __map_depth(sc, i);
word &= ~cleared;
@@ -213,7 +218,6 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
unsigned int start, sbitmap_for_each_fn fn, void *data)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -232,7 +236,7 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
while (scanned < sc->depth) {
unsigned long w_addr = sc->map_addr + (sbitmap_word_size * index);
- unsigned long w_depth, w_word, w_cleared;
+ unsigned long w_word, w_cleared;
unsigned long word, depth;
if (!readmem(w_addr, KVADDR, sbitmap_word_buf, sbitmap_word_size, "sbitmap_word", RETURN_ON_ERROR)) {
@@ -240,11 +244,10 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
error(FATAL, "cannot read sbitmap_word\n");
}
- w_depth = ULONG(sbitmap_word_buf + w_depth_off);
w_word = ULONG(sbitmap_word_buf + w_word_off);
w_cleared = ULONG(sbitmap_word_buf + w_cleared_off);
- depth = min(w_depth - nr, sc->depth - scanned);
+ depth = min(__map_depth(sc, index) - nr, sc->depth - scanned);
scanned += depth;
word = w_word & ~w_cleared;
--
2.30.2

View File

@ -0,0 +1,26 @@
From 9705669a49c341402efd8528e8fe809379dd798d Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 23 May 2022 14:48:50 +0900
Subject: [PATCH 05/15] Makefile: add missing crash_target.o to be cleaned
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index e520b1217a9d..162c2baa5164 100644
--- a/Makefile
+++ b/Makefile
@@ -184,7 +184,7 @@ GDB_7.6_FILES=
GDB_7.6_OFILES=${GDB}/gdb/symtab.o
GDB_10.2_FILES=
-GDB_10.2_OFILES=${GDB}/gdb/symtab.o
+GDB_10.2_OFILES=${GDB}/gdb/symtab.o crash_target.o
#
# GDB_FLAGS is passed up from the gdb Makefile.
--
2.30.2

View File

@ -1,75 +0,0 @@
From d16dc6fff0260ec26002046fae4aeb546d6b9a0e Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 17 Jan 2022 15:14:00 +0800
Subject: [PATCH 05/10] Move the initialization of "boot_date" to task_init()
The "boot_date" is initialized conditionally in the cmd_log(), which may
display incorrect "boot_date" value with the following command before
running the "log -T" command:
crash> help -k | grep date
date: Wed Dec 22 13:39:29 IST 2021
boot_date: Thu Jan 1 05:30:00 IST 1970
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The calculation of "boot_date" depends on the HZ value, and the HZ will
be calculated in task_init() at the latest, so let's move it here.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 18 +++---------------
task.c | 10 ++++++++++
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/kernel.c b/kernel.c
index 36c57ed501ad..094fe9b2efad 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5025,21 +5025,9 @@ cmd_log(void)
if (argerrs)
cmd_usage(pc->curcmd, SYNOPSIS);
- if (msg_flags & SHOW_LOG_CTIME) {
- if (pc->flags & MINIMAL_MODE) {
- error(WARNING, "the option '-T' is not available in minimal mode\n");
- return;
- }
-
- if (kt->boot_date.tv_sec == 0) {
- ulonglong uptime_jiffies;
- ulong uptime_sec;
-
- get_uptime(NULL, &uptime_jiffies);
- uptime_sec = (uptime_jiffies)/(ulonglong)machdep->hz;
- kt->boot_date.tv_sec = kt->date.tv_sec - uptime_sec;
- kt->boot_date.tv_nsec = 0;
- }
+ if (msg_flags & SHOW_LOG_CTIME && pc->flags & MINIMAL_MODE) {
+ error(WARNING, "the option '-T' is not available in minimal mode\n");
+ return;
}
if (msg_flags & SHOW_LOG_AUDIT) {
diff --git a/task.c b/task.c
index 76e184ae70b1..263a8344dd94 100644
--- a/task.c
+++ b/task.c
@@ -692,6 +692,16 @@ task_init(void)
stack_overflow_check_init();
+ if (machdep->hz) {
+ ulonglong uptime_jiffies;
+ ulong uptime_sec;
+
+ get_uptime(NULL, &uptime_jiffies);
+ uptime_sec = (uptime_jiffies)/(ulonglong)machdep->hz;
+ kt->boot_date.tv_sec = kt->date.tv_sec - uptime_sec;
+ kt->boot_date.tv_nsec = 0;
+ }
+
tt->flags |= TASK_INIT_DONE;
}
--
2.20.1

View File

@ -1,78 +0,0 @@
From 2ebd8c5ecf1f077975b82325a38dd777b594d0a9 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 19 Jan 2022 16:24:49 +0900
Subject: [PATCH 06/10] Remove ptype command from "ps -t" option to reduce
memory and time
With some vmlinux e.g. RHEL9 ones, the first execution of the gdb ptype
command heavily consumes memory and time. The "ps -t" option uses it in
start_time_timespec(), and it can be replaced with the crash macros.
This can reduce about 1.4 GB memory and 6 seconds time comsumption in
the following test:
$ echo "ps -t" | time crash vmlinux vmcore
Without the patch:
11.60user 0.43system 0:11.94elapsed 100%CPU (0avgtext+0avgdata 1837964maxresident)k
0inputs+400outputs (0major+413636minor)pagefaults 0swaps
With the patch:
5.40user 0.16system 0:05.46elapsed 101%CPU (0avgtext+0avgdata 417896maxresident)k
0inputs+384outputs (0major+41528minor)pagefaults 0swaps
Although the ptype command and similar ones cannot be fully removed,
but removing some of them will make the use of crash safer, especially
for an automatic crash reporter.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
task.c | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)
diff --git a/task.c b/task.c
index 263a8344dd94..a79ed0d96fb5 100644
--- a/task.c
+++ b/task.c
@@ -4662,8 +4662,6 @@ show_task_times(struct task_context *tcp, ulong flags)
static int
start_time_timespec(void)
{
- char buf[BUFSIZE];
-
switch(tt->flags & (TIMESPEC | NO_TIMESPEC | START_TIME_NSECS))
{
case TIMESPEC:
@@ -4677,24 +4675,11 @@ start_time_timespec(void)
tt->flags |= NO_TIMESPEC;
- open_tmpfile();
- sprintf(buf, "ptype struct task_struct");
- if (!gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR)) {
- close_tmpfile();
- return FALSE;
- }
-
- rewind(pc->tmpfile);
- while (fgets(buf, BUFSIZE, pc->tmpfile)) {
- if (strstr(buf, "start_time;")) {
- if (strstr(buf, "struct timespec")) {
- tt->flags &= ~NO_TIMESPEC;
- tt->flags |= TIMESPEC;
- }
- }
- }
-
- close_tmpfile();
+ if (VALID_MEMBER(task_struct_start_time) &&
+ STREQ(MEMBER_TYPE_NAME("task_struct", "start_time"), "timespec")) {
+ tt->flags &= ~NO_TIMESPEC;
+ tt->flags |= TIMESPEC;
+ }
if ((tt->flags & NO_TIMESPEC) && (SIZE(task_struct_start_time) == 8)) {
tt->flags &= ~NO_TIMESPEC;
--
2.20.1

View File

@ -0,0 +1,204 @@
From 6833262bf87177d8affe4f91b2e7d2c76ecdf636 Mon Sep 17 00:00:00 2001
From: Qi Zheng <zhengqi.arch@bytedance.com>
Date: Tue, 24 May 2022 20:25:53 +0800
Subject: [PATCH 06/15] bt: x86_64: filter out idle task stack
When we use crash to troubleshoot softlockup and other problems,
we often use the 'bt -a' command to print the stacks of running
processes on all CPUs. But now some servers have hundreds of CPUs
(such as AMD machines), which causes the 'bt -a' command to output
a lot of process stacks. And many of these stacks are the stacks
of the idle process, which are not needed by us.
Therefore, in order to reduce this part of the interference information,
this patch adds the -n option to the bt command. When we specify
'-n idle' (meaning no idle), the stack of the idle process will be
filtered out, thus speeding up our troubleshooting.
And the option works only for crash dumps captured by kdump.
The command output is as follows:
crash> bt -a -n idle
[...]
PID: 0 TASK: ffff889ff8c34380 CPU: 8 COMMAND: "swapper/8"
PID: 0 TASK: ffff889ff8c32d00 CPU: 9 COMMAND: "swapper/9"
PID: 0 TASK: ffff889ff8c31680 CPU: 10 COMMAND: "swapper/10"
PID: 0 TASK: ffff889ff8c35a00 CPU: 11 COMMAND: "swapper/11"
PID: 0 TASK: ffff889ff8c3c380 CPU: 12 COMMAND: "swapper/12"
PID: 150773 TASK: ffff889fe85a1680 CPU: 13 COMMAND: "bash"
#0 [ffffc9000d35bcd0] machine_kexec at ffffffff8105a407
#1 [ffffc9000d35bd28] __crash_kexec at ffffffff8113033d
#2 [ffffc9000d35bdf0] panic at ffffffff81081930
#3 [ffffc9000d35be70] sysrq_handle_crash at ffffffff814e38d1
#4 [ffffc9000d35be78] __handle_sysrq.cold.12 at ffffffff814e4175
#5 [ffffc9000d35bea8] write_sysrq_trigger at ffffffff814e404b
#6 [ffffc9000d35beb8] proc_reg_write at ffffffff81330d86
#7 [ffffc9000d35bed0] vfs_write at ffffffff812a72d5
#8 [ffffc9000d35bf00] ksys_write at ffffffff812a7579
#9 [ffffc9000d35bf38] do_syscall_64 at ffffffff81004259
RIP: 00007fa7abcdc274 RSP: 00007fffa731f678 RFLAGS: 00000246
RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fa7abcdc274
RDX: 0000000000000002 RSI: 0000563ca51ee6d0 RDI: 0000000000000001
RBP: 0000563ca51ee6d0 R8: 000000000000000a R9: 00007fa7abd6be80
R10: 000000000000000a R11: 0000000000000246 R12: 00007fa7abdad760
R13: 0000000000000002 R14: 00007fa7abda8760 R15: 0000000000000002
ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b
[...]
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Acked-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
help.c | 33 ++++++++++++++++++++++++++++++++-
kernel.c | 13 ++++++++++++-
x86_64.c | 8 ++++++++
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index ecbced24d2e3..c8444b4e54eb 100644
--- a/defs.h
+++ b/defs.h
@@ -5832,6 +5832,7 @@ ulong cpu_map_addr(const char *type);
#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
#define BT_OVERFLOW_STACK (0x8000000000000ULL)
+#define BT_SKIP_IDLE (0x10000000000000ULL)
#define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
#define BT_REF_HEXVAL (0x1)
diff --git a/help.c b/help.c
index 51a0fe3d687c..e1bbc5abe029 100644
--- a/help.c
+++ b/help.c
@@ -1909,12 +1909,14 @@ char *help_bt[] = {
"bt",
"backtrace",
"[-a|-c cpu(s)|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O|-v|-p] [-R ref] [-s [-x|d]]"
-"\n [-I ip] [-S sp] [pid | task]",
+"\n [-I ip] [-S sp] [-n idle] [pid | task]",
" Display a kernel stack backtrace. If no arguments are given, the stack",
" trace of the current context will be displayed.\n",
" -a displays the stack traces of the active task on each CPU.",
" (only applicable to crash dumps)",
" -A same as -a, but also displays vector registers (S390X only).",
+" -n idle filter the stack of idle tasks (x86_64).",
+" (only applicable to crash dumps)",
" -p display the stack trace of the panic task only.",
" (only applicable to crash dumps)",
" -c cpu display the stack trace of the active task on one or more CPUs,",
@@ -2004,6 +2006,35 @@ char *help_bt[] = {
" DS: 002b ESI: bfffc8a0 ES: 002b EDI: 00000000 ",
" SS: 002b ESP: bfffc82c EBP: bfffd224 ",
" CS: 0023 EIP: 400d032e ERR: 0000008e EFLAGS: 00000246 ",
+" ",
+" Display the stack trace of the active task(s) when the kernel panicked,",
+" and filter out the stack of the idle tasks:",
+" ",
+" %s> bt -a -n idle",
+" ...",
+" PID: 0 TASK: ffff889ff8c35a00 CPU: 11 COMMAND: \"swapper/11\"",
+" ",
+" PID: 0 TASK: ffff889ff8c3c380 CPU: 12 COMMAND: \"swapper/12\"",
+" ",
+" PID: 150773 TASK: ffff889fe85a1680 CPU: 13 COMMAND: \"bash\"",
+" #0 [ffffc9000d35bcd0] machine_kexec at ffffffff8105a407",
+" #1 [ffffc9000d35bd28] __crash_kexec at ffffffff8113033d",
+" #2 [ffffc9000d35bdf0] panic at ffffffff81081930",
+" #3 [ffffc9000d35be70] sysrq_handle_crash at ffffffff814e38d1",
+" #4 [ffffc9000d35be78] __handle_sysrq.cold.12 at ffffffff814e4175",
+" #5 [ffffc9000d35bea8] write_sysrq_trigger at ffffffff814e404b",
+" #6 [ffffc9000d35beb8] proc_reg_write at ffffffff81330d86",
+" #7 [ffffc9000d35bed0] vfs_write at ffffffff812a72d5",
+" #8 [ffffc9000d35bf00] ksys_write at ffffffff812a7579",
+" #9 [ffffc9000d35bf38] do_syscall_64 at ffffffff81004259",
+" RIP: 00007fa7abcdc274 RSP: 00007fffa731f678 RFLAGS: 00000246",
+" RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fa7abcdc274",
+" RDX: 0000000000000002 RSI: 0000563ca51ee6d0 RDI: 0000000000000001",
+" RBP: 0000563ca51ee6d0 R8: 000000000000000a R9: 00007fa7abd6be80",
+" R10: 000000000000000a R11: 0000000000000246 R12: 00007fa7abdad760",
+" R13: 0000000000000002 R14: 00007fa7abda8760 R15: 0000000000000002",
+" ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b",
+" ...",
"\n Display the stack trace of the active task on CPU 0 and 1:\n",
" %s> bt -c 0,1",
" PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: \"swapper\"",
diff --git a/kernel.c b/kernel.c
index d0921cf567d9..411e9da1e54f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -2503,7 +2503,7 @@ cmd_bt(void)
if (kt->flags & USE_OPT_BT)
bt->flags |= BT_OPT_BACK_TRACE;
- while ((c = getopt(argcnt, args, "D:fFI:S:c:aAloreEgstTdxR:Ovp")) != EOF) {
+ while ((c = getopt(argcnt, args, "D:fFI:S:c:n:aAloreEgstTdxR:Ovp")) != EOF) {
switch (c)
{
case 'f':
@@ -2672,6 +2672,13 @@ cmd_bt(void)
active++;
break;
+ case 'n':
+ if (machine_type("X86_64") && STREQ(optarg, "idle"))
+ bt->flags |= BT_SKIP_IDLE;
+ else
+ option_not_supported(c);
+ break;
+
case 'r':
bt->flags |= BT_RAW;
break;
@@ -3092,6 +3099,10 @@ back_trace(struct bt_info *bt)
} else
machdep->get_stack_frame(bt, &eip, &esp);
+ /* skip idle task stack */
+ if (bt->flags & BT_SKIP_IDLE)
+ return;
+
if (bt->flags & BT_KSTACKP) {
bt->stkptr = esp;
return;
diff --git a/x86_64.c b/x86_64.c
index ecaefd2f46a8..cfafbcc4dabe 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4918,6 +4918,9 @@ x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
if (bt->flags & BT_DUMPFILE_SEARCH)
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
+ if (bt->flags & BT_SKIP_IDLE)
+ bt->flags &= ~BT_SKIP_IDLE;
+
if (pcp)
*pcp = x86_64_get_pc(bt);
if (spp)
@@ -4960,6 +4963,9 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp)
estack = -1;
panic = FALSE;
+ if (bt_in->flags & BT_SKIP_IDLE)
+ bt_in->flags &= ~BT_SKIP_IDLE;
+
panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
if (panic_task && bt->machdep) {
@@ -5098,6 +5104,8 @@ next_sysrq:
if (!panic_task && STREQ(sym, "crash_nmi_callback")) {
*rip = *up;
*rsp = bt->stackbase + ((char *)(up) - bt->stackbuf);
+ if ((bt->flags & BT_SKIP_IDLE) && is_idle_thread(bt->task))
+ bt_in->flags |= BT_SKIP_IDLE;
return;
}
--
2.30.2

View File

@ -1,73 +0,0 @@
From ce92e458506aec5bc5516a771e26b0f907ce0db4 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 26 Jan 2022 20:32:35 +0800
Subject: [PATCH 07/10] GDB: fix completion related libstdc++ assert
Currently crash built with some specific flags (-D_GLIBCXX_ASSERTIONS
and etc.) may abort and print the following error when running the gdb
list command or tab-completion of symbols. For example:
crash> l panic
/usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
crash> p "TAB completion"
crash> p /usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
When the name string is null (the length of name is zero), there are
multiple places where array access is out of bounds in the gdb/ada-lang.c
(see ada_fold_name() and ada_lookup_name_info()).
The patch backports these gdb patches:
6a780b676637 ("Fix completion related libstdc++ assert when using -D_GLIBCXX_DEBUG")
2ccee230f830 ("Fix off-by-one error in ada_fold_name")
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
gdb-10.2.patch | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index 1332b6638028..f5e4c06e6f97 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -1591,3 +1591,34 @@
max += 2;
limit = cols / max;
if (limit != 1 && (limit * max == cols))
+--- gdb-10.2/gdb/ada-lang.c.orig
++++ gdb-10.2/gdb/ada-lang.c
+@@ -997,7 +997,7 @@ ada_fold_name (gdb::string_view name)
+ int len = name.size ();
+ GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
+
+- if (name[0] == '\'')
++ if (!name.empty () && name[0] == '\'')
+ {
+ strncpy (fold_buffer, name.data () + 1, len - 2);
+ fold_buffer[len - 2] = '\000';
+@@ -1006,8 +1006,9 @@ ada_fold_name (gdb::string_view name)
+ {
+ int i;
+
+- for (i = 0; i <= len; i += 1)
++ for (i = 0; i < len; i += 1)
+ fold_buffer[i] = tolower (name[i]);
++ fold_buffer[i] = '\0';
+ }
+
+ return fold_buffer;
+@@ -13596,7 +13597,7 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
+ {
+ gdb::string_view user_name = lookup_name.name ();
+
+- if (user_name[0] == '<')
++ if (!user_name.empty () && user_name[0] == '<')
+ {
+ if (user_name.back () == '>')
+ m_encoded_name
--
2.20.1

View File

@ -0,0 +1,95 @@
From 0f162febebc4d11a165dd40cee00f3b0ba691a52 Mon Sep 17 00:00:00 2001
From: Qi Zheng <zhengqi.arch@bytedance.com>
Date: Tue, 24 May 2022 20:25:54 +0800
Subject: [PATCH 07/15] bt: arm64: add support for 'bt -n idle'
The '-n idle' option of bt command can help us filter the
stack of the idle process when debugging the dumpfiles
captured by kdump.
This patch supports this feature on ARM64.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
---
arm64.c | 19 ++++++++++++++++---
help.c | 2 +-
kernel.c | 3 ++-
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 65f6cdf69fa6..0f615cf52bef 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3681,6 +3681,12 @@ arm64_get_dumpfile_stackframe(struct bt_info *bt, struct arm64_stackframe *frame
{
struct machine_specific *ms = machdep->machspec;
struct arm64_pt_regs *ptregs;
+ bool skip = false;
+
+ if (bt->flags & BT_SKIP_IDLE) {
+ skip = true;
+ bt->flags &= ~BT_SKIP_IDLE;
+ }
if (!ms->panic_task_regs ||
(!ms->panic_task_regs[bt->tc->processor].sp &&
@@ -3713,8 +3719,11 @@ try_kernel:
}
if (arm64_in_kdump_text(bt, frame) ||
- arm64_in_kdump_text_on_irq_stack(bt))
+ arm64_in_kdump_text_on_irq_stack(bt)) {
bt->flags |= BT_KDUMP_ADJUST;
+ if (skip && is_idle_thread(bt->task))
+ bt->flags |= BT_SKIP_IDLE;
+ }
return TRUE;
}
@@ -3738,10 +3747,14 @@ arm64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
int ret;
struct arm64_stackframe stackframe = { 0 };
- if (DUMPFILE() && is_task_active(bt->task))
+ if (DUMPFILE() && is_task_active(bt->task)) {
ret = arm64_get_dumpfile_stackframe(bt, &stackframe);
- else
+ } else {
+ if (bt->flags & BT_SKIP_IDLE)
+ bt->flags &= ~BT_SKIP_IDLE;
+
ret = arm64_get_stackframe(bt, &stackframe);
+ }
if (!ret)
error(WARNING,
diff --git a/help.c b/help.c
index e1bbc5abe029..99214c1590fa 100644
--- a/help.c
+++ b/help.c
@@ -1915,7 +1915,7 @@ char *help_bt[] = {
" -a displays the stack traces of the active task on each CPU.",
" (only applicable to crash dumps)",
" -A same as -a, but also displays vector registers (S390X only).",
-" -n idle filter the stack of idle tasks (x86_64).",
+" -n idle filter the stack of idle tasks (x86_64, arm64).",
" (only applicable to crash dumps)",
" -p display the stack trace of the panic task only.",
" (only applicable to crash dumps)",
diff --git a/kernel.c b/kernel.c
index 411e9da1e54f..a521ef30cdb0 100644
--- a/kernel.c
+++ b/kernel.c
@@ -2673,7 +2673,8 @@ cmd_bt(void)
break;
case 'n':
- if (machine_type("X86_64") && STREQ(optarg, "idle"))
+ if ((machine_type("X86_64") || machine_type("ARM64")) &&
+ STREQ(optarg, "idle"))
bt->flags |= BT_SKIP_IDLE;
else
option_not_supported(c);
--
2.30.2

View File

@ -1,149 +0,0 @@
From e389667cf62ef5db82f9796cdbc0134ec38612dc Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Fri, 21 Jan 2022 13:43:09 +0800
Subject: [PATCH 08/10] Improve the ps performance for vmcores with large
number of threads
Previously, the ps command will iterate over all threads which
have the same tgid, to accumulate their rss value, in order to
get a thread/process's final rss value as part of the final output.
For non-live systems, the rss accumulation values are identical for
threads which have the same tgid, so there is no need to do the
iteration and accumulation repeatly, thus a lot of readmem calls are
skipped. Otherwise it will be the performance bottleneck if the
vmcores have a large number of threads.
In this patch, the rss accumulation value will be stored in a cache,
next time a thread with the same tgid will take it directly without
the iteration.
For example, we can monitor the performance issue when a vmcore has
~65k processes, most of which are threads for several specific
processes. Without the patch, it will take ~7h for ps command
to finish. With the patch, ps command will finish in 1min.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 1 +
memory.c | 70 +++++++++++++++++++++++++++++++-------------------------
task.c | 1 +
3 files changed, 41 insertions(+), 31 deletions(-)
diff --git a/defs.h b/defs.h
index b63741c7d78b..55600d56ef1c 100644
--- a/defs.h
+++ b/defs.h
@@ -829,6 +829,7 @@ struct task_context { /* context stored for each task */
struct tgid_context { /* tgid and task stored for each task */
ulong tgid;
ulong task;
+ long rss_cache;
};
struct task_table { /* kernel/local task table data */
diff --git a/memory.c b/memory.c
index 5af45fd7d834..e80c59ea4534 100644
--- a/memory.c
+++ b/memory.c
@@ -4665,7 +4665,7 @@ void
get_task_mem_usage(ulong task, struct task_mem_usage *tm)
{
struct task_context *tc;
- long rss = 0;
+ long rss = 0, rss_cache = 0;
BZERO(tm, sizeof(struct task_mem_usage));
@@ -4730,38 +4730,46 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
(last->tgid == (last + 1)->tgid))
last++;
- while (first <= last)
- {
- /* count 0 -> filepages */
- if (!readmem(first->task +
- OFFSET(task_struct_rss_stat) +
- OFFSET(task_rss_stat_count), KVADDR,
- &sync_rss,
- sizeof(int),
- "task_struct rss_stat MM_FILEPAGES",
- RETURN_ON_ERROR))
- continue;
-
- rss += sync_rss;
-
- /* count 1 -> anonpages */
- if (!readmem(first->task +
- OFFSET(task_struct_rss_stat) +
- OFFSET(task_rss_stat_count) +
- sizeof(int),
- KVADDR, &sync_rss,
- sizeof(int),
- "task_struct rss_stat MM_ANONPAGES",
- RETURN_ON_ERROR))
- continue;
-
- rss += sync_rss;
-
- if (first == last)
- break;
- first++;
+ /*
+ * Using rss cache for dumpfile is more beneficial than live debug
+ * because its value never changes in dumpfile.
+ */
+ if (ACTIVE() || last->rss_cache == UNINITIALIZED) {
+ while (first <= last)
+ {
+ /* count 0 -> filepages */
+ if (!readmem(first->task +
+ OFFSET(task_struct_rss_stat) +
+ OFFSET(task_rss_stat_count), KVADDR,
+ &sync_rss,
+ sizeof(int),
+ "task_struct rss_stat MM_FILEPAGES",
+ RETURN_ON_ERROR))
+ continue;
+
+ rss_cache += sync_rss;
+
+ /* count 1 -> anonpages */
+ if (!readmem(first->task +
+ OFFSET(task_struct_rss_stat) +
+ OFFSET(task_rss_stat_count) +
+ sizeof(int),
+ KVADDR, &sync_rss,
+ sizeof(int),
+ "task_struct rss_stat MM_ANONPAGES",
+ RETURN_ON_ERROR))
+ continue;
+
+ rss_cache += sync_rss;
+
+ if (first == last)
+ break;
+ first++;
+ }
+ last->rss_cache = rss_cache;
}
+ rss += last->rss_cache;
tt->last_tgid = last;
}
}
diff --git a/task.c b/task.c
index a79ed0d96fb5..864c838637ee 100644
--- a/task.c
+++ b/task.c
@@ -2947,6 +2947,7 @@ add_context(ulong task, char *tp)
tg = tt->tgid_array + tt->running_tasks;
tg->tgid = *tgid_addr;
tg->task = task;
+ tg->rss_cache = UNINITIALIZED;
if (do_verify && !verify_task(tc, do_verify)) {
error(INFO, "invalid task address: %lx\n", tc->task);
--
2.20.1

View File

@ -0,0 +1,66 @@
From dda5b2d02b8d8de1264f84b6267582aa7a1e5a57 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 31 May 2022 17:12:16 +0900
Subject: [PATCH 08/15] gdb: print details of unnamed struct and union
Currently gdb's "ptype" command does not print the details of unnamed
structure and union deeper than second level in a structure, it prints
only "{...}" instead. And crash's "struct" and similar commands also
inherit this behavior, so we cannot get the full information of them.
To print the details of them, change the show variable when it is an
unnamed one like crash-7.x.
Without the patch:
crash> struct -o page
struct page {
[0] unsigned long flags;
union {
struct {...};
struct {...};
...
With the patch:
crash> struct -o page
struct page {
[0] unsigned long flags;
union {
struct {
[8] struct list_head lru;
[24] struct address_space *mapping;
[32] unsigned long index;
[40] unsigned long private;
};
struct {
[8] dma_addr_t dma_addr;
};
...
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
gdb-10.2.patch | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index b67db4e1ded9..577f5e45fc5a 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -1638,3 +1638,15 @@ exit 0
$(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
-o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
+--- gdb-10.2/gdb/c-typeprint.c.orig
++++ gdb-10.2/gdb/c-typeprint.c
+@@ -1202,6 +1202,9 @@ c_type_print_base_struct_union (struct t
+ = podata->end_bitpos
+ - TYPE_LENGTH (type->field (i).type ()) * TARGET_CHAR_BIT;
+ }
++ else if (strlen(TYPE_FIELD_NAME (type, i)) == 0)
++ /* crash: Print details for unnamed struct and union. */
++ newshow = show;
+
+ c_print_type_1 (type->field (i).type (),
+ TYPE_FIELD_NAME (type, i),
--
2.30.2

View File

@ -0,0 +1,392 @@
From 7095c8fd029e3a33117e3b67de73f504686ebfe2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 2 Jun 2022 20:12:55 +0800
Subject: [PATCH 09/15] Enhance "dev -d|-D" options to support blk-mq sbitmap
Since Linux 5.16-rc1, which kernel commit 9a14d6ce4135 ("block: remove
debugfs blk_mq_ctx dispatched/merged/completed attributes") removed the
members from struct blk_mq_ctx, crash has not displayed disk I/O statistics
for multiqueue (blk-mq) devices.
Let's parse the sbitmap in blk-mq layer to support it.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
defs.h | 11 +++
dev.c | 244 +++++++++++++++++++++++++++++++++++++++++++++---------
symbols.c | 22 +++++
3 files changed, 238 insertions(+), 39 deletions(-)
diff --git a/defs.h b/defs.h
index c8444b4e54eb..2681586a33dc 100644
--- a/defs.h
+++ b/defs.h
@@ -2170,6 +2170,16 @@ struct offset_table { /* stash of commonly-used offsets */
long sbq_wait_state_wait;
long sbitmap_alloc_hint;
long sbitmap_round_robin;
+ long request_cmd_flags;
+ long request_q;
+ long request_state;
+ long request_queue_queue_hw_ctx;
+ long request_queue_nr_hw_queues;
+ long blk_mq_hw_ctx_tags;
+ long blk_mq_tags_bitmap_tags;
+ long blk_mq_tags_breserved_tags;
+ long blk_mq_tags_nr_reserved_tags;
+ long blk_mq_tags_rqs;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2339,6 +2349,7 @@ struct size_table { /* stash of commonly-used sizes */
long sbitmap;
long sbitmap_queue;
long sbq_wait_state;
+ long blk_mq_tags;
};
struct array_table {
diff --git a/dev.c b/dev.c
index a493e51ac95c..4be4c96df8b0 100644
--- a/dev.c
+++ b/dev.c
@@ -4238,19 +4238,176 @@ get_one_mctx_diskio(unsigned long mctx, struct diskio *io)
io->write = (dispatch[1] - comp[1]);
}
+typedef bool (busy_tag_iter_fn)(ulong rq, void *data);
+
+struct mq_inflight {
+ ulong q;
+ struct diskio *dio;
+};
+
+struct bt_iter_data {
+ ulong tags;
+ uint reserved;
+ uint nr_reserved_tags;
+ busy_tag_iter_fn *fn;
+ void *data;
+};
+
+/*
+ * See the include/linux/blk_types.h and include/linux/blk-mq.h
+ */
+#define MQ_RQ_IN_FLIGHT 1
+#define REQ_OP_BITS 8
+#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
+
+static uint op_is_write(uint op)
+{
+ return (op & REQ_OP_MASK) & 1;
+}
+
+static bool mq_check_inflight(ulong rq, void *data)
+{
+ uint cmd_flags = 0, state = 0;
+ ulong addr = 0, queue = 0;
+ struct mq_inflight *mi = data;
+
+ if (!IS_KVADDR(rq))
+ return TRUE;
+
+ addr = rq + OFFSET(request_q);
+ if (!readmem(addr, KVADDR, &queue, sizeof(ulong), "request.q", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rq + OFFSET(request_cmd_flags);
+ if (!readmem(addr, KVADDR, &cmd_flags, sizeof(uint), "request.cmd_flags", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rq + OFFSET(request_state);
+ if (!readmem(addr, KVADDR, &state, sizeof(uint), "request.state", RETURN_ON_ERROR))
+ return FALSE;
+
+ if (queue == mi->q && state == MQ_RQ_IN_FLIGHT) {
+ if (op_is_write(cmd_flags))
+ mi->dio->write++;
+ else
+ mi->dio->read++;
+ }
+
+ return TRUE;
+}
+
+static bool bt_iter(uint bitnr, void *data)
+{
+ ulong addr = 0, rqs_addr = 0, rq = 0;
+ struct bt_iter_data *iter_data = data;
+ ulong tag = iter_data->tags;
+
+ if (!iter_data->reserved)
+ bitnr += iter_data->nr_reserved_tags;
+
+ /* rqs */
+ addr = tag + OFFSET(blk_mq_tags_rqs);
+ if (!readmem(addr, KVADDR, &rqs_addr, sizeof(void *), "blk_mq_tags.rqs", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rqs_addr + bitnr * sizeof(ulong); /* rqs[bitnr] */
+ if (!readmem(addr, KVADDR, &rq, sizeof(ulong), "blk_mq_tags.rqs[]", RETURN_ON_ERROR))
+ return FALSE;
+
+ return iter_data->fn(rq, iter_data->data);
+}
+
+static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_resvd_tags, struct diskio *dio)
+{
+ struct sbitmap_context sc = {0};
+ struct mq_inflight mi = {
+ .q = q,
+ .dio = dio,
+ };
+ struct bt_iter_data iter_data = {
+ .tags = tags,
+ .reserved = reserved,
+ .nr_reserved_tags = nr_resvd_tags,
+ .fn = mq_check_inflight,
+ .data = &mi,
+ };
+
+ sbitmap_context_load(sbq + OFFSET(sbitmap_queue_sb), &sc);
+ sbitmap_for_each_set(&sc, bt_iter, &iter_data);
+}
+
+static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
+{
+ uint i;
+
+ for (i = 0; i < cnt; i++) {
+ ulong addr = 0, tags = 0;
+ uint nr_reserved_tags = 0;
+
+ /* Tags owned by the block driver */
+ addr = hctx[i] + OFFSET(blk_mq_hw_ctx_tags);
+ if (!readmem(addr, KVADDR, &tags, sizeof(ulong),
+ "blk_mq_hw_ctx.tags", RETURN_ON_ERROR))
+ break;
+
+ addr = tags + OFFSET(blk_mq_tags_nr_reserved_tags);
+ if (!readmem(addr, KVADDR, &nr_reserved_tags, sizeof(uint),
+ "blk_mq_tags_nr_reserved_tags", RETURN_ON_ERROR))
+ break;
+
+ if (nr_reserved_tags) {
+ addr = tags + OFFSET(blk_mq_tags_breserved_tags);
+ bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
+ }
+ addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
+ bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
+ }
+}
+
+static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
+{
+ uint cnt = 0;
+ ulong addr = 0, hctx_addr = 0;
+ ulong *hctx_array = NULL;
+
+ addr = q + OFFSET(request_queue_nr_hw_queues);
+ readmem(addr, KVADDR, &cnt, sizeof(uint),
+ "request_queue.nr_hw_queues", FAULT_ON_ERROR);
+
+ addr = q + OFFSET(request_queue_queue_hw_ctx);
+ readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
+ "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+
+ hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);
+ if (!hctx_array)
+ error(FATAL, "fail to get memory for the hctx_array\n");
+
+ if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
+ "request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {
+ FREEBUF(hctx_array);
+ return;
+ }
+
+ queue_for_each_hw_ctx(q, hctx_array, cnt, dio);
+
+ FREEBUF(hctx_array);
+}
+
static void
get_mq_diskio(unsigned long q, unsigned long *mq_count)
{
int cpu;
unsigned long queue_ctx;
unsigned long mctx_addr;
- struct diskio tmp;
+ struct diskio tmp = {0};
if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed))
+ INVALID_MEMBER(blk_mq_ctx_rq_completed)) {
+ get_mq_diskio_from_hw_queues(q, &tmp);
+ mq_count[0] = tmp.read;
+ mq_count[1] = tmp.write;
return;
-
- memset(&tmp, 0x00, sizeof(struct diskio));
+ }
readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
sizeof(ulong), "request_queue.queue_ctx",
@@ -4479,41 +4636,24 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
&& (io.read + io.write == 0))
return;
- if (use_mq_interface(queue_addr) &&
- (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed)))
- fprintf(fp, "%s%s%s %s%s%s%s %s%s%s",
- mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
- space(MINSPACE),
- mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
- space(MINSPACE),
- mkstring(buf2, 10, LJUST, disk_name),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
- LJUST|LONG_HEX, (char *)queue_addr),
- space(MINSPACE),
- mkstring(buf4, 17, RJUST, "(not supported)"),
- space(MINSPACE));
-
- else
- fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
- mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
- space(MINSPACE),
- mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
- space(MINSPACE),
- mkstring(buf2, 10, LJUST, disk_name),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
- LJUST|LONG_HEX, (char *)queue_addr),
- space(MINSPACE),
- io.read + io.write,
- space(MINSPACE),
- mkstring(buf4, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.read),
- space(MINSPACE),
- mkstring(buf5, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.write),
- space(MINSPACE));
+ fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
+ mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
+ space(MINSPACE),
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
+ space(MINSPACE),
+ mkstring(buf2, 10, LJUST, disk_name),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
+ LJUST|LONG_HEX, (char *)queue_addr),
+ space(MINSPACE),
+ io.read + io.write,
+ space(MINSPACE),
+ mkstring(buf4, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.read),
+ space(MINSPACE),
+ mkstring(buf5, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.write),
+ space(MINSPACE));
if (VALID_MEMBER(request_queue_in_flight)) {
if (!use_mq_interface(queue_addr)) {
@@ -4597,6 +4737,9 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry");
MEMBER_OFFSET_INIT(kset_list, "kset", "list");
MEMBER_OFFSET_INIT(request_list_count, "request_list", "count");
+ MEMBER_OFFSET_INIT(request_cmd_flags, "request", "cmd_flags");
+ MEMBER_OFFSET_INIT(request_q, "request", "q");
+ MEMBER_OFFSET_INIT(request_state, "request", "state");
MEMBER_OFFSET_INIT(request_queue_in_flight, "request_queue",
"in_flight");
if (MEMBER_EXISTS("request_queue", "rq"))
@@ -4608,10 +4751,33 @@ void diskio_init(void)
"mq_ops");
ANON_MEMBER_OFFSET_INIT(request_queue_queue_ctx,
"request_queue", "queue_ctx");
+ MEMBER_OFFSET_INIT(request_queue_queue_hw_ctx,
+ "request_queue", "queue_hw_ctx");
+ MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,
+ "request_queue", "nr_hw_queues");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
"rq_dispatched");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
"rq_completed");
+ MEMBER_OFFSET_INIT(blk_mq_hw_ctx_tags, "blk_mq_hw_ctx", "tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_bitmap_tags, "blk_mq_tags",
+ "bitmap_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_breserved_tags, "blk_mq_tags",
+ "breserved_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_nr_reserved_tags, "blk_mq_tags",
+ "nr_reserved_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_rqs, "blk_mq_tags", "rqs");
+ STRUCT_SIZE_INIT(blk_mq_tags, "blk_mq_tags");
+ STRUCT_SIZE_INIT(sbitmap, "sbitmap");
+ STRUCT_SIZE_INIT(sbitmap_word, "sbitmap_word");
+ MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");
+ MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");
+ MEMBER_OFFSET_INIT(sbitmap_depth, "sbitmap", "depth");
+ 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_queue_sb, "sbitmap_queue", "sb");
+
}
MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
"klist_devices");
diff --git a/symbols.c b/symbols.c
index 5d12a021c769..c1f09556d710 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10385,6 +10385,12 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(kset_list));
fprintf(fp, " request_list_count: %ld\n",
OFFSET(request_list_count));
+ fprintf(fp, " request_cmd_flags: %ld\n",
+ OFFSET(request_cmd_flags));
+ fprintf(fp, " request_q: %ld\n",
+ OFFSET(request_q));
+ fprintf(fp, " request_state: %ld\n",
+ OFFSET(request_state));
fprintf(fp, " request_queue_in_flight: %ld\n",
OFFSET(request_queue_in_flight));
fprintf(fp, " request_queue_rq: %ld\n",
@@ -10393,10 +10399,25 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(request_queue_mq_ops));
fprintf(fp, " request_queue_queue_ctx: %ld\n",
OFFSET(request_queue_queue_ctx));
+ fprintf(fp, " request_queue_queue_hw_ctx: %ld\n",
+ OFFSET(request_queue_queue_hw_ctx));
+ fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
+ OFFSET(request_queue_nr_hw_queues));
fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n",
OFFSET(blk_mq_ctx_rq_dispatched));
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
OFFSET(blk_mq_ctx_rq_completed));
+ fprintf(fp, " blk_mq_hw_ctx_tags: %ld\n",
+ OFFSET(blk_mq_hw_ctx_tags));
+ fprintf(fp, " blk_mq_tags_bitmap_tags: %ld\n",
+ OFFSET(blk_mq_tags_bitmap_tags));
+ fprintf(fp, " blk_mq_tags_breserved_tags: %ld\n",
+ OFFSET(blk_mq_tags_breserved_tags));
+ fprintf(fp, " blk_mq_tags_nr_reserved_tags: %ld\n",
+ OFFSET(blk_mq_tags_nr_reserved_tags));
+ fprintf(fp, " blk_mq_tags_rqs: %ld\n",
+ OFFSET(blk_mq_tags_rqs));
+
fprintf(fp, " subsys_private_klist_devices: %ld\n",
OFFSET(subsys_private_klist_devices));
fprintf(fp, " subsystem_kset: %ld\n",
@@ -11003,6 +11024,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " sbitmap: %ld\n", SIZE(sbitmap));
fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
+ fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));
fprintf(fp, "\n array_table:\n");
/*
--
2.30.2

View File

@ -1,58 +0,0 @@
From dd35cf6fc5463ff31206fbb27238b4c3802c063d Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 26 Jan 2022 06:07:00 +0000
Subject: [PATCH 09/10] arm64: Fix segfault by "bt" command with offline cpus
Currently on arm64, NT_PRSTATUS notes in dumpfile are not mapped to
online cpus and machine_specific->panic_task_regs correctly. As a
result, the "bt" command can cause a segmentation fault.
crash> bt -c 0
PID: 0 TASK: ffff8000117fa240 CPU: 0 COMMAND: "swapper/0"
Segmentation fault (core dumped)
To fix this,
1) make map_cpus_to_prstatus_kdump_cmprs() map the notes to
dd->nt_prstatus_percpu also on arm64, and
2) move arm64_get_crash_notes() to machdep_init(POST_INIT) in order
to apply the mapping to machine_specific->panic_task_regs.
Resolves: https://github.com/crash-utility/crash/issues/105
Reported-by: xuchunmei000 <xuchunmei@linux.alibaba.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Tested-by: David Wysochanski <dwysocha@redhat.com>
---
arm64.c | 2 +-
diskdump.c | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index 23c3d75d85aa..4f2c2b5104a1 100644
--- a/arm64.c
+++ b/arm64.c
@@ -472,7 +472,7 @@ arm64_init(int when)
arm64_stackframe_init();
break;
- case POST_VM:
+ case POST_INIT:
/*
* crash_notes contains machine specific information about the
* crash. In particular, it contains CPU registers at the time
diff --git a/diskdump.c b/diskdump.c
index 3e1cfd548c96..d5674276e1fd 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -111,8 +111,7 @@ map_cpus_to_prstatus_kdump_cmprs(void)
if (pc->flags2 & QEMU_MEM_DUMP_COMPRESSED) /* notes exist for all cpus */
goto resize_note_pointers;
- if (!(online = get_cpus_online()) || (online == kt->cpus) ||
- machine_type("ARM64"))
+ if (!(online = get_cpus_online()) || (online == kt->cpus))
goto resize_note_pointers;
if (CRASHDEBUG(1))
--
2.20.1

View File

@ -0,0 +1,121 @@
From 68ce0b9a35d77d767872dd1a729c50e4695a30a8 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 2 Jun 2022 20:12:56 +0800
Subject: [PATCH 10/15] Fix for "dev -d|-D" options to support blk-mq change on
Linux v5.18-rc1
Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed
the "queue_hw_ctx" member from struct request_queue at Linux v5.18-rc1,
and replaced it with a struct xarray "hctx_table". Without the patch, the
"dev -d|-D" options will print an error:
crash> dev -d
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE
dev: invalid structure member offset: request_queue_queue_hw_ctx
With the patch:
crash> dev -d
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE
8 ffff8e99d0a1ae00 sda ffff8e9c14c59980 10 6 4
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
dev.c | 42 +++++++++++++++++++++++++++++++++---------
symbols.c | 2 ++
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/defs.h b/defs.h
index 2681586a33dc..7d3b73422f48 100644
--- a/defs.h
+++ b/defs.h
@@ -2180,6 +2180,7 @@ struct offset_table { /* stash of commonly-used offsets */
long blk_mq_tags_breserved_tags;
long blk_mq_tags_nr_reserved_tags;
long blk_mq_tags_rqs;
+ long request_queue_hctx_table;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 4be4c96df8b0..0172c83ffaea 100644
--- a/dev.c
+++ b/dev.c
@@ -4369,20 +4369,42 @@ static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
uint cnt = 0;
ulong addr = 0, hctx_addr = 0;
ulong *hctx_array = NULL;
+ struct list_pair *lp = NULL;
+
+ if (VALID_MEMBER(request_queue_hctx_table)) {
+ addr = q + OFFSET(request_queue_hctx_table);
+ cnt = do_xarray(addr, XARRAY_COUNT, NULL);
+ lp = (struct list_pair *)GETBUF(sizeof(struct list_pair) * (cnt + 1));
+ if (!lp)
+ error(FATAL, "fail to get memory for list_pair.\n");
+ lp[0].index = cnt;
+ cnt = do_xarray(addr, XARRAY_GATHER, lp);
+ } else {
+ addr = q + OFFSET(request_queue_nr_hw_queues);
+ readmem(addr, KVADDR, &cnt, sizeof(uint),
+ "request_queue.nr_hw_queues", FAULT_ON_ERROR);
- addr = q + OFFSET(request_queue_nr_hw_queues);
- readmem(addr, KVADDR, &cnt, sizeof(uint),
- "request_queue.nr_hw_queues", FAULT_ON_ERROR);
-
- addr = q + OFFSET(request_queue_queue_hw_ctx);
- readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
- "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+ addr = q + OFFSET(request_queue_queue_hw_ctx);
+ readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
+ "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+ }
hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);
- if (!hctx_array)
+ if (!hctx_array) {
+ if (lp)
+ FREEBUF(lp);
error(FATAL, "fail to get memory for the hctx_array\n");
+ }
+
+ if (lp && hctx_array) {
+ uint i;
+
+ /* copy it from list_pair to hctx_array */
+ for (i = 0; i < cnt; i++)
+ hctx_array[i] = (ulong)lp[i].value;
- if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
+ FREEBUF(lp);
+ } else if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
"request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {
FREEBUF(hctx_array);
return;
@@ -4755,6 +4777,8 @@ void diskio_init(void)
"request_queue", "queue_hw_ctx");
MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,
"request_queue", "nr_hw_queues");
+ MEMBER_OFFSET_INIT(request_queue_hctx_table,
+ "request_queue", "hctx_table");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
"rq_dispatched");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
diff --git a/symbols.c b/symbols.c
index c1f09556d710..bee1faf92c83 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10403,6 +10403,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(request_queue_queue_hw_ctx));
fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
OFFSET(request_queue_nr_hw_queues));
+ fprintf(fp, " request_queue_hctx_table: %ld\n",
+ OFFSET(request_queue_hctx_table));
fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n",
OFFSET(blk_mq_ctx_rq_dispatched));
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
--
2.30.2

View File

@ -1,88 +0,0 @@
From 5f390ed811b00753ce7d5ceec5717280df16fd28 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 2 Feb 2022 02:14:56 +0000
Subject: [PATCH 10/10] Fix for "kmem -s|-S" and "bt -F[F]" on Linux 5.17-rc1
Since the following kernel commits split slab info from struct page
into struct slab, crash cannot get several slab related offsets from
struct page.
d122019bf061 ("mm: Split slab into its own type")
07f910f9b729 ("mm: Remove slab from struct page")
Without the patch, "kmem -s|-S" and "bt -F[F]" options cannot work
correctly with the following errors:
crash> kmem -s kmem_cache
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
kmem: page_to_nid: invalid page: ffff9454afc35020
kmem: kmem_cache: cannot gather relevant slab data
ffff945140042000 216 ? ? ? 8k kmem_cache
crash> bt -F
...
bt: invalid structure member offset: page_slab
FILE: memory.c LINE: 9477 FUNCTION: vaddr_to_kmem_cache()
Signed-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
memory.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/memory.c b/memory.c
index e80c59ea4534..8448ddc3a16c 100644
--- a/memory.c
+++ b/memory.c
@@ -421,6 +421,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(page_prev, "page", "prev");
if (INVALID_MEMBER(page_next))
ANON_MEMBER_OFFSET_INIT(page_next, "page", "next");
+ if (INVALID_MEMBER(page_next))
+ MEMBER_OFFSET_INIT(page_next, "slab", "next");
MEMBER_OFFSET_INIT(page_list, "page", "list");
if (VALID_MEMBER(page_list)) {
@@ -747,11 +749,15 @@ vm_init(void)
MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache", "random");
MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page");
+ if (INVALID_MEMBER(kmem_cache_cpu_page))
+ MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "slab");
MEMBER_OFFSET_INIT(kmem_cache_cpu_node, "kmem_cache_cpu", "node");
MEMBER_OFFSET_INIT(kmem_cache_cpu_partial, "kmem_cache_cpu", "partial");
MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
if (INVALID_MEMBER(page_inuse))
ANON_MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
+ if (INVALID_MEMBER(page_inuse))
+ MEMBER_OFFSET_INIT(page_inuse, "slab", "inuse");
MEMBER_OFFSET_INIT(page_offset, "page", "offset");
if (INVALID_MEMBER(page_offset))
ANON_MEMBER_OFFSET_INIT(page_offset, "page", "offset");
@@ -763,6 +769,9 @@ vm_init(void)
if (INVALID_MEMBER(page_slab))
ANON_MEMBER_OFFSET_INIT(page_slab, "page", "slab_cache");
}
+ if (INVALID_MEMBER(page_slab))
+ MEMBER_OFFSET_INIT(page_slab, "slab", "slab_cache");
+
MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
if (INVALID_MEMBER(page_slab_page))
ANON_MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
@@ -772,10 +781,14 @@ vm_init(void)
MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
if (INVALID_MEMBER(page_freelist))
ANON_MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
+ if (INVALID_MEMBER(page_freelist))
+ MEMBER_OFFSET_INIT(page_freelist, "slab", "freelist");
if (INVALID_MEMBER(kmem_cache_objects)) {
MEMBER_OFFSET_INIT(kmem_cache_oo, "kmem_cache", "oo");
/* NOTE: returns offset of containing bitfield */
ANON_MEMBER_OFFSET_INIT(page_objects, "page", "objects");
+ if (INVALID_MEMBER(page_objects))
+ ANON_MEMBER_OFFSET_INIT(page_objects, "slab", "objects");
}
if (VALID_MEMBER(kmem_cache_node)) {
ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.node", NULL, 0);
--
2.20.1

View File

@ -0,0 +1,43 @@
From c672d7a4c290712b32c54329cbdc1e74d122e813 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 6 Jun 2022 19:09:16 +0800
Subject: [PATCH 11/15] Doc: update man page for the "bpf" and "sbitmapq"
commands
The information of the "bpf" and "sbitmapq" commands is missing in the man
page of the crash utility. Let's add it to the man page.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
crash.8 | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/crash.8 b/crash.8
index 1f3657b11e4c..e553a0b4adb3 100644
--- a/crash.8
+++ b/crash.8
@@ -584,6 +584,9 @@ creates a single-word alias for a command.
.I ascii
displays an ascii chart or translates a numeric value into its ascii components.
.TP
+.I bpf
+provides information on currently-loaded eBPF programs and maps.
+.TP
.I bt
displays a task's kernel-stack backtrace. If it is given the
.I \-a
@@ -706,6 +709,11 @@ number of seconds between each command execution.
.I runq
displays the tasks on the run queue.
.TP
+.I sbitmapq
+dumps the contents of the sbitmap_queue structure and the used
+bits in the bitmap. Also, it shows the dump of a structure array
+associated with the sbitmap_queue.
+.TP
.I search
searches a range of user or kernel memory space for given value.
.TP
--
2.30.2

View File

@ -0,0 +1,47 @@
From 9ce31a14d1083cbb2beb4a8e6eb7b88234b79a99 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 12/15] sbitmapq: Fix for sbitmap_queue without ws_active
member
The sbitmap_queue.ws_active member was added by kernel commit 5d2ee7122c73
("sbitmap: optimize wakeup check") 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_queue_ws_active
FILE: sbitmap.c LINE: 393 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
sbitmap.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index e8ebd62fe01c..152c28e6875f 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -325,7 +325,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
fprintf(fp, "wake_batch = %u\n", sqc->wake_batch);
fprintf(fp, "wake_index = %d\n", sqc->wake_index);
- fprintf(fp, "ws_active = %d\n", sqc->ws_active);
+ if (VALID_MEMBER(sbitmap_queue_ws_active)) /* 5.0 and later */
+ fprintf(fp, "ws_active = %d\n", sqc->ws_active);
sbq_wait_state_size = SIZE(sbq_wait_state);
wait_cnt_off = OFFSET(sbq_wait_state_wait_cnt);
@@ -380,7 +381,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
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));
- sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
+ if (VALID_MEMBER(sbitmap_queue_ws_active))
+ sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
if (VALID_MEMBER(sbitmap_queue_round_robin))
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
--
2.30.2

View File

@ -0,0 +1,109 @@
From 0d3e86fee5eead93b521a0e20a0e099ede4ab72b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 13/15] sbitmapq: Fix for sbitmap_word without cleared member
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 <k-hagio-ab@nec.com>
---
sbitmap.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 152c28e6875f..c9f7209f9e3e 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);
+
+ 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.30.2

View File

@ -0,0 +1,48 @@
From 12fe6c7cdd768f87ce6e903a2bbfb0c0591585c5 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 14/15] sbitmapq: Fix for sbitmap_queue without
min_shallow_depth member
The sbitmap_queue.min_shallow_depth member was added by kernel commit
a327553965de ("sbitmap: fix missed wakeups caused by sbitmap_queue_get_shallow()")
at Linux 4.18. Without the patch, on earlier kernels the "sbitmapq"
command fails with the following error:
crash> sbitmapq ffff89bb7638ee50
sbitmapq: invalid structure member offset: sbitmap_queue_min_shallow_depth
FILE: sbitmap.c LINE: 398 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
sbitmap.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index c9f7209f9e3e..bb2f19e6207b 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -371,7 +371,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
else if (VALID_MEMBER(sbitmap_round_robin)) /* 5.13 and later */
fprintf(fp, "round_robin = %d\n", sc->round_robin);
- fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
+ if (VALID_MEMBER(sbitmap_queue_min_shallow_depth)) /* 4.18 and later */
+ fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
}
static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context *sqc)
@@ -395,7 +396,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
if (VALID_MEMBER(sbitmap_queue_round_robin))
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
- sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
+ if (VALID_MEMBER(sbitmap_queue_min_shallow_depth))
+ sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
FREEBUF(sbitmap_queue_buf);
}
--
2.30.2

View File

@ -0,0 +1,83 @@
From c07068266b41450ca6821ee0a1a3adf34206015f Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 15:21:53 +0900
Subject: [PATCH 15/15] Make "dev -d|-D" options parse sbitmap on Linux 4.18
and later
There have been a few reports that the "dev -d|-D" options displayed
incorrect I/O stats due to racy blk_mq_ctx.rq_* counters. To fix it,
make the options parse sbitmap to count I/O stats on Linux 4.18 and
later kernels, which include RHEL8 ones.
To do this, adjust to the blk_mq_tags structure of Linux 5.10 through
5.15 kernels, which contain kernel commit 222a5ae03cdd ("blk-mq: Use
pointers for blk_mq_tags bitmap tags") and do not contain ae0f1a732f4a
("blk-mq: Stop using pointers for blk_mq_tags bitmap tags").
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
dev.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/dev.c b/dev.c
index 0172c83ffaea..db97f8aebdc2 100644
--- a/dev.c
+++ b/dev.c
@@ -4339,6 +4339,10 @@ static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_r
static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
{
uint i;
+ int bitmap_tags_is_ptr = 0;
+
+ if (MEMBER_TYPE("blk_mq_tags", "bitmap_tags") == TYPE_CODE_PTR)
+ bitmap_tags_is_ptr = 1;
for (i = 0; i < cnt; i++) {
ulong addr = 0, tags = 0;
@@ -4357,9 +4361,17 @@ static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio
if (nr_reserved_tags) {
addr = tags + OFFSET(blk_mq_tags_breserved_tags);
+ if (bitmap_tags_is_ptr &&
+ !readmem(addr, KVADDR, &addr, sizeof(ulong),
+ "blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
+ break;
bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
}
addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
+ if (bitmap_tags_is_ptr &&
+ !readmem(addr, KVADDR, &addr, sizeof(ulong),
+ "blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
+ break;
bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
}
}
@@ -4423,14 +4435,23 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
unsigned long mctx_addr;
struct diskio tmp = {0};
- if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed)) {
+ /*
+ * Currently this function does not support old blk-mq implementation
+ * before 12f5b9314545 ("blk-mq: Remove generation seqeunce"), so
+ * filter them out.
+ */
+ if (VALID_MEMBER(request_state)) {
+ if (CRASHDEBUG(1))
+ fprintf(fp, "mq: using sbitmap\n");
get_mq_diskio_from_hw_queues(q, &tmp);
mq_count[0] = tmp.read;
mq_count[1] = tmp.write;
return;
}
+ if (CRASHDEBUG(1))
+ fprintf(fp, "mq: using blk_mq_ctx.rq_{completed,dispatched} counters\n");
+
readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
sizeof(ulong), "request_queue.queue_ctx",
FAULT_ON_ERROR);
--
2.30.2

View File

@ -1,6 +1,6 @@
--- crash-8.0.0/Makefile.orig
+++ crash-8.0.0/Makefile
@@ -203,7 +203,7 @@ GDB_FLAGS=
--- crash-8.0.1/Makefile.orig
+++ crash-8.0.1/Makefile
@@ -204,7 +204,7 @@ GDB_FLAGS=
# TARGET_CFLAGS will be configured automatically by configure
TARGET_CFLAGS=
@ -9,17 +9,17 @@
GPL_FILES=
TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \
@@ -233,7 +233,7 @@ all: make_configure
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
make --no-print-directory gdb_unzip; fi
$(MAKE) gdb_unzip; fi
- @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic -Wl,-z,now -fPIE" > ${GDB}/gdb/mergelibs
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.0/configure.c.orig
+++ crash-8.0.0/configure.c
--- crash-8.0.1/configure.c.orig
+++ crash-8.0.1/configure.c
@@ -810,7 +810,8 @@ build_configure(struct supported_gdb_version *sp)
fprintf(fp2, "%s\n", sp->GDB);
sprintf(target_data.gdb_version, "%s", &sp->GDB[4]);

View File

@ -1,16 +1,16 @@
--- crash-8.0.0/Makefile.orig
+++ crash-8.0.0/Makefile
@@ -233,7 +233,7 @@ all: make_configure
--- crash-8.0.1/Makefile.orig
+++ crash-8.0.1/Makefile
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
make --no-print-directory gdb_unzip; fi
$(MAKE) gdb_unzip; fi
- @echo "${LDFLAGS} -lz -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic" > ${GDB}/gdb/mergelibs
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.0/diskdump.c.orig
+++ crash-8.0.0/diskdump.c
--- crash-8.0.1/diskdump.c.orig
+++ crash-8.0.1/diskdump.c
@@ -23,6 +23,9 @@
* GNU General Public License for more details.
*/

View File

@ -3,8 +3,8 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 8.0.0
Release: 6%{?dist}.alma
Version: 8.0.1
Release: 2%{?dist}.alma
License: GPLv3
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
@ -18,24 +18,23 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy_zstd.patch
Patch1: crash-8.0.0_build.patch
Patch2: 0001-arm64-Support-overflow-stack-panic.patch
Patch3: 0002-defs.h-fix-breakage-of-compatibility-of-struct-machd.patch
Patch4: 0003-defs.h-fix-breakage-of-compatibility-of-struct-symbo.patch
Patch5: 0001-Fix-pvops-Xen-detection-for-arm-machine.patch
Patch6: 0002-Handle-blk_mq_ctx-member-changes-for-kernels-5.16-rc.patch
Patch7: 0001-Fix-for-timer-r-option-to-display-all-the-per-CPU-cl.patch
Patch8: 0002-Fix-for-bt-v-option-to-display-the-stack-end-address.patch
Patch9: 0003-Fix-for-HZ-calculation-on-Linux-5.14-and-later.patch
Patch10: 0004-memory-Handle-struct-slab-changes-on-Linux-5.17-rc1-.patch
Patch11: 0005-Move-the-initialization-of-boot_date-to-task_init.patch
Patch12: 0006-Remove-ptype-command-from-ps-t-option-to-reduce-memo.patch
Patch13: 0007-GDB-fix-completion-related-libstdc-assert.patch
Patch14: 0008-Improve-the-ps-performance-for-vmcores-with-large-nu.patch
Patch15: 0009-arm64-Fix-segfault-by-bt-command-with-offline-cpus.patch
Patch16: 0010-Fix-for-kmem-s-S-and-bt-F-F-on-Linux-5.17-rc1.patch
Patch17: 0001-arm64-Use-CONFIG_ARM64_VA_BITS-to-initialize-VA_BITS.patch
Patch18: 0001-arm64-deduce-the-start-address-of-kernel-code-based-.patch
Patch1: crash-8.0.1_build.patch
Patch2: 0001-ppc64-update-the-NR_CPUS-to-8192.patch
Patch3: 0001-sbitmapq-remove-struct-and-member-validation-in-sbit.patch
Patch4: 0002-sbitmapq-fix-invalid-offset-for-sbitmap_queue_alloc_.patch
Patch5: 0003-sbitmapq-fix-invalid-offset-for-sbitmap_queue_round_.patch
Patch6: 0004-sbitmapq-fix-invalid-offset-for-sbitmap_word_depth-o.patch
Patch7: 0005-Makefile-add-missing-crash_target.o-to-be-cleaned.patch
Patch8: 0006-bt-x86_64-filter-out-idle-task-stack.patch
Patch9: 0007-bt-arm64-add-support-for-bt-n-idle.patch
Patch10: 0008-gdb-print-details-of-unnamed-struct-and-union.patch
Patch11: 0009-Enhance-dev-d-D-options-to-support-blk-mq-sbitmap.patch
Patch12: 0010-Fix-for-dev-d-D-options-to-support-blk-mq-change-on-.patch
Patch13: 0011-Doc-update-man-page-for-the-bpf-and-sbitmapq-command.patch
Patch14: 0012-sbitmapq-Fix-for-sbitmap_queue-without-ws_active-mem.patch
Patch15: 0013-sbitmapq-Fix-for-sbitmap_word-without-cleared-member.patch
Patch16: 0014-sbitmapq-Fix-for-sbitmap_queue-without-min_shallow_d.patch
Patch17: 0015-Make-dev-d-D-options-parse-sbitmap-on-Linux-4.18-and.patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -56,7 +55,7 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%prep
%setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy_zstd.patch
%patch1 -p1 -b crash-8.0.0_build.patch
%patch1 -p1 -b crash-8.0.1_build.patch
%patch2 -p1
%patch3 -p1
%patch4 -p1
@ -73,12 +72,11 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%build
cp %{SOURCE1} .
make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" CXXFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}"
make -j`nproc` RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" CXXFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}"
%install
rm -rf %{buildroot}
@ -99,11 +97,15 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Wed May 18 2022 Eduard Abdullin <eabdullin@almalinux.org> - 8.0.0-6.alma
* Tue Nov 15 2022 Eduard Abdullin <eabdullin@almalinux.org> - 8.0.1-2.alma
- Debrand for AlmaLinux
* Fri Mar 04 2022 Lianbo Jiang <lijiang@redhat.com> - 8.0.0-6
- Fix for "bt: read of IRQ stack failed" issue on aarch64
* Fri Jun 10 2022 Lianbo Jiang <lijiang@redhat.com> - 8.0.1-2
- Fix for the "struct -o" command issue
- Enhance the "dev -d" and "bt" commands
* Sat May 14 2022 Lianbo Jiang <lijiang@redhat.com> - 8.0.1-1
- Rebase to upstream crash 8.0.1
* Mon Feb 07 2022 Lianbo Jiang <lijiang@redhat.com> - 8.0.0-5
- Fix segfault on aarch64 for "bt -a|-c" command