[PATCH v3] make the MAX_MALLOC_BUFS customizable
by Shivang Upadhyay
the default (and minimum) value of MAX_MALLOC_BUFS is 3072, but can be
changed with command line with flag `--max-malloc-bufs`.
Signed-off-by: Shivang Upadhyay <shivangu(a)linux.ibm.com>
---
defs.h | 1 +
main.c | 9 +++++++++
tools.c | 9 ++++++---
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index ab4aee8..863baf9 100644
--- a/defs.h
+++ b/defs.h
@@ -5608,6 +5608,7 @@ void exec_args_input_file(struct command_table_entry *, struct args_input_file *
/*
* tools.c
*/
+extern int MAX_MALLOC_BUFS;
FILE *set_error(char *);
int __error(int, char *, ...);
#define error __error /* avoid conflict with gdb error() */
diff --git a/main.c b/main.c
index 71bcc15..0b0cabe 100644
--- a/main.c
+++ b/main.c
@@ -46,6 +46,7 @@ static struct option long_options[] = {
{"version", 0, 0, 0},
{"buildinfo", 0, 0, 0},
{"cpus", required_argument, 0, 0},
+ {"max-malloc-bufs", required_argument, 0, 0},
{"no_ikconfig", 0, 0, 0},
{"hyper", 0, 0, 0},
{"p2m_mfn", required_argument, 0, 0},
@@ -163,6 +164,14 @@ main(int argc, char **argv)
else if (STREQ(long_options[option_index].name, "cpus"))
kt->cpus_override = optarg;
+ else if (STREQ(long_options[option_index].name, "max-malloc-bufs")) {
+ MAX_MALLOC_BUFS = atoi(optarg);
+
+ if (MAX_MALLOC_BUFS < 3072) {
+ MAX_MALLOC_BUFS = 3072;
+ }
+ }
+
else if (STREQ(long_options[option_index].name, "hyper"))
pc->flags |= XEN_HYPER;
diff --git a/tools.c b/tools.c
index a9ad18d..69250c4 100644
--- a/tools.c
+++ b/tools.c
@@ -5698,7 +5698,7 @@ ll_power(long long base, long long exp)
#define B32K (4)
#define SHARED_BUF_SIZES (B32K+1)
-#define MAX_MALLOC_BUFS (2000)
+int MAX_MALLOC_BUFS = 3072; /* can be changed from command line args */
#define MAX_CACHE_SIZE (KILOBYTES(32))
struct shared_bufs {
@@ -5723,7 +5723,7 @@ struct shared_bufs {
long buf_8K_ovf;
long buf_32K_ovf;
int buf_inuse[SHARED_BUF_SIZES];
- char *malloc_bp[MAX_MALLOC_BUFS];
+ char **malloc_bp;
long smallest;
long largest;
long embedded;
@@ -5744,6 +5744,7 @@ buf_init(void)
bp->smallest = 0x7fffffff;
bp->total = 0.0;
+ bp->malloc_bp = (char**) calloc(MAX_MALLOC_BUFS * sizeof(char*), 1);
#ifdef VALGRIND
VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K));
@@ -6130,7 +6131,9 @@ getbuf(long reqsize)
dump_shared_bufs();
return ((char *)(long)
- error(FATAL, "cannot allocate any more memory!\n"));
+ error(FATAL, "cannot allocate any more memory!\n"
+ "try increasing --max-malloc-bufs (current value : %d)\n",
+ MAX_MALLOC_BUFS));
}
/*
--
2.52.0
2 weeks, 2 days
Behind the Scenes of Campus Data Centers: Insights from Crash Utility Practices
by yingashley13@gmail.com
Modern universities rely heavily on digital infrastructure to keep classrooms, online platforms, and administrative systems running smoothly. While students and faculty experience seamless access to online courses, virtual libraries, and academic portals, much of this reliability comes from what happens behind the scenes—specifically within campus data centers. These centers serve as the backbone of digital learning, ensuring continuous access to resources, stable performance, and quick recovery during system failures.
In higher education, the importance of uninterrupted online learning cannot be overstated. Many students, for instance, rely on platforms like Myassignmenthelp for academic support, where they might search for options such as take my online class for me (https://myassignmenthelp.com/take-my-online-class.html
). This highlights how critical system reliability is for educational services, whether hosted directly by universities or through third-party academic support platforms. Without dependable infrastructure, both students and institutions risk losing valuable time, resources, and learning opportunities.
This is where practices drawn from tools like the Crash Utility come into play. Originally designed for analyzing Linux kernel crash dumps, these tools provide system administrators with detailed insights into why systems fail. For campus data centers, adopting similar diagnostic approaches allows IT teams to quickly identify the root cause of failures, prevent recurring issues, and maintain high system availability. In turn, this ensures that students can log into their learning portals, submit assignments, and access lecture recordings without disruption.
Moreover, proactive crash analysis fosters a culture of resilience within educational institutions. Instead of waiting for problems to escalate, IT administrators can anticipate potential bottlenecks or vulnerabilities and resolve them before they affect users. For universities striving to enhance their digital infrastructure, integrating such practices strengthens their ability to support large-scale e-learning initiatives, hybrid classrooms, and research collaborations.
In conclusion, while students may only see the front-end of digital learning systems, the true strength of an institution lies in its backend stability. By incorporating insights from crash utility practices, campus data centers can ensure smooth, uninterrupted academic experiences—making education more accessible, reliable, and future-ready.
3 weeks
Re: [PATCH] make the MAX_MALLOC_BUFS customizable
by lijiang
Hi, Shivang
Thank you for the patch.
On Thu, Nov 20, 2025 at 4:18 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Wed, 19 Nov 2025 16:23:46 +0530
> From: Shivang Upadhyay <shivangu(a)linux.ibm.com>
> Subject: [Crash-utility] [PATCH] make the MAX_MALLOC_BUFS customizable
> To: k-hagio-ab(a)nec.com, lijiang(a)redhat.com
> Cc: shivangu(a)linux.ibm.com, devel(a)lists.crash-utility.osci.io
> Message-ID: <20251119105346.24902-1-shivangu(a)linux.ibm.com>
>
> default value is kept to 2000, but can be changed with
> command line with flag `--max-malloc-bufs`.
>
> Signed-off-by: Shivang Upadhyay <shivangu(a)linux.ibm.com>
> ---
> defs.h | 1 +
> main.c | 4 ++++
> tools.c | 9 ++++++---
> 3 files changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index ab4aee8..863baf9 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -5608,6 +5608,7 @@ void exec_args_input_file(struct command_table_entry
> *, struct args_input_file *
> /*
> * tools.c
> */
> +extern int MAX_MALLOC_BUFS;
> FILE *set_error(char *);
> int __error(int, char *, ...);
> #define error __error /* avoid conflict with gdb error() */
> diff --git a/main.c b/main.c
> index 71bcc15..e986792 100644
> --- a/main.c
> +++ b/main.c
> @@ -46,6 +46,7 @@ static struct option long_options[] = {
> {"version", 0, 0, 0},
> {"buildinfo", 0, 0, 0},
> {"cpus", required_argument, 0, 0},
> + {"max-malloc-bufs", required_argument, 0, 0},
> {"no_ikconfig", 0, 0, 0},
> {"hyper", 0, 0, 0},
> {"p2m_mfn", required_argument, 0, 0},
> @@ -163,6 +164,9 @@ main(int argc, char **argv)
> else if (STREQ(long_options[option_index].name,
> "cpus"))
> kt->cpus_override = optarg;
>
> + else if (STREQ(long_options[option_index].name,
> "max-malloc-bufs"))
> + MAX_MALLOC_BUFS = atoi(optarg);
> +
> else if (STREQ(long_options[option_index].name,
> "hyper"))
> pc->flags |= XEN_HYPER;
>
> diff --git a/tools.c b/tools.c
> index a9ad18d..c9867e1 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -5698,7 +5698,7 @@ ll_power(long long base, long long exp)
> #define B32K (4)
>
> #define SHARED_BUF_SIZES (B32K+1)
> -#define MAX_MALLOC_BUFS (2000)
> +int MAX_MALLOC_BUFS = 2000; /* can be changed from command line args */
>
Think it again and discuss with customers, that should be good to fold
these two patches into one patch:
https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01829.html
That is to say, increase the default MAX_MALLOC_BUFS and also introduce the
--max-malloc-bufs options, which can handle both cases:
1. most customers never hit the max limit
2. deal with large vmcores without blocking analysis
What do you think?
Thank
Lianbo
#define MAX_CACHE_SIZE (KILOBYTES(32))
>
> struct shared_bufs {
> @@ -5723,7 +5723,7 @@ struct shared_bufs {
> long buf_8K_ovf;
> long buf_32K_ovf;
> int buf_inuse[SHARED_BUF_SIZES];
> - char *malloc_bp[MAX_MALLOC_BUFS];
> + char **malloc_bp;
> long smallest;
> long largest;
> long embedded;
> @@ -5744,6 +5744,7 @@ buf_init(void)
>
> bp->smallest = 0x7fffffff;
> bp->total = 0.0;
> + bp->malloc_bp = (char**) calloc(MAX_MALLOC_BUFS * sizeof(char*),
> 1);
>
> #ifdef VALGRIND
> VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K));
> @@ -6130,7 +6131,9 @@ getbuf(long reqsize)
> dump_shared_bufs();
>
> return ((char *)(long)
> - error(FATAL, "cannot allocate any more memory!\n"));
> + error(FATAL, "cannot allocate any more memory!\n"
> + "try increasing --max-malloc-bufs
> (current value : %d)\n",
> + MAX_MALLOC_BUFS));
> }
>
> /*
> --
> 2.51.0
>
3 weeks
[PATCH] Fix "timer -r" option on Linux 6.18 and later kernels
by HAGIO KAZUHITO(萩尾 一仁)
Kernel commit 009eb5da29a9 ("hrtimer: Remove hrtimer_clock_base::
Get_time") removed the get_time member from struct hrtimer_clock_base.
As a result, the "timer -r" option fails with the following error:
crash> timer -r
timer: invalid structure member offset: hrtimer_clock_base_get_time
FILE: kernel.c LINE: 7953 FUNCTION: dump_hrtimer_clock_base()
As the get_time function is switched by __hrtimer_cb_get_time() function
with clock_id macro value, crash cannot follow their changes
automatically. So change what "timer -r" displays there from the
get_time function name to enum hrtimer_base_type name.
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
I refered to page_flags_init_from_pageflags_enum() function to use
dump_enumerator_list(), pc->flags2 and etc.
defs.h | 1 +
kernel.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++----
symbols.c | 2 ++
3 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index ab4aee8520a7..7f87e8e939e9 100644
--- a/defs.h
+++ b/defs.h
@@ -2280,6 +2280,7 @@ struct offset_table { /* stash of commonly-used offsets */
long bpf_ringbuf_map_rb;
long bpf_ringbuf_consumer_pos;
long bpf_ringbuf_nr_pages;
+ long hrtimer_clock_base_index;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/kernel.c b/kernel.c
index 13f33742990e..ec287bb55c05 100644
--- a/kernel.c
+++ b/kernel.c
@@ -43,6 +43,7 @@ static void display_bh_1(void);
static void display_bh_2(void);
static void display_bh_3(void);
static void display_bh_4(void);
+static int hrtimer_base_type_init(void);
static void dump_hrtimer_data(const ulong *cpus);
static void dump_hrtimer_clock_base(const void *, const int);
static void dump_hrtimer_base(const void *, const int);
@@ -796,6 +797,12 @@ kernel_init()
"hrtimer_clock_base", "first");
MEMBER_OFFSET_INIT(hrtimer_clock_base_get_time,
"hrtimer_clock_base", "get_time");
+ if (INVALID_MEMBER(hrtimer_clock_base_get_time)) {
+ /* Linux 6.18: 009eb5da29a9 */
+ MEMBER_OFFSET_INIT(hrtimer_clock_base_index, "hrtimer_clock_base", "index");
+ if (!hrtimer_base_type_init())
+ error(WARNING, "cannot get enum hrtimer_base_type\n");
+ }
}
STRUCT_SIZE_INIT(hrtimer_base, "hrtimer_base");
@@ -7938,6 +7945,52 @@ static int expires_len = -1;
static int softexpires_len = -1;
static int tte_len = -1;
+static char **hrtimer_base_type = NULL;
+static int
+hrtimer_base_type_init(void)
+{
+ long max_bases;
+ int i, c ATTRIBUTE_UNUSED;
+ char buf[BUFSIZE];
+ char *arglist[MAXARGS];
+
+ if (!enumerator_value("HRTIMER_MAX_CLOCK_BASES", &max_bases))
+ return FALSE;
+
+ hrtimer_base_type = (char **)calloc(max_bases, sizeof(char *));
+ if (!hrtimer_base_type)
+ return FALSE;
+
+ pc->flags2 |= ALLOW_FP; /* Required during initialization */
+ open_tmpfile();
+ if (dump_enumerator_list("hrtimer_base_type")) {
+ rewind(pc->tmpfile);
+ while (fgets(buf, BUFSIZE, pc->tmpfile)) {
+ if (!strstr(buf, " = "))
+ continue;
+ c = parse_line(buf, arglist);
+ i = atoi(arglist[2]);
+ if (0 <= i && i < max_bases)
+ hrtimer_base_type[i] = strdup(arglist[0]);
+ }
+ close_tmpfile();
+ pc->flags2 &= ~ALLOW_FP;
+ } else {
+ close_tmpfile();
+ pc->flags2 &= ~ALLOW_FP;
+ free(hrtimer_base_type);
+ hrtimer_base_type = NULL;
+ return FALSE;
+ }
+
+ if (CRASHDEBUG(1)) {
+ for (i = 0; i < max_bases; i++)
+ fprintf(fp, "hrtimer_base_type[%d] = %s\n", i, hrtimer_base_type[i]);
+ }
+
+ return TRUE;
+}
+
static void
dump_hrtimer_clock_base(const void *hrtimer_bases, const int num)
{
@@ -7949,11 +8002,23 @@ dump_hrtimer_clock_base(const void *hrtimer_bases, const int num)
base = (void *)hrtimer_bases + OFFSET(hrtimer_cpu_base_clock_base) +
SIZE(hrtimer_clock_base) * num;
- readmem((ulong)(base + OFFSET(hrtimer_clock_base_get_time)), KVADDR,
- &get_time, sizeof(get_time), "hrtimer_clock_base get_time",
- FAULT_ON_ERROR);
- fprintf(fp, " CLOCK: %d HRTIMER_CLOCK_BASE: %lx [%s]\n", num,
- (ulong)base, value_to_symstr(get_time, buf, 0));
+
+ if (INVALID_MEMBER(hrtimer_clock_base_get_time)) {
+ /* Linux 6.18: 009eb5da29a9 */
+ if (hrtimer_base_type) {
+ uint index;
+ readmem((ulong)(base + OFFSET(hrtimer_clock_base_index)), KVADDR, &index,
+ sizeof(index), "hrtimer_clock_base index", FAULT_ON_ERROR);
+ fprintf(fp, " CLOCK: %d HRTIMER_CLOCK_BASE: %lx [%s]\n", num,
+ (ulong)base, hrtimer_base_type[index]);
+ } else
+ fprintf(fp, " CLOCK: %d HRTIMER_CLOCK_BASE: %lx\n", num, (ulong)base);
+ } else {
+ readmem((ulong)(base + OFFSET(hrtimer_clock_base_get_time)), KVADDR, &get_time,
+ sizeof(get_time), "hrtimer_clock_base get_time", FAULT_ON_ERROR);
+ fprintf(fp, " CLOCK: %d HRTIMER_CLOCK_BASE: %lx [%s]\n", num,
+ (ulong)base, value_to_symstr(get_time, buf, 0));
+ }
/* get current time(uptime) */
get_uptime(NULL, ¤t_time);
diff --git a/symbols.c b/symbols.c
index 480fdb6d98b3..c446beb43a76 100644
--- a/symbols.c
+++ b/symbols.c
@@ -11760,6 +11760,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(hrtimer_clock_base_first));
fprintf(fp, " hrtimer_clock_base_get_time: %ld\n",
OFFSET(hrtimer_clock_base_get_time));
+ fprintf(fp, " hrtimer_clock_base_index: %ld\n",
+ OFFSET(hrtimer_clock_base_index));
fprintf(fp, " hrtimer_base_first: %ld\n",
OFFSET(hrtimer_base_first));
fprintf(fp, " hrtimer_base_pending: %ld\n",
--
2.31.1
3 weeks, 1 day
[PATCH] Fix typo: uncompess -> uncompress
by Dominique Martinet
---
Not much to say about this, just happened to run into that building an
aarch64 crash for testing and forgetting to add zstd flag -- thanks for
the cross build option, that was great! :)
diskdump.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index de907551153d..5d3ef81fc607 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1368,7 +1368,7 @@ cache_page(physaddr_t paddr)
} else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
if (!(dd->flags & ZSTD_SUPPORTED)) {
- error(INFO, "%s: uncompess failed: no zstd compression support\n",
+ error(INFO, "%s: uncompress failed: no zstd compression support\n",
DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
return READ_ERROR;
}
@@ -1376,7 +1376,7 @@ cache_page(physaddr_t paddr)
if (!dctx) {
dctx = ZSTD_createDCtx();
if (!dctx) {
- error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
+ error(INFO, "%s: uncompress failed: cannot create ZSTD_DCtx\n",
DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
return READ_ERROR;
}
--
2.47.3
3 weeks, 1 day
[PATCH] Resolve BLK_MQ_F_TAG_HCTX_SHARED at runtime
by Tao Liu
Though upstream kernel have defined BLK_MQ_F_TAG_HCTX_SHARED
as (1 << 3), the value might be set different, e.g. [1]. In
this patch, we will use enumerator_value() to get its value
at runtime, to make the code more adaptable.
[1]: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-8/-/blob...
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
This patch is the follow-up of [2].
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01848.html
---
dev.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dev.c b/dev.c
index 27318e8..127cf5a 100644
--- a/dev.c
+++ b/dev.c
@@ -4326,11 +4326,11 @@ struct bt_iter_data {
#define MQ_RQ_IN_FLIGHT 1
#define REQ_OP_BITS 8
#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
-#define BLK_MQ_F_TAG_HCTX_SHARED (1 << 3)
+static int blk_hctx_shared = 0;
static bool blk_mq_is_shared_tags(unsigned int flags)
{
- return flags & BLK_MQ_F_TAG_HCTX_SHARED;
+ return flags & blk_hctx_shared;
}
static uint op_is_write(uint op)
@@ -4952,6 +4952,7 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(request_queue_tag_set, "request_queue", "tag_set");
MEMBER_OFFSET_INIT(blk_mq_tag_set_flags, "blk_mq_tag_set", "flags");
MEMBER_OFFSET_INIT(blk_mq_tag_set_shared_tags, "blk_mq_tag_set", "shared_tags");
+ enumerator_value("BLK_MQ_F_TAG_HCTX_SHARED", &blk_hctx_shared);
dt->flags |= DISKIO_INIT;
}
--
2.47.0
3 weeks, 2 days