[PATCH v3 1/3] s390x: Add non-zero vmalloc_start check to s390x_vr_IS_VMALLOC_ADDR()
by Mikhail Zaslonko
Update s390x_vr_IS_VMALLOC_ADDR() to include a non-zero vmalloc_start
check, making it consistent with s390x_generic_IS_VMALLOC_ADDR().
Fixes: d0164e7e480a ("s390x: uncouple physical and virtual memory spaces")
Signed-off-by: Mikhail Zaslonko <zaslonko(a)linux.ibm.com>
---
s390x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/s390x.c b/s390x.c
index 0e8e2b3..1117bf0 100644
--- a/s390x.c
+++ b/s390x.c
@@ -724,13 +724,13 @@ static ulong s390x_vr_PTOV(ulong paddr)
{
return paddr + machdep->identity_map_base;
}
static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr)
{
- return (vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase);
+ return (vt->vmalloc_start && vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase);
}
ulong s390x_VTOP(ulong vaddr)
{
return machdep->machspec->virt_to_phys(vaddr);
}
--
2.49.0
3 days, 1 hour
Re: [PATCH v2 2/2] eppic.patch: Add customized functions to eppic
by lijiang
On Mon, Sep 29, 2025 at 12:11 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Mon, 29 Sep 2025 17:08:10 +1300
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v2 2/2] eppic.patch: Add customized
> functions to eppic
> To: devel(a)lists.crash-utility.osci.io
> Cc: jbrisson(a)linux.ibm.com
> Message-ID: <20250929040810.25718-3-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> This patch will add the following functions to eppic:
>
> 1) Allow main() as the entry for any eppic program. Previously only func()
> which companied by func_help() & func_usage() is regarded as the main
> entry of the eppic program. This constraint only makes sense for
> creating
> a crash-like cmd. If users only want to create a oneshot run program for
> fast testing, then the constraint is misleading. So this patch will add
> main() as entry for eppic programs.
>
> 2) Add new command "eppic" for oneshot run eppic programs. Previously eppic
> expect programs to run as the form of crash-like cmd, and it is not
> convenient for oneshot run programs. With "eppic" command, people can
> use "edit -f" or any other editors to create eppic programs, then run
> it via "eppic myfile.c".
>
> 3) Add a template for any new eppic program files. If "edit -f" a new
> file, a
> template with an example will be written into the new file. So users can
> refer to it when writting any eppic programs.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> extensions/eppic.mk | 13 ++-
> extensions/eppic.patch | 210 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 222 insertions(+), 1 deletion(-)
> create mode 100644 extensions/eppic.patch
>
>
I don't have much comment on this, only one thing:
For the eppic.patch, I would suggest using the same style with
gdb-16.2.patch. E.g:
...
--- gdb-16.2/gdb/c-typeprint.c.orig
+++ gdb-16.2/gdb/c-typeprint.c
@@ -1066,6 +1066,9 @@ c_type_print_base_struct_union (struct type *type,
struct ui_file *stream,
= podata->end_bitpos
- type->field (i).type ()->length () * TARGET_CHAR_BIT;
}
+ else if (strlen(type->field(i).name()) == 0)
+ /* crash: Print details for unnamed struct and union. */
+ newshow = show;
c_print_type_1 (type->field (i).type (),
type->field (i).name (),
...
(I just pasted a section from the gdb-16.2.patch)
> diff --git a/extensions/eppic.mk b/extensions/eppic.mk
> index 9435793..b175df5 100644
> --- a/extensions/eppic.mk
> +++ b/extensions/eppic.mk
> @@ -53,7 +53,18 @@ all:
> fi; \
> if [ -f $(APPFILE) ]; \
> then \
> - make -f eppic.mk eppic.so; \
> + pushd eppic >/dev/null; \
> + if patch --dry-run -N -p0 < ../eppic.patch
> >/dev/null ; then \
> + patch -N -p0 < ../eppic.patch; \
> + popd >/dev/null; \
> + make -f eppic.mk eppic.so; \
> + elif patch --dry-run -N -p0 -R <
> ../eppic.patch >/dev/null ; then \
> + popd >/dev/null; \
> + make -f eppic.mk eppic.so; \
> + else \
> + popd >/dev/null; \
> + echo "eppic.so: apply eppic.patch
> error"; \
> + fi; \
> else \
> echo "eppic.so: failed to pull eppic code
> from git repo"; \
> fi; \
> diff --git a/extensions/eppic.patch b/extensions/eppic.patch
> new file mode 100644
> index 0000000..9e43665
> --- /dev/null
> +++ b/extensions/eppic.patch
> @@ -0,0 +1,210 @@
> +--- applications/crash/eppic.c
> ++++ applications/crash/eppic.c
> +@@ -20,6 +20,7 @@
> + #include "defs.h"
> +
> + #include <eppic_api.h>
> ++#include "eppic.h"
> +
> + /*
> + * Global data (global_data.c)
> +@@ -788,6 +789,39 @@ char *sclass_help[]={
> + NULL
> + };
> +
> ++char *eppic_help[]={
> ++ "eppic",
> ++ "Run eppic program(es).",
> ++ "<fileName1.c>[, <fileName2.c>]",
> ++ " Oneshot run eppic program(es) which with a main()
> entry each.",
> ++ NULL
> ++};
> ++
> ++void
> ++eppic_command(void)
> ++{
> ++ char *buf;
> ++ optind = 1;
> ++
> ++ if (!args[optind]) {
> ++ cmd_usage(crash_global_cmd(), SYNOPSIS);
> ++ return;
> ++ }
> ++
> ++ while(args[optind]) {
> ++ buf = eppic_filempath(args[optind]);
> ++ if (!buf) {
> ++ eppic_msg("eppic_filempath error on %s\n",
> args[optind]);
> ++ return;
> ++ }
> ++ eppic_load(buf);
> ++ if (eppic_findfile(buf, 0))
> ++ eppic_unload(buf);
> ++ eppic_free(buf);
> ++ optind++;
> ++ }
> ++}
> ++
> + #define NCMDS 200
> + static struct command_table_entry command_table[NCMDS] = {
> +
> +@@ -797,6 +831,7 @@ static struct command_table_entry
> command_table[NCMDS] = {
> + {"sdebug", sdebug_cmd, sdebug_help},
> + {"sname", sname_cmd, sname_help},
> + {"sclass", sclass_cmd, sclass_help},
> ++ {"eppic", eppic_command, eppic_help},
> + {(char *)0 }
> + };
> +
> +@@ -885,6 +920,13 @@ char **help=malloc(sizeof *help * 5);
> + }
> + }
> + free(help);
> ++
> ++ if (load && !strcmp(name, "main")) {
> ++ int optind_save = optind;
> ++ eppic_cmd(name, NULL, 0);
> ++ optind = optind_save;
> ++ }
> ++
> + return;
> + }
> +
> +--- libeppic/eppic_api.h
> ++++ libeppic/eppic_api.h
> +@@ -16,6 +16,9 @@
> + /* minor and major version number
> + 4.0 switch to new Eppic name and use of fully typed symbols.
> + */
> ++#ifndef EPPIC_API_H
> ++#define EPPIC_API_H
> ++
> + #define S_MAJOR 5
> + #define S_MINOR 0
> +
> +@@ -298,3 +301,5 @@ void eppic_dbg_named(int class, char *name, int
> level, char *, ...);
> +
> + /* parsers debug flags */
> + extern int eppicdebug, eppicppdebug;
> ++
> ++#endif
> +\ No newline at end of file
> +--- libeppic/eppic_func.c
> ++++ libeppic/eppic_func.c
> +@@ -22,6 +22,8 @@
> + #include <sys/types.h>
> + #include <time.h>
> + #include <sys/stat.h>
> ++#include <fcntl.h>
> ++#include <unistd.h>
> + #include "eppic.h"
> +
> + /*
> +@@ -793,6 +795,42 @@ char *ed=getenv("EDITOR");
> + if(!system(buf)) eppic_load(fname);
> + }
> +
> ++static const char *example[] = {
> ++"/*
> ",
> ++" * Example: Print all tasks' PID & command
> ",
> ++" *
> ",
> ++" * // Kernel's global variables and data structures can be used
> directly without",
> ++" * // pre-define it in kernel header. If any are within kernel modules,
> should",
> ++" * // preload the .ko first via \"mod -S/-s\" cmd in crash before
> invoke your",
> ++" * // eppic program.
> ",
> ++" * //
> ",
> ++" * // Eppic program's syntax is similar to C but with slight
> differences. ",
> ++" * // Code samples:
> ",
> ++" * //
> https://github.com/lucchouina/eppic/tree/master/applications/crash/code",
> ++" * // Available eppic functions:
> ",
> ++" * //
> https://github.com/lucchouina/eppic/blob/master/libeppic/eppic_builtin.c#...
> ",
> ++" *
> ",
> ++" * int main(void)
> ",
> ++" * {
> ",
> ++" * struct task_struct *p;
> ",
> ++" * unsigned long offset;
> ",
> ++" *
> ",
> ++" * p = (struct task_struct *)&init_task;
> ",
> ++" * offset = (unsigned long)&(p->tasks) - (unsigned long)p;
> ",
> ++" *
> ",
> ++" * do {
> ",
> ++" * printf(\"PID: %d Command: %s\\n\", (int)(p->pid),
> getstr((char *)&(p->comm[0])));",
> ++" * p = (struct task_struct *)((unsigned long)(p->tasks.next) -
> offset);",
> ++" * } while(p != &init_task);
> ",
> ++" *
> ",
> ++" * return 0;
> ",
> ++" * }
> ",
> ++" *
> ",
> ++" * crash> eppic program_file.c
> ",
> ++" */
> ",
> ++};
>
This looks very helpful.
Thanks
Lianbo
> ++
> ++char *eppic_get_func_file(char *);
> + /*
> + This funciton is called to start a vi session on a function
> + (file=0) or a file (file=1);
> +@@ -800,24 +838,31 @@ char *ed=getenv("EDITOR");
> + void
> + eppic_vi(char *fname, int file)
> + {
> +-int line, freeit=0;
> ++int line=1, freeit=0, fd;
> + char *filename;
> ++char newline = '\n';
> +
> + if(file) {
> +
> + filename=eppic_filempath(fname);
> +
> + if(!filename) {
> +-
> +- eppic_msg("File not found : %s\n", fname);
> +- return;
> +-
> +- }
> +-
> +- line=1;
> +- freeit=1;
> +-
> +-
> ++ fd = creat(fname, 0644);
> ++ if (fd < 0) {
> ++ eppic_msg("File not found : %s\n", fname);
> ++ return;
> ++ } else {
> ++ for (int i = 0; i < sizeof(example)/sizeof(char *); i++) {
> ++ write(fd, example[i], strlen(example[i]));
> ++ write(fd, &newline, sizeof(newline));
> ++ }
> ++ close(fd);
> ++ filename = fname;
> ++ freeit=0;
> ++ }
> ++ } else {
> ++ freeit=1;
> ++ }
> + } else {
> +
> + func *f=eppic_getfbyname(fname, 0);
> +@@ -837,6 +882,10 @@ char *filename;
> +
> + eppic_exevi(filename, line);
> +
> ++ char *fi_name = eppic_get_func_file("main");
> ++ if (fi_name)
> ++ eppic_deletefile(fi_name);
> ++
> + if(freeit) eppic_free(filename);
> +
> + }
> +@@ -1184,3 +1233,10 @@ eppic_runcmd(char *fname, var_t*args)
> + return 0;
> + }
> +
> ++char *eppic_get_func_file(char *funcname)
> ++{
> ++ func *fn = eppic_getfbyname(funcname, 0);
> ++ if (!fn)
> ++ return NULL;
> ++ return fn->file->fname;
> ++}
> --
> 2.47.0
>
>
6 days, 11 hours
Re: [PATCH v2 1/2] extensions: Search all possible paths
by lijiang
Hi, Tao
Thank you for the update.
On Mon, Sep 29, 2025 at 12:11 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Mon, 29 Sep 2025 17:08:09 +1300
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v2 1/2] extensions: Search all
> possible paths
> To: devel(a)lists.crash-utility.osci.io
> Cc: jbrisson(a)linux.ibm.com
> Message-ID: <20250929040810.25718-2-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Search all possible paths for extensions. Previously if one path, e.g.
> "/usr/lib64/crash/extensions" exists, but no extensions found within,
> crash will not search any later paths, e.g. "./extensions". This patch
> will let crash continue to search any later paths.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> extensions.c | 63 ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/extensions.c b/extensions.c
> index d23b1e3..0493f19 100644
> --- a/extensions.c
> +++ b/extensions.c
> @@ -19,7 +19,7 @@
> #include <dlfcn.h>
>
> static int in_extensions_library(char *, char *);
> -static char *get_extensions_directory(char *);
> +static char *get_extensions_directory(char *, bool *);
> static void show_all_extensions(void);
> static void show_extensions(char *);
>
> @@ -395,32 +395,33 @@ in_extensions_library(char *lib, char *buf)
> * Look for an extensions directory using the proper order.
> */
> static char *
> -get_extensions_directory(char *dirbuf)
> +get_extensions_directory(char *dirbuf, bool *end)
> {
> - char *env;
> + static int index = 0;
> + char *dirs[] = {
> + getenv("CRASH_EXTENSIONS"),
> + "/usr/lib64/crash/extensions",
> + "/usr/lib/crash/extensions",
> + "./extensions",
> + };
> + char *dir;
>
> - if ((env = getenv("CRASH_EXTENSIONS"))) {
> - if (is_directory(env)) {
> - strcpy(dirbuf, env);
> - return dirbuf;
> - }
> +retry:
> + if (index >= sizeof(dirs) / sizeof(char *)) {
> + *end = true;
> + return NULL;
> }
> -
> - if (BITS64()) {
> - sprintf(dirbuf, "/usr/lib64/crash/extensions");
> - if (is_directory(dirbuf))
> - return dirbuf;
> + *end = false;
> + dir = dirs[index++];
> + if (is_directory(dir)) {
> + if (!BITS64() && strstr(dir, "lib64")) {
> + goto retry;
> + }
> + snprintf(dirbuf, BUFSIZE - 1, "%s", dir);
> + return dir;
> + } else {
> + return NULL;
> }
> -
> - sprintf(dirbuf, "/usr/lib/crash/extensions");
> - if (is_directory(dirbuf))
> - return dirbuf;
> -
> - sprintf(dirbuf, "./extensions");
> - if (is_directory(dirbuf))
> - return dirbuf;
> -
> - return NULL;
> }
>
> The above code attempts to use a goto loop, this is hard to understand and
debug.
I refactored the original get_extensions_directory() as below, but I
haven't tested it. Can you try it?
+static char* get_extensions_directory(char *dirbuf, size_t sz)
+{
+ const char *dirs[] = {
+ getenv("CRASH_EXTENSIONS"),
+ BITS64() ? "/usr/lib64/crash/extensions" :
"/usr/lib/crash/extensions",
+ "./extensions",
+ NULL
+ };
+
+ for (const char **p = dirs; *p; ++p) {
+ if (is_directory(*p)) {
+ snprintf(dirbuf, sz, "%s", *p);
+ return dirbuf;
+ }
+ }
+ return NULL;
+}
And also modify the is_directory(), for example:
int
-is_directory(char *file)
+is_directory(const char *file)
{
struct stat sbuf;
Anyway I'm still not sure if that can meet your needs.
Thanks
Lianbo
> @@ -432,14 +433,20 @@ preload_extensions(void)
> char dirbuf[BUFSIZE];
> char filename[BUFSIZE*2];
> int found;
> + bool end;
>
> - if (!get_extensions_directory(dirbuf))
> - return;
> +next_dir:
> + if (!get_extensions_directory(dirbuf, &end)) {
> + if (end)
> + return;
> + else
> + goto next_dir;
> + }
>
> dirp = opendir(dirbuf);
> if (!dirp) {
> error(INFO, "%s: %s\n", dirbuf, strerror(errno));
> - return;
> + goto next_dir;
> }
>
> pc->curcmd = pc->program_name;
> @@ -461,10 +468,12 @@ preload_extensions(void)
>
> if (found)
> fprintf(fp, "\n");
> - else
> + else {
> error(NOTE,
> "%s: no extension modules found in directory\n\n",
> dirbuf);
> + goto next_dir;
> + }
> }
>
> /*
> --
> 2.47.0
>
6 days, 11 hours
[PATCH v3] Add "log -R" to display human readable Rust symbol name
by Lianbo Jiang
Currently, the log command will display human readable Rust
symbol name by default if any, but, sometimes still want to
print the original messages from the log buffer(do not demangle).
In addition, if the log buffer has lines like "_R ... +" which
are not Rust symbols unexpectedly, probably the output will be
missed, that is unexpected.
To fix above cases, add "log -R" to display human readable Rust
symbol name, otherwise still print the original messages.
With the patch:
crash> log -R
...
[ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS SE5C610.86B.01.01.0018.072020161249 07/20/2016
[ 2174.308966] Call Trace:
[ 2174.311693] <TASK>
[ 2174.314033] dump_stack_lvl+0x5d/0x80
[ 2174.318125] panic+0x156/0x32a
[ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]
[ 2174.329700] ? console_unlock+0x9c/0x140
[ 2174.334080] ? irq_work_queue+0x2d/0x50
[ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]
[ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0 [rust_panic]
[ 2174.353698] ? _printk+0x6b/0x90
[ 2174.357303] init_module+0x57/0xff0 [rust_panic]
[ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]
...
Suggested-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
defs.h | 1 +
help.c | 24 ++++++++++++++++++-
kernel.c | 5 +++-
printk.c | 71 ++++++++++++++++++++++++++++++++++----------------------
4 files changed, 71 insertions(+), 30 deletions(-)
diff --git a/defs.h b/defs.h
index 3fd7d897c781..c434a5cae702 100644
--- a/defs.h
+++ b/defs.h
@@ -6229,6 +6229,7 @@ void parse_kernel_version(char *);
#define SHOW_LOG_CTIME (0x10)
#define SHOW_LOG_SAFE (0x20)
#define SHOW_LOG_CALLER (0x40)
+#define SHOW_LOG_RUST (0x80)
void set_cpu(int);
void clear_machdep_cache(void);
struct stack_hook *gather_text_list(struct bt_info *);
diff --git a/help.c b/help.c
index 4f071e0bd0a0..78d7a5c70e30 100644
--- a/help.c
+++ b/help.c
@@ -4026,7 +4026,7 @@ NULL
char *help_log[] = {
"log",
"dump system message buffer",
-"[-Ttdmasc]",
+"[-TtdmascR]",
" This command dumps the kernel log_buf contents in chronological order. The",
" command supports the older log_buf formats, which may or may not contain a",
" timestamp inserted prior to each message, as well as the newer variable-length",
@@ -4053,6 +4053,8 @@ char *help_log[] = {
" the CPU id (if in CPU context) that called printk(), if available.",
" Generally available on Linux 5.1 to 5.9 kernels configured with",
" CONFIG_PRINTK_CALLER or Linux 5.10 and later kernels.",
+" -R Display the message text with human readable Rust symbol name if any,",
+" otherwise still print the original message text.",
" ",
"\nEXAMPLES",
" Dump the kernel message buffer:\n",
@@ -4231,6 +4233,26 @@ char *help_log[] = {
" [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
" [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3",
" ...",
+" ",
+" Display the message text with human readable Rust symbol name if any,",
+" otherwise still print the original message text.\n",
+" %s> log -R",
+" ...",
+" [ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE",
+" [ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS SE5C610.86B.01.01.0018.072020161249 07/20/2016",
+" [ 2174.308966] Call Trace:",
+" [ 2174.311693] <TASK>",
+" [ 2174.314033] dump_stack_lvl+0x5d/0x80",
+" [ 2174.318125] panic+0x156/0x32a",
+" [ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]",
+" [ 2174.329700] ? console_unlock+0x9c/0x140",
+" [ 2174.334080] ? irq_work_queue+0x2d/0x50",
+" [ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" [ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0 [rust_panic]",
+" [ 2174.353698] ? _printk+0x6b/0x90",
+" [ 2174.357303] init_module+0x57/0xff0 [rust_panic]",
+" [ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" ...",
NULL
};
diff --git a/kernel.c b/kernel.c
index e4213d7a663e..e077275d7ed6 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5136,7 +5136,7 @@ cmd_log(void)
msg_flags = 0;
- while ((c = getopt(argcnt, args, "Ttdmasc")) != EOF) {
+ while ((c = getopt(argcnt, args, "TtdmascR")) != EOF) {
switch(c)
{
case 'T':
@@ -5160,6 +5160,9 @@ cmd_log(void)
case 'c':
msg_flags |= SHOW_LOG_CALLER;
break;
+ case 'R':
+ msg_flags |= SHOW_LOG_RUST;
+ break;
default:
argerrs++;
break;
diff --git a/printk.c b/printk.c
index 51b618e2a434..f7346f4c1c1d 100644
--- a/printk.c
+++ b/printk.c
@@ -116,7 +116,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
uint64_t ts_nsec;
ulonglong nanos;
ulonglong seq;
- int ilen = 0, i;
+ int ilen = 0, i, nlines;
char *desc, *info, *text, *p;
ulong rem;
@@ -202,44 +202,59 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
text = m->text_data + begin;
- if (text_len > BUFSIZE) {
+ if ((msg_flags & SHOW_LOG_RUST) && (text_len > BUFSIZE)) {
error(WARNING, "\nThe messages could be truncated!\n");
text_len = BUFSIZE;
}
- for (i = 0, p = text; i < text_len; i++, p++) {
- if (*p == '\n')
+ for (i = 0, nlines = 0, p = text; i < text_len; i++, p++) {
+ if (*p == '\n') {
+ if ((msg_flags & SHOW_LOG_RUST) && (i != text_len - 1)) {
+ nlines++;
+ if (strlen(buf)) {
+ fprintf(fp, "%s", buf);
+ memset(buf, 0, strlen(buf));
+ }
+ }
fprintf(fp, "\n%s", space(ilen));
- else if (isprint(*p) || isspace(*p))
- sprintf(&buf[i], "%c", *p);
+ } else if ((msg_flags & SHOW_LOG_RUST) && (isprint(*p) || isspace(*p))) {
+ if (nlines >= 1)
+ fputc(*p, fp);
+ else
+ sprintf(&buf[i], "%c", *p);
+ } else if (isprint(*p) || isspace(*p))
+ fputc(*p, fp);
else
fputc('.', fp);
}
/*
* Try to demangle a mangled Rust symbol(calltrace) from log buffer
*/
- char *p1 = strstr(buf, "_R");
- if (!p1)
- p1 = strstr(buf, "_ZN");
- char *p2 = strrchr(buf, '+');
- if (p1 && p2) {
- char mangled[BUFSIZE] = {0};
- char demangled[BUFSIZE] = {0};
- char *res;
- size_t slen = p1 - buf;
-
- if (slen)
- memcpy(demangled, buf, slen);
-
- memcpy(mangled, p1, p2-p1);
- res = rust_demangle(mangled, DMGL_RUST);
- if (res) {
- snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
- fprintf(fp, "%s",demangled);
- free(res);
- }
- } else
- fprintf(fp, "%s", buf);
+ if (msg_flags & SHOW_LOG_RUST) {
+ char *p1 = strstr(buf, "_R");
+ if (!p1)
+ p1 = strstr(buf, "_ZN");
+ char *p2 = strrchr(buf, '+');
+ if (p1 && p2) {
+ char mangled[BUFSIZE] = {0};
+ char demangled[BUFSIZE] = {0};
+ char *res;
+ size_t slen = p1 - buf;
+
+ if (slen)
+ memcpy(demangled, buf, slen);
+
+ memcpy(mangled, p1, p2-p1);
+ res = rust_demangle(mangled, DMGL_RUST);
+ if (res) {
+ snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
+ fprintf(fp, "%s",demangled);
+ free(res);
+ } else
+ fprintf(fp, "%s", buf);
+ } else
+ fprintf(fp, "%s", buf);
+ }
if (msg_flags & SHOW_LOG_DICT) {
text = info + OFFSET(printk_info_dev_info) +
--
2.50.1
6 days, 17 hours
[PATCH v2] Add "log -R" to display human readable Rust symbol name
by Lianbo Jiang
Currently, the log command will display human readable Rust
symbol name by default if any, but, sometimes still want to
print the original messages from the log buffer(do not demangle).
In addition, if the log buffer has lines like "_R ... +" which
are not Rust symbols unexpectedly, probably the output will be
missed, that is unexpected.
To fix above cases, add "log -R" to display human readable Rust
symbol name, otherwise still print the original messages.
With the patch:
crash> log -R
...
[ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS SE5C610.86B.01.01.0018.072020161249 07/20/2016
[ 2174.308966] Call Trace:
[ 2174.311693] <TASK>
[ 2174.314033] dump_stack_lvl+0x5d/0x80
[ 2174.318125] panic+0x156/0x32a
[ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]
[ 2174.329700] ? console_unlock+0x9c/0x140
[ 2174.334080] ? irq_work_queue+0x2d/0x50
[ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]
[ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0 [rust_panic]
[ 2174.353698] ? _printk+0x6b/0x90
[ 2174.357303] init_module+0x57/0xff0 [rust_panic]
[ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]
...
Suggested-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
defs.h | 1 +
help.c | 24 +++++++++++++++++++++++-
kernel.c | 5 ++++-
printk.c | 53 +++++++++++++++++++++++++++++------------------------
4 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/defs.h b/defs.h
index 156ac0232906..997145cba9d2 100644
--- a/defs.h
+++ b/defs.h
@@ -6227,6 +6227,7 @@ void parse_kernel_version(char *);
#define SHOW_LOG_CTIME (0x10)
#define SHOW_LOG_SAFE (0x20)
#define SHOW_LOG_CALLER (0x40)
+#define SHOW_LOG_RUST (0x80)
void set_cpu(int);
void clear_machdep_cache(void);
struct stack_hook *gather_text_list(struct bt_info *);
diff --git a/help.c b/help.c
index 4f071e0bd0a0..78d7a5c70e30 100644
--- a/help.c
+++ b/help.c
@@ -4026,7 +4026,7 @@ NULL
char *help_log[] = {
"log",
"dump system message buffer",
-"[-Ttdmasc]",
+"[-TtdmascR]",
" This command dumps the kernel log_buf contents in chronological order. The",
" command supports the older log_buf formats, which may or may not contain a",
" timestamp inserted prior to each message, as well as the newer variable-length",
@@ -4053,6 +4053,8 @@ char *help_log[] = {
" the CPU id (if in CPU context) that called printk(), if available.",
" Generally available on Linux 5.1 to 5.9 kernels configured with",
" CONFIG_PRINTK_CALLER or Linux 5.10 and later kernels.",
+" -R Display the message text with human readable Rust symbol name if any,",
+" otherwise still print the original message text.",
" ",
"\nEXAMPLES",
" Dump the kernel message buffer:\n",
@@ -4231,6 +4233,26 @@ char *help_log[] = {
" [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
" [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3",
" ...",
+" ",
+" Display the message text with human readable Rust symbol name if any,",
+" otherwise still print the original message text.\n",
+" %s> log -R",
+" ...",
+" [ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE",
+" [ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS SE5C610.86B.01.01.0018.072020161249 07/20/2016",
+" [ 2174.308966] Call Trace:",
+" [ 2174.311693] <TASK>",
+" [ 2174.314033] dump_stack_lvl+0x5d/0x80",
+" [ 2174.318125] panic+0x156/0x32a",
+" [ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]",
+" [ 2174.329700] ? console_unlock+0x9c/0x140",
+" [ 2174.334080] ? irq_work_queue+0x2d/0x50",
+" [ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" [ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0 [rust_panic]",
+" [ 2174.353698] ? _printk+0x6b/0x90",
+" [ 2174.357303] init_module+0x57/0xff0 [rust_panic]",
+" [ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" ...",
NULL
};
diff --git a/kernel.c b/kernel.c
index e4213d7a663e..e077275d7ed6 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5136,7 +5136,7 @@ cmd_log(void)
msg_flags = 0;
- while ((c = getopt(argcnt, args, "Ttdmasc")) != EOF) {
+ while ((c = getopt(argcnt, args, "TtdmascR")) != EOF) {
switch(c)
{
case 'T':
@@ -5160,6 +5160,9 @@ cmd_log(void)
case 'c':
msg_flags |= SHOW_LOG_CALLER;
break;
+ case 'R':
+ msg_flags |= SHOW_LOG_RUST;
+ break;
default:
argerrs++;
break;
diff --git a/printk.c b/printk.c
index 51b618e2a434..b8fcc8e58160 100644
--- a/printk.c
+++ b/printk.c
@@ -202,7 +202,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
text = m->text_data + begin;
- if (text_len > BUFSIZE) {
+ if ((msg_flags & SHOW_LOG_RUST) && (text_len > BUFSIZE)) {
error(WARNING, "\nThe messages could be truncated!\n");
text_len = BUFSIZE;
}
@@ -210,36 +210,41 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
for (i = 0, p = text; i < text_len; i++, p++) {
if (*p == '\n')
fprintf(fp, "\n%s", space(ilen));
- else if (isprint(*p) || isspace(*p))
+ else if ((msg_flags & SHOW_LOG_RUST) && (isprint(*p) || isspace(*p)))
sprintf(&buf[i], "%c", *p);
+ else if (isprint(*p) || isspace(*p))
+ fputc(*p, fp);
else
fputc('.', fp);
}
/*
* Try to demangle a mangled Rust symbol(calltrace) from log buffer
*/
- char *p1 = strstr(buf, "_R");
- if (!p1)
- p1 = strstr(buf, "_ZN");
- char *p2 = strrchr(buf, '+');
- if (p1 && p2) {
- char mangled[BUFSIZE] = {0};
- char demangled[BUFSIZE] = {0};
- char *res;
- size_t slen = p1 - buf;
-
- if (slen)
- memcpy(demangled, buf, slen);
-
- memcpy(mangled, p1, p2-p1);
- res = rust_demangle(mangled, DMGL_RUST);
- if (res) {
- snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
- fprintf(fp, "%s",demangled);
- free(res);
- }
- } else
- fprintf(fp, "%s", buf);
+ if (msg_flags & SHOW_LOG_RUST) {
+ char *p1 = strstr(buf, "_R");
+ if (!p1)
+ p1 = strstr(buf, "_ZN");
+ char *p2 = strrchr(buf, '+');
+ if (p1 && p2) {
+ char mangled[BUFSIZE] = {0};
+ char demangled[BUFSIZE] = {0};
+ char *res;
+ size_t slen = p1 - buf;
+
+ if (slen)
+ memcpy(demangled, buf, slen);
+
+ memcpy(mangled, p1, p2-p1);
+ res = rust_demangle(mangled, DMGL_RUST);
+ if (res) {
+ snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
+ fprintf(fp, "%s",demangled);
+ free(res);
+ } else
+ fprintf(fp, "%s", buf);
+ } else
+ fprintf(fp, "%s", buf);
+ }
if (msg_flags & SHOW_LOG_DICT) {
text = info + OFFSET(printk_info_dev_info) +
--
2.50.1
1 week, 1 day
Re: [PATCH] Optimize extensions's compiler from gcc to $(CC)
by lijiang
Hi, Jianyun
Thank you for the patch.
On Fri, Sep 26, 2025 at 7:27 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Tue, 23 Sep 2025 21:43:38 +0800
> From: 高建云 <jianyungao89(a)gmail.com>
> Subject: [Crash-utility] [PATCH] Optimize extensions's compiler from
> gcc to $(CC)
> To: devel(a)lists.crash-utility.osci.io
> Message-ID:
> <
> CAHP3+4CZqDNh5LV5DgY0HLfB_MQPqAU0PzoZZTfk9Kfvz+BHJA(a)mail.gmail.com>
> Content-Type: multipart/alternative;
> boundary="00000000000043dcaa063f782098"
>
> --00000000000043dcaa063f782098
> Content-Type: text/plain; charset="UTF-8"
>
> Change the default compiler of the extensions from the fixed gcc
> to $(CC) passed in by the upper layer Makefile,
> to facilitate cross_compile.
>
> Signed-off-by: jianyun.gao <jianyungao89(a)gmail.com>
> ---
> Makefile | 2 +-
> extensions/Makefile | 10 +++++-----
> 2 files changed, 6 insertions(+), 6 deletions(-)
>
>
I tried the patch, and this caused the following failure, can you help
double check?
$ make CROSS_COMPILE=aarch64-linux-gnu- extensions
aarch64-linux-gnu-gcc -Wall -g -shared -rdynamic -o dminfo.so dminfo.c
-fPIC -DARM64 -DGDB_16_2
aarch64-linux-gnu-gcc -Wall -g -shared -rdynamic -o echo.so echo.c -fPIC
-DARM64 -DGDB_16_2
Cloning into 'eppic'...
remote: Enumerating objects: 691, done.
remote: Counting objects: 100% (210/210), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 691 (delta 150), reused 165 (delta 124), pack-reused 481
(from 1)
Receiving objects: 100% (691/691), 318.81 KiB | 312.00 KiB/s, done.
Resolving deltas: 100% (372/372), done.
cd eppic/libeppic && make
bison -peppic -v -t -d eppic.y
eppic.y: warning: 135 shift/reduce conflicts [-Wconflicts-sr]
eppic.y: warning: 22 reduce/reduce conflicts [-Wconflicts-rr]
eppic.y: note: rerun with option '-Wcounterexamples' to generate conflict
counterexamples
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_util.o eppic_util.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_node.o eppic_node.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_var.o eppic_var.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_func.o eppic_func.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_str.o eppic_str.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_op.o eppic_op.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_num.o eppic_num.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_stat.o eppic_stat.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_builtin.o eppic_builtin.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_type.o eppic_type.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_case.o eppic_case.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_api.o eppic_api.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_member.o eppic_member.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_alloc.o eppic_alloc.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_define.o eppic_define.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_input.o eppic_input.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c -o
eppic_print.o eppic_print.c
bison -peppicpp -v -t -d eppicpp.y
eppicpp.y: warning: 23 shift/reduce conflicts [-Wconflicts-sr]
eppicpp.y: note: rerun with option '-Wcounterexamples' to generate conflict
counterexamples
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c eppicpp.tab.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c eppic.tab.c
flex -L -Peppic -t eppic.l > lex.eppic.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c lex.eppic.c
flex -Peppicpp -t eppicpp.l > lex.eppicpp.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c lex.eppicpp.c
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -o mkbaseop
mkbaseop.c
./mkbaseop > baseops.c
/bin/sh: 1: ./mkbaseop: Exec format error
make[5]: [Makefile:71: baseops.o] Error 126 (ignored)
aarch64-linux-gnu-gcc -g -O0 -fno-omit-frame-pointer -fPIC -c baseops.c
ar cur libeppic.a eppic_util.o eppic_node.o eppic_var.o eppic_func.o
eppic_str.o eppic_op.o eppic_num.o eppic_stat.o eppic_builtin.o
eppic_type.o eppic_case.o eppic_api.o eppic_member.o eppic_alloc.o
eppic_define.o eppic_input.o eppic_print.o eppicpp.tab.o eppic.tab.o
lex.eppic.o lex.eppicpp.o baseops.o
ar: `u' modifier ignored since `D' is the default (see `U')
gcc -g -O0 -Ieppic/libeppic -I.. -nostartfiles -shared -rdynamic -o
eppic.so eppic/applications/crash/eppic.c -fPIC -DARM64 -DGDB_16_2
-Leppic/libeppic -leppic
/usr/bin/ld: skipping incompatible eppic/libeppic/libeppic.a when searching
for -leppic
/usr/bin/ld: cannot find -leppic: No such file or directory
collect2: error: ld returned 1 exit status
make[4]: [eppic.mk:71: eppic.so] Error 1 (ignored)
gcc -Wall -g -I. -shared -rdynamic -o snap.so snap.c -fPIC -DARM64
-DGDB_16_2
But for the trace and gcore, etc. It can work.
Thanks
Lianbo
> diff --git a/Makefile b/Makefile
> index b277129..58b1326 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -727,7 +727,7 @@ extensions: make_configure
> @$(MAKE) do_extensions
>
> do_extensions:
> - @$(MAKE) -C extensions -i TARGET=$(TARGET) TARGET_CFLAGS="$(CFLAGS)
> $(TARGET_CFLAGS)" GDB=$(GDB) GDB_FLAGS=$(GDB_FLAGS)
> + @$(MAKE) -C extensions -i CC=$(CC) TARGET=$(TARGET)
> TARGET_CFLAGS="$(CFLAGS) $(TARGET_CFLAGS)" GDB=$(GDB)
> GDB_FLAGS=$(GDB_FLAGS)
>
> memory_driver: make_configure
> @$(MAKE) -C memory_driver -i
> diff --git a/extensions/Makefile b/extensions/Makefile
> index e4c68c3..67d3839 100644
> --- a/extensions/Makefile
> +++ b/extensions/Makefile
> @@ -23,7 +23,7 @@
> # suffice, create a .mk file with the same prefix as the .c file,
> # and that makefile will be invoked.
> #
> -
> +CC ?= gcc
> CONTRIB_SO := $(patsubst %.c,%.so,$(wildcard *.c))
>
> all: link_defs $(CONTRIB_SO)
> @@ -37,11 +37,11 @@ $(CONTRIB_SO): %.so: %.c defs.h
> $(MAKE) -f $*.mk; \
> else \
> grep -q '((constructor))' $*.c && { \
> - echo "gcc -Wall -g -shared -rdynamic -o $@ $*.c -fPIC
> -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS)"; \
> - gcc -Wall -g -shared -rdynamic -o $@ $*.c -fPIC -D$(TARGET)
> $(TARGET_CFLAGS) $(GDB_FLAGS); \
> + echo "$(CC) -Wall -g -shared -rdynamic -o $@ $*.c -fPIC
> -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS)"; \
> + $(CC) -Wall -g -shared -rdynamic -o $@ $*.c -fPIC -D$(TARGET)
> $(TARGET_CFLAGS) $(GDB_FLAGS); \
> } || { \
> - echo "gcc -Wall -g -nostartfiles -shared -rdynamic -o $@ $*.c
> -fPIC -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS)"; \
> - gcc -Wall -g -nostartfiles -shared -rdynamic -o $@ $*.c -fPIC
> -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS); \
> + echo "$(CC) -Wall -g -nostartfiles -shared -rdynamic -o $@ $*.c
> -fPIC -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS)"; \
> + $(CC) -Wall -g -nostartfiles -shared -rdynamic -o $@ $*.c -fPIC
> -D$(TARGET) $(TARGET_CFLAGS) $(GDB_FLAGS); \
> }; \
> fi
>
> --
> 2.34.1
>
>
1 week, 1 day
Re: [PATCH v2 2/2] s390x: Always perform kernel address translation in vtop verbose mode
by Mikhail Zaslonko
On 10/20/2025 2:27 PM, Alexander Gordeev wrote:
> On Fri, Oct 17, 2025 at 01:26:41PM +0200, Mikhail Zaslonko wrote:
>> In s390x_kvtop() early return may take place despite the verbose
>> flag. Thus we can miss page-table walk information in the vtop output
>> for kernel virtual addresses.
>> Make sure that s390x_vtop() is always called for kernel virtual addresses
>> when the verbose flag is passed to s390x_kvtop() by do_vtop().
>>
>> Suggested-by: Heiko Carstens <hca(a)linux.ibm.com>
>> Signed-off-by: Mikhail Zaslonko <zaslonko(a)linux.ibm.com>
>> ---
>> s390x.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/s390x.c b/s390x.c
>> index 25dca5e..77d9082 100644
>> --- a/s390x.c
>> +++ b/s390x.c
>> @@ -943,15 +943,15 @@ s390x_kvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose
>>
>> if (!IS_KVADDR(vaddr)){
>> *paddr = 0;
>> return FALSE;
>> }
>>
>> - if (!IS_VMALLOC_ADDR(vaddr)) {
>> - *paddr = VTOP(vaddr);
>> - return TRUE;
>> + if (!verbose && !IS_VMALLOC_ADDR(vaddr)) {
>> + *paddr = VTOP(vaddr);
>> + return TRUE;
>
> Few other architectures do it like this:
>
> if (!vt->vmalloc_start) {
> *paddr = VTOP(kvaddr);
> return TRUE;
> }
> if (!IS_VMALLOC_ADDR(kvaddr)) {
> *paddr = VTOP(kvaddr);
> if (!verbose)
> return TRUE;
> }
>
> Would it work for s390x?
It would, but does it make sense updating *paddr value for non-verbose case prior to
calling s390x_vtop() where we set it back to zero at the very start (see below).
Do you think we should just try keeping the code similar to other architectures?
/* lookup virtual address in page tables */
int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose)
{
ulong entry, paddr;
int level, len;
if (verbose)
fprintf(fp, "PAGE DIRECTORY: %016lx\n", table);
*phys_addr = 0;
>
>> }
>>
>> pgd_base = (unsigned long)vt->kernel_pgd[0];
>> return s390x_vtop(pgd_base, vaddr, paddr, verbose);
>> }
>
> Thanks!
1 week, 3 days
Re: [PATCH v2 1/2] s390x: Add non-zero vmalloc_start check to s390x_vr_IS_VMALLOC_ADDR()
by Mikhail Zaslonko
On 10/20/2025 2:25 PM, Alexander Gordeev wrote:
> On Fri, Oct 17, 2025 at 01:26:40PM +0200, Mikhail Zaslonko wrote:
>
> Hi Mikhail,
>
> Could you please clarify why these are not two separate commits?
You might be right. It makes sense splitting this commit in two.
>
>> - Update s390x_vr_IS_VMALLOC_ADDR() to include a non-zero vmalloc_start
>> check, making it consistent with s390x_generic_IS_VMALLOC_ADDR().
>
> This one looks as a bug fix to me.
>
>> - Remove redundant vmalloc_start check from s390x_kvtop().
>
> And this one is a follow-up optimization, unless there was
> a reason for this check before commit d0164e7 ("s390x: uncouple
> physical and virtual memory spaces"). Do you have any ideas?
I don't see a reason for this check as soon as IS_VMALLOC_ADDR() comprises
this check for s390x. I think it could come from kvtop implementation for other
architectures indeed.
>
>> Signed-off-by: Mikhail Zaslonko <zaslonko(a)linux.ibm.com>
>> ---
>> s390x.c | 7 +------
>> 1 file changed, 1 insertion(+), 6 deletions(-)
>
> Thanks!
Thanks for taking a look!
1 week, 3 days
[PATCH RFC][makedumpfile 00/10] btf/kallsyms based eppic extension for mm page filtering
by Tao Liu
A) This patchset will introduce the following features to makedumpfile:
1) Enable eppic script for memory pages filtering.
2) Enable btf and kallsyms for symbol type and address resolving.
3) Port maple tree data structures and functions, primarily used for
vma iteration.
B) The purpose of the features are:
1) Currently makedumpfile filters mm pages based on page flags, because flags
can help to determine one page's usage. But this page-flag-checking method
lacks of flexibility in certain cases, e.g. if we want to filter those mm
pages occupied by GPU during vmcore dumping due to:
a) GPU may be taking a large memory and contains sensitive data;
b) GPU mm pages have no relations to kernel crash and useless for vmcore
analysis.
But there is no GPU mm page specific flags, and apparently we don't need
to create one just for kdump use. A programmable filtering tool is more
suitable for such cases. In addition, different GPU vendors may use
different ways for mm pages allocating, programmable filtering is better
than hard coding these GPU specific logics into makedumpfile in this case.
2) Currently makedumpfile already contains a programmable filtering tool, aka
eppic script, which allows user to write customized code for data erasing.
However it has the following drawbacks:
a) cannot do mm page filtering.
b) need to access to debuginfo of both kernel and modules, which is not
applicable in the 2nd kernel.
c) Poor performance, making vmcore dumping time unacceptable (See
the following performance testing).
makedumpfile need to resolve the dwarf data from debuginfo, to get symbols
types and addresses. In recent kernel there are dwarf alternatives such
as btf/kallsyms which can be used for this purpose. And btf/kallsyms info
are already packed within vmcore, so we can use it directly.
3) Maple tree data structures are used in recent kernels, such as vma
iteration. So maple tree poring is needed.
With these, this patchset introduces an upgraded eppic, which is based on
btf/kallsyms symbol resolving, and is programmable for mm page filtering.
The following info shows its usage and performance, please note the tests
are performed in 1st kernel:
$ time ./makedumpfile -d 31 -l /var/crash/127.0.0.1-2025-06-10-18\:03\:12/vmcore
/tmp/dwarf.out -x /lib/debug/lib/modules/6.11.8-300.fc41.x86_64/vmlinux
--eppic eppic_scripts/filter_amdgpu_mm_pages.c
real 14m6.894s
user 4m16.900s
sys 9m44.695s
$ time ./makedumpfile -d 31 -l /var/crash/127.0.0.1-2025-06-10-18\:03\:12/vmcore
/tmp/btf.out --eppic eppic_scripts/filter_amdgpu_mm_pages.c
real 0m10.672s
user 0m9.270s
sys 0m1.130s
-rw------- 1 root root 367475074 Jun 10 18:06 btf.out
-rw------- 1 root root 367475074 Jun 10 21:05 dwarf.out
-rw-rw-rw- 1 root root 387181418 Jun 10 18:03 /var/crash/127.0.0.1-2025-06-10-18:03:12/vmcore
C) Discussion:
1) GPU types: Currently only tested with amdgpu's mm page filtering, others
are not tested.
2) Code structure: There are some similar code shared by makedumpfile and
crash, such as maple tree data structure, also I planed to port the
btf/kallsyms code to crash as well, so there are code duplications for
crash & makedumpfile. Since I havn't working on crash poring, code change
on btf/kallsyms is expected. How can we share the code, creating a common
library or keep the duplication as it is?
3) OS: The code can work on rhel-10+/rhel9.5+ on x86_64/arm64/s390/ppc64.
Others are not tested.
D) Testing:
1) If you don't want to create your vmcore, you can find a vmcore which I
created with amdgpu mm pages unfiltered [1], the amdgpu mm pages are
allocated by program [2]. You can use the vmcore in 1st kernel to filter
the amdgpu mm pages by the previous performance testing cmdline. To
verify the pages are filtered in crash:
Unfiltered:
crash> search -c "!QAZXSW@#EDC"
ffff96b7fa800000: !QAZXSW@#EDCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ffff96b87c800000: !QAZXSW@#EDCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
crash> rd ffff96b7fa800000
ffff96b7fa800000: 405753585a415121 !QAZXSW@
crash> rd ffff96b87c800000
ffff96b87c800000: 405753585a415121 !QAZXSW@
Filtered:
crash> search -c "!QAZXSW@#EDC"
crash> rd ffff96b7fa800000
rd: page excluded: kernel virtual address: ffff96b7fa800000 type: "64-bit KVADDR"
crash> rd ffff96b87c800000
rd: page excluded: kernel virtual address: ffff96b87c800000 type: "64-bit KVADDR"
2) You can use eppic_scripts/print_all_vma.c against an ordinary vmcore to
test only btf/kallsyms functions by output all VMAs if no amdgpu
vmcores/machine avaliable.
[1]: https://people.redhat.com/~ltao/core/
[2]: https://gist.github.com/liutgnu/a8cbce1c666452f1530e1410d1f352df
Tao Liu (10):
dwarf_info: Support kernel address randomization
dwarf_info: Fix a infinite recursion bug for search_domain
Add page filtering function
Add btf/kallsyms support for symbol type/address resolving
Export necessary btf/kallsyms functions to eppic extension
Port the maple tree data structures and functions
Supporting main() as the entry of eppic script
Enable page filtering for dwarf eppic
Enable page filtering for btf/kallsyms eppic
Introducing 2 eppic scripts to test the dwarf/btf eppic extension
Makefile | 6 +-
btf.c | 919 +++++++++++++++++++++++++
btf.h | 176 +++++
dwarf_info.c | 15 +-
eppic_maple.c | 431 ++++++++++++
eppic_maple.h | 8 +
eppic_scripts/filter_amdgpu_mm_pages.c | 36 +
eppic_scripts/print_all_vma.c | 29 +
erase_info.c | 123 +++-
erase_info.h | 22 +
extension_btf.c | 218 ++++++
extension_eppic.c | 41 +-
extension_eppic.h | 6 +-
kallsyms.c | 371 ++++++++++
kallsyms.h | 42 ++
makedumpfile.c | 21 +-
makedumpfile.h | 11 +
17 files changed, 2448 insertions(+), 27 deletions(-)
create mode 100644 btf.c
create mode 100644 btf.h
create mode 100644 eppic_maple.c
create mode 100644 eppic_maple.h
create mode 100644 eppic_scripts/filter_amdgpu_mm_pages.c
create mode 100644 eppic_scripts/print_all_vma.c
create mode 100644 extension_btf.c
create mode 100644 kallsyms.c
create mode 100644 kallsyms.h
--
2.47.0
1 week, 3 days
[PATCH v2 1/2] s390x: Add non-zero vmalloc_start check to s390x_vr_IS_VMALLOC_ADDR()
by Mikhail Zaslonko
- Update s390x_vr_IS_VMALLOC_ADDR() to include a non-zero vmalloc_start
check, making it consistent with s390x_generic_IS_VMALLOC_ADDR().
- Remove redundant vmalloc_start check from s390x_kvtop().
Signed-off-by: Mikhail Zaslonko <zaslonko(a)linux.ibm.com>
---
s390x.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/s390x.c b/s390x.c
index 0e8e2b3..25dca5e 100644
--- a/s390x.c
+++ b/s390x.c
@@ -724,13 +724,13 @@ static ulong s390x_vr_PTOV(ulong paddr)
{
return paddr + machdep->identity_map_base;
}
static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr)
{
- return (vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase);
+ return (vt->vmalloc_start && vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase);
}
ulong s390x_VTOP(ulong vaddr)
{
return machdep->machspec->virt_to_phys(vaddr);
}
@@ -943,17 +943,12 @@ s390x_kvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose
if (!IS_KVADDR(vaddr)){
*paddr = 0;
return FALSE;
}
- if (!vt->vmalloc_start) {
- *paddr = VTOP(vaddr);
- return TRUE;
- }
-
if (!IS_VMALLOC_ADDR(vaddr)) {
*paddr = VTOP(vaddr);
return TRUE;
}
pgd_base = (unsigned long)vt->kernel_pgd[0];
--
2.49.0
1 week, 6 days