Re: [Crash-utility] [PATCH v4 2/4] Get the absolute value of SYMNAME_HASH_INDEX
by lijiang
> > > Currently, the macro is used twice in the symbols.c. This change seems
> > > not complicated. Any thoughts?
> >
> > do I understand your suggestion correct, you propose to replace the
> >
> > #define SYMNAME_HASH_INDEX(name) ...
> >
> > in defs.h by something like
> >
> > static unsigned long long SYMNAME_HASH_INDEX(const unsigned char * const name) {
> > return (name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2]) % SYMNAME_HASH);
> > }
> >
> > in symbols.c? If so, I think that should be fine.
> >
Yes, you are right, Philipp.
>
> Please correct me if I'm wrong. I don't think the function can work.
> Let's say name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2]) ==
> -1, then we will have:
>
> static unsigned long long SYMNAME_HASH_INDEX(const unsigned char * const name) {
> return (-1) % 512;
> }
>
> The returned value is a very large number, and will overflow the array.
>
No, this is a modulo operation, and its result will never exceed '512' anyway.
(unsigned long long)(-1) % 512 = 511
Thanks.
Lianbo
3 years, 2 months
[PATCH v4 0/4] Improve kernel modules symbol searching performance
by Tao Liu
This patch set improves symbol_search/symbol_exists performance by introducing hash
table for kernel modules symbols.
v3 -> v4:
1) Removed unused variables in function symbol_search/symbol_exists.
2) Replaced 'assert' with syment_is_installed check function.
3) Add Reviewed-by sign for the first 3 patches.
Tao Liu (4):
Improve the performance of symbol searching for kernel modules
Get the absolute value of SYMNAME_HASH_INDEX
Set name_hash_next field to be NULL for the newly installed elements
Add check if an syment element is installed one more time
defs.h | 3 +-
kernel.c | 1 +
symbols.c | 192 ++++++++++++++++++++++++++++++------------------------
3 files changed, 109 insertions(+), 87 deletions(-)
--
2.29.2
3 years, 2 months
Re: [Crash-utility] [PATCH v4 4/4] Add check if an syment element is installed one more time
by lijiang
> Date: Sat, 18 Sep 2021 15:59:32 +0800
> From: Tao Liu <ltao(a)redhat.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH v4 4/4] Add check if an syment element
> is installed one more time
> Message-ID: <20210918075932.132339-5-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> symname_hash_install won't check if spn has been installed before. If
> it does, the second install will corrupt the hash table as well as
> spn->cnt counting. This patch adds the check to avoid such risks.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> symbols.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/symbols.c b/symbols.c
> index f7157b1..6d12c55 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -1147,6 +1147,20 @@ mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
> symname_hash_remove(st->mod_symname_hash, sp);
> }
>
> +static inline int
> +syment_is_installed(struct syment *table[], struct syment *spn)
> +{
> + struct syment *sp;
> + int index;
> +
> + index = SYMNAME_HASH_INDEX(spn->name);
> + for (sp = table[index]; sp; sp = sp->name_hash_next) {
> + if (sp == spn)
> + return TRUE;
> + }
> + return FALSE;
> +}
> +
> /*
> * Install a single static kernel symbol into the symname_hash.
> */
> @@ -1156,7 +1170,7 @@ symname_hash_install(struct syment *table[], struct syment *spn)
> struct syment *sp;
> int index;
>
> - if (!spn)
> + if (!spn || syment_is_installed(table, spn))
> return;
Here, why don't we call the existing symname_hash_search() and
redefine a new syment_is_installed()? Could you please describe more
details?
Thanks.
Lianbo
>
> index = SYMNAME_HASH_INDEX(spn->name);
> --
> 2.29.2
3 years, 2 months
Re: [Crash-utility] [PATCH v4 1/4] Improve the performance of symbol searching for kernel modules
by lijiang
> Date: Sat, 18 Sep 2021 15:59:29 +0800
> From: Tao Liu <ltao(a)redhat.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH v4 1/4] Improve the performance of
> symbol searching for kernel modules
> Message-ID: <20210918075932.132339-2-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> Currently the sequence for symbol_search to search a symbol is: 1) kernel
> symname hash table, 2) iterate all kernel symbols, 3) iterate all kernel
> modules and their symbols. In the worst case, if a non-exist symbol been
> searched, all 3 stages will be went through. The time consuming status for
> each stage is like:
>
> stage 1 stage 2 stage 3
> 0.007000(ms) 0.593000(ms) 2.421000(ms)
>
> stage 3 takes too much time when comparing to stage 1. This patch introduces
> a symname hash table for kernel modules, to improve the performance of symbol
> searching.
>
> Functions symbol_search and symbol_exists are fundamental and widely used by
> other crash functions, thus the benefit of performance improvement can
> get accumulated. For example, "ps -m" and "irq" commands, which call
> the functions many times, will become faster with the patch.
Thank you for the patch, Tao.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> Reviewed-by: Philipp Rudo <prudo(a)redhat.com>
> ---
> defs.h | 1 +
> kernel.c | 1 +
> symbols.c | 176 ++++++++++++++++++++++++++++--------------------------
> 3 files changed, 92 insertions(+), 86 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index eb1c71b..c10ebff 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2751,6 +2751,7 @@ 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;
> diff --git a/kernel.c b/kernel.c
> index b2c8a0c..307eeee 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -4663,6 +4663,7 @@ reinit_modules(void)
> kt->mods_installed = 0;
> clear_text_value_cache();
>
> + memset(st->mod_symname_hash, 0, sizeof(st->mod_symname_hash));
> module_init();
> }
>
> diff --git a/symbols.c b/symbols.c
> index bf6d94d..7ab47f2 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -64,8 +64,10 @@ static int namespace_ctl(int, struct symbol_namespace *, void *, void *);
> static void symval_hash_init(void);
> static struct syment *symval_hash_search(ulong);
> static void symname_hash_init(void);
> -static void symname_hash_install(struct syment *);
> -static struct syment *symname_hash_search(char *);
> +static void symname_hash_install(struct syment *[], struct syment *);
> +static void symname_hash_remove(struct syment *[], struct syment *);
> +static struct syment *symname_hash_search(struct syment *[], char *,
> + int (*)(struct syment *, char *));
> static void gnu_qsort(bfd *, void *, long, unsigned int, asymbol *, asymbol *);
> static int check_gnu_debuglink(bfd *);
> static int separate_debug_file_exists(const char *, unsigned long, int *);
> @@ -1119,7 +1121,7 @@ symname_hash_init(void)
> struct syment *sp;
>
> for (sp = st->symtable; sp < st->symend; sp++)
> - symname_hash_install(sp);
> + symname_hash_install(st->symname_hash, sp);
>
> if ((sp = symbol_search("__per_cpu_start")))
> st->__per_cpu_start = sp->value;
> @@ -1127,21 +1129,42 @@ symname_hash_init(void)
> st->__per_cpu_end = sp->value;
> }
>
> +static void
> +mod_symtable_hash_install_range(struct syment *from, struct syment *to)
> +{
> + struct syment *sp;
> +
> + for (sp = from; sp <= to; sp++)
> + symname_hash_install(st->mod_symname_hash, sp);
> +}
> +
> +static void
> +mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
> +{
> + struct syment *sp;
> +
> + for (sp = from; sp <= to; sp++)
> + symname_hash_remove(st->mod_symname_hash, sp);
> +}
> +
> /*
> * Install a single static kernel symbol into the symname_hash.
> */
> static void
> -symname_hash_install(struct syment *spn)
> +symname_hash_install(struct syment *table[], struct syment *spn)
> {
> struct syment *sp;
> int index;
>
> + if (!spn)
> + return;
> +
> index = SYMNAME_HASH_INDEX(spn->name);
> spn->cnt = 1;
>
> - if ((sp = st->symname_hash[index]) == NULL)
> - st->symname_hash[index] = spn;
> - else {
> + if ((sp = table[index]) == NULL) {
> + table[index] = spn;
These changes seem unnecessary, the 'st' is a global variable, which
can be accessed anywhere.
> + } else {
> while (sp) {
> if (STREQ(sp->name, spn->name)) {
> sp->cnt++;
> @@ -1157,17 +1180,47 @@ symname_hash_install(struct syment *spn)
> }
> }
>
> +static void
> +symname_hash_remove(struct syment *table[], struct syment *spn)
> +{
> + struct syment *sp;
> + int index;
> +
> + if (!spn)
> + return;
> +
> + index = SYMNAME_HASH_INDEX(spn->name);
> +
> + if (table[index] == spn)
> + table[index] = spn->name_hash_next;
> +
> + for (sp = table[index]; sp; sp = sp->name_hash_next) {
> + if (STREQ(sp->name, spn->name))
> + sp->cnt--;
> + if (sp->name_hash_next == spn)
> + sp->name_hash_next = spn->name_hash_next;
> + }
> +}
> +
> /*
> * Static kernel symbol value search
> */
> static struct syment *
> -symname_hash_search(char *name)
> +symname_hash_search(struct syment *table[], char *name,
> + int (*skip_condition)(struct syment *, char *))
If the skip_condition() can be put into the symbol_search(), the
interface of symname_hash_search() doesn't need to be changed. Could
you please
try it?
> {
> struct syment *sp;
> + int index;
>
> - sp = st->symname_hash[SYMNAME_HASH_INDEX(name)];
> + index = SYMNAME_HASH_INDEX(name);
> + sp = table[index];
>
> while (sp) {
> + if (skip_condition && skip_condition(sp, name)) {
> + sp = sp->name_hash_next;
> + continue;
> + }
> +
> if (STREQ(sp->name, name))
> return sp;
> sp = sp->name_hash_next;
> @@ -1595,6 +1648,7 @@ store_module_symbols_v1(ulong total, int mods_installed)
> lm->mod_symend = sp;
> }
> }
> + mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
> }
>
> st->flags |= MODULE_SYMS;
> @@ -2075,6 +2129,8 @@ store_module_symbols_v2(ulong total, int mods_installed)
> lm->mod_init_symend = sp;
> }
> }
> + mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
> + mod_symtable_hash_install_range(lm->mod_init_symtable, lm->mod_init_symend);
> }
>
> st->flags |= MODULE_SYMS;
> @@ -4482,6 +4538,17 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
> return(cnt);
> }
>
> +static int
> +skip_symbols(struct syment *sp, char *s)
> +{
> + int pseudos, skip = 0;
> +
> + pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_") ||
> + strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
> + if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
> + skip = 1;
> + return skip;
> +}
>
Here, refactoring code is good, but it should be a separate patch,
right? And then you could
add your main changes such as the mod_symname_hash.
> /*
> * Return the syment of a symbol.
> @@ -4489,58 +4556,16 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
> struct syment *
> symbol_search(char *s)
> {
> - int i;
> - struct syment *sp_hashed, *sp, *sp_end;
> - struct load_module *lm;
> - int pseudos, search_init;
> + struct syment *sp_hashed, *sp;
>
> - sp_hashed = symname_hash_search(s);
> + sp_hashed = symname_hash_search(st->symname_hash, s, NULL);
>
> for (sp = sp_hashed ? sp_hashed : st->symtable; sp < st->symend; sp++) {
> if (STREQ(s, sp->name))
> return(sp);
> }
>
> - pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
> - search_init = FALSE;
> -
> - for (i = 0; i < st->mods_installed; i++) {
> - lm = &st->load_modules[i];
> - if (lm->mod_flags & MOD_INIT)
> - search_init = TRUE;
> - sp = lm->mod_symtable;
> - sp_end = lm->mod_symend;
> -
> - for ( ; sp <= sp_end; sp++) {
> - if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
> - continue;
> - if (STREQ(s, sp->name))
> - return(sp);
> - }
> - }
> -
> - if (!search_init)
> - return((struct syment *)NULL);
> -
> - pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
> -
> - for (i = 0; i < st->mods_installed; i++) {
> - lm = &st->load_modules[i];
> - if (!lm->mod_init_symtable)
> - continue;
> - sp = lm->mod_init_symtable;
> - sp_end = lm->mod_init_symend;
> -
> - for ( ; sp < sp_end; sp++) {
> - if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
> - continue;
> -
> - if (STREQ(s, sp->name))
> - return(sp);
> - }
> - }
> -
> - return((struct syment *)NULL);
> + return symname_hash_search(st->mod_symname_hash, s, skip_symbols);
> }
>
> /*
> @@ -5432,33 +5457,11 @@ value_symbol(ulong value)
> int
> symbol_exists(char *symbol)
> {
> - int i;
> - struct syment *sp, *sp_end;
> - struct load_module *lm;
> -
> - if ((sp = symname_hash_search(symbol)))
> + if (symname_hash_search(st->symname_hash, symbol, NULL))
> return TRUE;
>
> - for (i = 0; i < st->mods_installed; i++) {
> - lm = &st->load_modules[i];
> - sp = lm->mod_symtable;
> - sp_end = lm->mod_symend;
> -
> - for ( ; sp < sp_end; sp++) {
> - if (STREQ(symbol, sp->name))
> - return(TRUE);
> - }
> -
> - if (lm->mod_init_symtable) {
> - sp = lm->mod_init_symtable;
> - sp_end = lm->mod_init_symend;
> -
> - for ( ; sp < sp_end; sp++) {
> - if (STREQ(symbol, sp->name))
> - return(TRUE);
> - }
> - }
> - }
> + if (symname_hash_search(st->mod_symname_hash, symbol, NULL))
> + return TRUE;
>
> return(FALSE);
> }
> @@ -5513,12 +5516,7 @@ per_cpu_symbol_search(char *symbol)
> int
> kernel_symbol_exists(char *symbol)
> {
> - struct syment *sp;
> -
> - if ((sp = symname_hash_search(symbol)))
> - return TRUE;
> - else
> - return FALSE;
> + return !!(symname_hash_search(st->symname_hash, symbol, NULL));
> }
>
> /*
> @@ -5527,7 +5525,7 @@ kernel_symbol_exists(char *symbol)
> struct syment *
> kernel_symbol_search(char *symbol)
> {
> - return symname_hash_search(symbol);
> + return symname_hash_search(st->symname_hash, symbol, NULL);
> }
>
> /*
> @@ -12464,8 +12462,10 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms,
> error(INFO, "%s: last symbol: %s is not _MODULE_END_%s?\n",
> lm->mod_name, lm->mod_load_symend->name, lm->mod_name);
>
> + mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
> lm->mod_symtable = lm->mod_load_symtable;
> lm->mod_symend = lm->mod_load_symend;
> + mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
>
> lm->mod_flags &= ~MOD_EXT_SYMS;
> lm->mod_flags |= MOD_LOAD_SYMS;
> @@ -12495,6 +12495,7 @@ delete_load_module(ulong base_addr)
> req->name = lm->mod_namelist;
> gdb_interface(req);
> }
> + mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
> if (lm->mod_load_symtable) {
> free(lm->mod_load_symtable);
> namespace_ctl(NAMESPACE_FREE,
> @@ -12504,6 +12505,7 @@ delete_load_module(ulong base_addr)
> unlink_module(lm);
> lm->mod_symtable = lm->mod_ext_symtable;
> lm->mod_symend = lm->mod_ext_symend;
> + mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
> lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
> lm->mod_flags |= MOD_EXT_SYMS;
> lm->mod_load_symtable = NULL;
> @@ -12532,6 +12534,7 @@ delete_load_module(ulong base_addr)
> req->name = lm->mod_namelist;
> gdb_interface(req);
> }
> + mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
> if (lm->mod_load_symtable) {
> free(lm->mod_load_symtable);
> namespace_ctl(NAMESPACE_FREE,
> @@ -12541,6 +12544,7 @@ delete_load_module(ulong base_addr)
> unlink_module(lm);
> lm->mod_symtable = lm->mod_ext_symtable;
> lm->mod_symend = lm->mod_ext_symend;
> + mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
> lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
> lm->mod_flags |= MOD_EXT_SYMS;
> lm->mod_load_symtable = NULL;
> --
> 2.29.2
3 years, 2 months
[ANNOUNCE] crash with GDB 10.2 and release plan
by HAGIO KAZUHITO(萩尾 一仁)
Hi,
We have worked on updating the GDB contained by the crash utility to
version 10.2. We are going to merge the patch series [1] next week.
[1] https://github.com/lian-bo/crash-gdb10.2-devel-temp
And, here is the plan of the next releases:
1. create "crash-7-branch" to maintain the current gdb-7.6 crash
for more several months.
2. merge the gdb-10.2 patch series into the master branch.
3. release crash-8.0.0 with gdb-10.2 and crash-7.3.1 with gdb-7.6
in this November or December.
4. release crash-7.3.2 with gdb-7.6 next year as its end of life.
Nov or Dec May? (every 6 months)
8.0.0 8.0.1
master -------+--gdb10.2--*--------------*------>
|
crash-7-branch `-----------*--------------| (end of life)
7.3.1 7.3.2
It would be helpful if you would test it and report/fix bugs.
We would like to thank Alexey Makhalov, who has done this excellent work,
Tao Liu also has helped us test and fix bugs a lot, Youling Tang has tested
on MIPS architecture, and all developers who have tested and reported bugs.
Thanks,
Kazu
3 years, 2 months
Re: [Crash-utility] [PATCH v4 2/4] Get the absolute value of SYMNAME_HASH_INDEX
by lijiang
> Date: Sat, 18 Sep 2021 15:59:30 +0800
> From: Tao Liu <ltao(a)redhat.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH v4 2/4] Get the absolute value of
> SYMNAME_HASH_INDEX
> Message-ID: <20210918075932.132339-3-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> SYMNAME_HASH_INDEX is used as the index of symname hash table. It will
> be out of range if SYMNAME_HASH_INDEX is negative. Let's get its absolute
> value to avoid such risk.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> Reviewed-by: Philipp Rudo <prudo(a)redhat.com>
> ---
> defs.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/defs.h b/defs.h
> index c10ebff..3129f06 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2725,7 +2725,7 @@ struct downsized {
>
> #define SYMNAME_HASH (512)
> #define SYMNAME_HASH_INDEX(name) \
> - ((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH)
> + (abs((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH))
>
I guess this may be caused by integer overflow, the expression uses
integer calculations by default. Does the following change work for
you?
-#define SYMNAME_HASH (512)
+#define SYMNAME_HASH (512ULL)
Thanks.
Lianbo
> #define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
> #define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
> --
> 2.29.2
>
3 years, 3 months
Re: [Crash-utility] [PATCH v4] diskdump: Add support for reading dumpfiles compressed by Zstandard
by lijiang
> Date: Mon, 27 Sep 2021 00:45:42 +0000
> From: HAGIO KAZUHITO(?????) <k-hagio-ab(a)nec.com>
> To: lijiang <lijiang(a)redhat.com>
> Cc: "Discussion list for crash utility usage, maintenance and
> development" <crash-utility(a)redhat.com>
> Subject: [Crash-utility] [PATCH v4] diskdump: Add support for reading
> dumpfiles compressed by Zstandard
> Message-ID:
> <TYYPR01MB6777731C245433F4DC18EEFADDA79(a)TYYPR01MB6777.jpnprd01.prod.outlook.com>
>
> Content-Type: text/plain; charset="iso-2022-jp"
>
> Add support for reading dumpfiles compressed by Zstandard (zstd)
> using makedumpfile.
>
> To build crash with zstd support, type "make zstd".
>
> Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
> ---
> v3 -> v4
> - also moved the definition of dctx into cache_page()
> - moved the second "if (!dctx)" block into the first one
>
Thank you for the update, Kazu.
> Makefile | 4 ++++
> README | 4 ++--
> configure.c | 24 +++++++++++++++++++++---
> defs.h | 4 ++++
> diskdump.c | 37 +++++++++++++++++++++++++++++++++++++
> diskdump.h | 1 +
> help.c | 4 ++--
> 7 files changed, 71 insertions(+), 7 deletions(-)
>
For V4:
Acked-by: Lianbo Jiang <lijiang(a)redhat.com>
3 years, 3 months
Re: [Crash-utility] [PATCH] arm64 : assign page_offset and kvbase based on VA_BITS passed
by lijiang
> Date: Thu, 23 Sep 2021 01:46:31 +0530
> From: Ankur Bansal <er.ankurbansal(a)gmail.com>
> To: crash-utility(a)redhat.com
> Cc: Ankur Bansal <er.ankurbansal(a)gmail.com>
> Subject: [Crash-utility] [PATCH] arm64 : assign page_offset and kvbase
> based on VA_BITS passed
> Message-ID:
> <1632341791-10205-1-git-send-email-er.ankurbansal(a)gmail.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> assign page_offset and kvbase based on VA_BITS passed
>
Thank you for the patch, Ankur.
Can you help to describe the reason in detail? And what happened?
Thanks.
Lianbo
> Change-Id: I525f3c7fd91e1f06e909c2f4c1749c44c068baea
> Signed-off-by: Ankur Bansal <er.ankurbansal(a)gmail.com>
> ---
> arm64.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 7069312..2dc77f7 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -220,10 +220,17 @@ arm64_init(int when)
>
> /* vabits_actual introduced after mm flip, so it should be flipped layout */
> if (ms->VA_BITS_ACTUAL) {
> - ms->page_offset = ARM64_FLIP_PAGE_OFFSET;
> - /* useless on arm64 */
> - machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET;
> - machdep->kvbase = ARM64_FLIP_PAGE_OFFSET;
> + if ((pc->flags2 & SNAP)) {
> + ms->page_offset = ARM64_FLIP_PAGE_OFFSET;
> + /* useless on arm64 */
> + machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET;
> + machdep->kvbase = ARM64_FLIP_PAGE_OFFSET;
> + }
> + else{
> + ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
> + machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
> + machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
> + }
> ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
> } else {
> ms->page_offset = ARM64_PAGE_OFFSET;
> --
> 2.7.4
3 years, 3 months
[PATCH v4] diskdump: Add support for reading dumpfiles compressed by Zstandard
by HAGIO KAZUHITO(萩尾 一仁)
Add support for reading dumpfiles compressed by Zstandard (zstd)
using makedumpfile.
To build crash with zstd support, type "make zstd".
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
v3 -> v4
- also moved the definition of dctx into cache_page()
- moved the second "if (!dctx)" block into the first one
Makefile | 4 ++++
README | 4 ++--
configure.c | 24 +++++++++++++++++++++---
defs.h | 4 ++++
diskdump.c | 37 +++++++++++++++++++++++++++++++++++++
diskdump.h | 1 +
help.c | 4 ++--
7 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index ece13069a029..eae023c54bdd 100644
--- a/Makefile
+++ b/Makefile
@@ -333,6 +333,10 @@ snappy: make_configure
@./configure -x snappy ${CONF_TARGET_FLAG} -w -b
@make --no-print-directory gdb_merge
+zstd: make_configure
+ @./configure -x zstd ${CONF_TARGET_FLAG} -w -b
+ @make --no-print-directory gdb_merge
+
valgrind: make_configure
@./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
@make --no-print-directory gdb_merge
diff --git a/README b/README
index 50179742e620..4962f272074b 100644
--- a/README
+++ b/README
@@ -102,8 +102,8 @@
Traditionally when vmcores are compressed via the makedumpfile(8) facility
the libz compression library is used, and by default the crash utility
only supports libz. Recently makedumpfile has been enhanced to optionally
- use either the LZO or snappy compression libraries. To build crash with
- either or both of those libraries, type "make lzo" or "make snappy".
+ use the LZO, snappy or zstd compression libraries. To build crash with any
+ or all of those libraries, type "make lzo", "make snappy" or "make zstd".
crash supports valgrind Memcheck tool on the crash's custom memory allocator.
To build crash with this feature enabled, type "make valgrind" and then run
diff --git a/configure.c b/configure.c
index e8f619a3c061..b691a139b960 100644
--- a/configure.c
+++ b/configure.c
@@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial)
* - enter -DSNAPPY in the CFLAGS.extra file
* - enter -lsnappy in the LDFLAGS.extra file
*
+ * For zstd:
+ * - enter -DZSTD in the CFLAGS.extra file
+ * - enter -lzstd in the LDFLAGS.extra file
+ *
* For valgrind:
* - enter -DVALGRIND in the CFLAGS.extra file
*/
@@ -1746,6 +1750,7 @@ add_extra_lib(char *option)
{
int lzo, add_DLZO, add_llzo2;
int snappy, add_DSNAPPY, add_lsnappy;
+ int zstd, add_DZSTD, add_lzstd;
int valgrind, add_DVALGRIND;
char *cflags, *ldflags;
FILE *fp_cflags, *fp_ldflags;
@@ -1754,6 +1759,7 @@ add_extra_lib(char *option)
lzo = add_DLZO = add_llzo2 = 0;
snappy = add_DSNAPPY = add_lsnappy = 0;
+ zstd = add_DZSTD = add_lzstd = 0;
valgrind = add_DVALGRIND = 0;
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
@@ -1775,13 +1781,21 @@ add_extra_lib(char *option)
add_lsnappy++;
}
+ if (strcmp(option, "zstd") == 0) {
+ zstd++;
+ if (!cflags || !strstr(cflags, "-DZSTD"))
+ add_DZSTD++;
+ if (!ldflags || !strstr(ldflags, "-lzstd"))
+ add_lzstd++;
+ }
+
if (strcmp(option, "valgrind") == 0) {
valgrind++;
if (!cflags || !strstr(cflags, "-DVALGRIND"))
add_DVALGRIND++;
}
- if ((lzo || snappy) &&
+ if ((lzo || snappy || zstd) &&
file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
perror("diskdump.o");
return;
@@ -1806,24 +1820,28 @@ add_extra_lib(char *option)
return;
}
- if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
+ if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
while (fgets(inbuf, 512, fp_cflags))
;
if (add_DLZO)
fputs("-DLZO\n", fp_cflags);
if (add_DSNAPPY)
fputs("-DSNAPPY\n", fp_cflags);
+ if (add_DZSTD)
+ fputs("-DZSTD\n", fp_cflags);
if (add_DVALGRIND)
fputs("-DVALGRIND\n", fp_cflags);
}
- if (add_llzo2 || add_lsnappy) {
+ if (add_llzo2 || add_lsnappy || add_lzstd) {
while (fgets(inbuf, 512, fp_ldflags))
;
if (add_llzo2)
fputs("-llzo2\n", fp_ldflags);
if (add_lsnappy)
fputs("-lsnappy\n", fp_ldflags);
+ if (add_lzstd)
+ fputs("-lzstd\n", fp_ldflags);
}
fclose(fp_cflags);
diff --git a/defs.h b/defs.h
index eb1c71b5333a..b2e94722c92b 100644
--- a/defs.h
+++ b/defs.h
@@ -54,6 +54,9 @@
#ifdef SNAPPY
#include <snappy-c.h>
#endif
+#ifdef ZSTD
+#include <zstd.h>
+#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
@@ -327,6 +330,7 @@ struct number_option {
#define NO_ELF_NOTES (0x20)
#define LZO_SUPPORTED (0x40)
#define SNAPPY_SUPPORTED (0x80)
+#define ZSTD_SUPPORTED (0x100)
#define DISKDUMP_VALID() (dd->flags & DISKDUMP_LOCAL)
#define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL)
#define KDUMP_SPLIT() (dd->flags & DUMPFILE_SPLIT)
diff --git a/diskdump.c b/diskdump.c
index de3eeb2c720c..112f769f8949 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1001,6 +1001,9 @@ is_diskdump(char *file)
#ifdef SNAPPY
dd->flags |= SNAPPY_SUPPORTED;
#endif
+#ifdef ZSTD
+ dd->flags |= ZSTD_SUPPORTED;
+#endif
pc->read_vmcoreinfo = vmcoreinfo_read_string;
@@ -1124,6 +1127,9 @@ cache_page(physaddr_t paddr)
const int block_size = dd->block_size;
const off_t failed = (off_t)-1;
ulong retlen;
+#ifdef ZSTD
+ static ZSTD_DCtx *dctx = NULL;
+#endif
for (i = found = 0; i < DISKDUMP_CACHED_PAGES; i++) {
if (DISKDUMP_VALID_PAGE(dd->page_cache_hdr[i].pg_flags))
@@ -1251,6 +1257,33 @@ cache_page(physaddr_t paddr)
ret);
return READ_ERROR;
}
+#endif
+ } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
+
+ if (!(dd->flags & ZSTD_SUPPORTED)) {
+ error(INFO, "%s: uncompess failed: no zstd compression support\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+ return READ_ERROR;
+ }
+#ifdef ZSTD
+ if (!dctx) {
+ dctx = ZSTD_createDCtx();
+ if (!dctx) {
+ error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+ return READ_ERROR;
+ }
+ }
+
+ retlen = ZSTD_decompressDCtx(dctx,
+ dd->page_cache_hdr[i].pg_bufptr, block_size,
+ dd->compressed_page, pd.size);
+ if (ZSTD_isError(retlen) || (retlen != block_size)) {
+ error(INFO, "%s: uncompress failed: %d (%s)\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
+ retlen, ZSTD_getErrorName(retlen));
+ return READ_ERROR;
+ }
#endif
} else
memcpy(dd->page_cache_hdr[i].pg_bufptr,
@@ -1806,6 +1839,8 @@ __diskdump_memory_dump(FILE *fp)
fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : "");
if (dd->flags & SNAPPY_SUPPORTED)
fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : "");
+ if (dd->flags & ZSTD_SUPPORTED)
+ fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : "");
fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
fprintf(fp, " dfd: %d\n", dd->dfd);
fprintf(fp, " ofp: %lx\n", (ulong)dd->ofp);
@@ -1872,6 +1907,8 @@ __diskdump_memory_dump(FILE *fp)
fprintf(fp, "DUMP_DH_COMPRESSED_LZO");
if (dh->status & DUMP_DH_COMPRESSED_SNAPPY)
fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY");
+ if (dh->status & DUMP_DH_COMPRESSED_ZSTD)
+ fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD");
if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE)
fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE");
if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP)
diff --git a/diskdump.h b/diskdump.h
index 28713407b841..c152c7b86616 100644
--- a/diskdump.h
+++ b/diskdump.h
@@ -86,6 +86,7 @@ struct kdump_sub_header {
#define DUMP_DH_COMPRESSED_SNAPPY 0x4 /* page is compressed with snappy */
#define DUMP_DH_COMPRESSED_INCOMPLETE 0x8 /* dumpfile is incomplete */
#define DUMP_DH_EXCLUDED_VMEMMAP 0x10 /* unused vmemmap pages are excluded */
+#define DUMP_DH_COMPRESSED_ZSTD 0x20 /* page is compressed with zstd */
/* descriptor of each page for vmcore */
typedef struct page_desc {
diff --git a/help.c b/help.c
index 6c262a3ffcbb..f34838d59908 100644
--- a/help.c
+++ b/help.c
@@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY,
" Traditionally when vmcores are compressed via the makedumpfile(8) facility",
" the libz compression library is used, and by default the crash utility",
" only supports libz. Recently makedumpfile has been enhanced to optionally",
-" use either the LZO or snappy compression libraries. To build crash with",
-" either or both of those libraries, type \"make lzo\" or \"make snappy\".",
+" use the LZO, snappy or zstd compression libraries. To build crash with any",
+" or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".",
"",
" crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
" To build crash with this feature enabled, type \"make valgrind\" and then run",
--
2.27.0
3 years, 3 months
Re: [Crash-utility] [PATCH v3] diskdump: Add support for reading dumpfiles compressed by Zstandard
by lijiang
On Fri, Sep 24, 2021 at 10:51 AM HAGIO KAZUHITO(萩尾 一仁)
<k-hagio-ab(a)nec.com> wrote:
>
> Add support for reading dumpfiles compressed by Zstandard (zstd)
> using makedumpfile.
>
> To build crash with zstd support, type "make zstd".
>
> Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
> ---
> v2 -> v3
> - add a 'For zstd:' section in the comment above add_extra_lib()
> - move ZSTD_createDCtx() into cache_page() and add an error when
> it cannot create dctx
> - add a sanity check on retlen
>
> Makefile | 4 ++++
> README | 4 ++--
> configure.c | 24 +++++++++++++++++++++---
> defs.h | 4 ++++
> diskdump.c | 38 ++++++++++++++++++++++++++++++++++++++
> diskdump.h | 1 +
> help.c | 4 ++--
> 7 files changed, 72 insertions(+), 7 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index ece13069a029..eae023c54bdd 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -333,6 +333,10 @@ snappy: make_configure
> @./configure -x snappy ${CONF_TARGET_FLAG} -w -b
> @make --no-print-directory gdb_merge
>
> +zstd: make_configure
> + @./configure -x zstd ${CONF_TARGET_FLAG} -w -b
> + @make --no-print-directory gdb_merge
> +
> valgrind: make_configure
> @./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
> @make --no-print-directory gdb_merge
> diff --git a/README b/README
> index 50179742e620..4962f272074b 100644
> --- a/README
> +++ b/README
> @@ -102,8 +102,8 @@
> Traditionally when vmcores are compressed via the makedumpfile(8) facility
> the libz compression library is used, and by default the crash utility
> only supports libz. Recently makedumpfile has been enhanced to optionally
> - use either the LZO or snappy compression libraries. To build crash with
> - either or both of those libraries, type "make lzo" or "make snappy".
> + use the LZO, snappy or zstd compression libraries. To build crash with any
> + or all of those libraries, type "make lzo", "make snappy" or "make zstd".
>
> crash supports valgrind Memcheck tool on the crash's custom memory allocator.
> To build crash with this feature enabled, type "make valgrind" and then run
> diff --git a/configure.c b/configure.c
> index e8f619a3c061..b691a139b960 100644
> --- a/configure.c
> +++ b/configure.c
> @@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial)
> * - enter -DSNAPPY in the CFLAGS.extra file
> * - enter -lsnappy in the LDFLAGS.extra file
> *
> + * For zstd:
> + * - enter -DZSTD in the CFLAGS.extra file
> + * - enter -lzstd in the LDFLAGS.extra file
> + *
> * For valgrind:
> * - enter -DVALGRIND in the CFLAGS.extra file
> */
> @@ -1746,6 +1750,7 @@ add_extra_lib(char *option)
> {
> int lzo, add_DLZO, add_llzo2;
> int snappy, add_DSNAPPY, add_lsnappy;
> + int zstd, add_DZSTD, add_lzstd;
> int valgrind, add_DVALGRIND;
> char *cflags, *ldflags;
> FILE *fp_cflags, *fp_ldflags;
> @@ -1754,6 +1759,7 @@ add_extra_lib(char *option)
>
> lzo = add_DLZO = add_llzo2 = 0;
> snappy = add_DSNAPPY = add_lsnappy = 0;
> + zstd = add_DZSTD = add_lzstd = 0;
> valgrind = add_DVALGRIND = 0;
>
> ldflags = get_extra_flags("LDFLAGS.extra", NULL);
> @@ -1775,13 +1781,21 @@ add_extra_lib(char *option)
> add_lsnappy++;
> }
>
> + if (strcmp(option, "zstd") == 0) {
> + zstd++;
> + if (!cflags || !strstr(cflags, "-DZSTD"))
> + add_DZSTD++;
> + if (!ldflags || !strstr(ldflags, "-lzstd"))
> + add_lzstd++;
> + }
> +
> if (strcmp(option, "valgrind") == 0) {
> valgrind++;
> if (!cflags || !strstr(cflags, "-DVALGRIND"))
> add_DVALGRIND++;
> }
>
> - if ((lzo || snappy) &&
> + if ((lzo || snappy || zstd) &&
> file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
> perror("diskdump.o");
> return;
> @@ -1806,24 +1820,28 @@ add_extra_lib(char *option)
> return;
> }
>
> - if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
> + if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
> while (fgets(inbuf, 512, fp_cflags))
> ;
> if (add_DLZO)
> fputs("-DLZO\n", fp_cflags);
> if (add_DSNAPPY)
> fputs("-DSNAPPY\n", fp_cflags);
> + if (add_DZSTD)
> + fputs("-DZSTD\n", fp_cflags);
> if (add_DVALGRIND)
> fputs("-DVALGRIND\n", fp_cflags);
> }
>
> - if (add_llzo2 || add_lsnappy) {
> + if (add_llzo2 || add_lsnappy || add_lzstd) {
> while (fgets(inbuf, 512, fp_ldflags))
> ;
> if (add_llzo2)
> fputs("-llzo2\n", fp_ldflags);
> if (add_lsnappy)
> fputs("-lsnappy\n", fp_ldflags);
> + if (add_lzstd)
> + fputs("-lzstd\n", fp_ldflags);
> }
>
> fclose(fp_cflags);
> diff --git a/defs.h b/defs.h
> index eb1c71b5333a..b2e94722c92b 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -54,6 +54,9 @@
> #ifdef SNAPPY
> #include <snappy-c.h>
> #endif
> +#ifdef ZSTD
> +#include <zstd.h>
> +#endif
>
> #ifndef ATTRIBUTE_UNUSED
> #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
> @@ -327,6 +330,7 @@ struct number_option {
> #define NO_ELF_NOTES (0x20)
> #define LZO_SUPPORTED (0x40)
> #define SNAPPY_SUPPORTED (0x80)
> +#define ZSTD_SUPPORTED (0x100)
> #define DISKDUMP_VALID() (dd->flags & DISKDUMP_LOCAL)
> #define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL)
> #define KDUMP_SPLIT() (dd->flags & DUMPFILE_SPLIT)
> diff --git a/diskdump.c b/diskdump.c
> index de3eeb2c720c..9e80cd3d6f52 100644
> --- a/diskdump.c
> +++ b/diskdump.c
> @@ -96,6 +96,10 @@ static struct diskdump_data **dd_list = NULL;
> static int num_dd = 0;
> static int num_dumpfiles = 0;
>
> +#ifdef ZSTD
> +static ZSTD_DCtx *dctx = NULL;
> +#endif
> +
Would it be better to move the above definition to cache_page()? Because it is
not used in other functions, and the behavior is the same.
> int dumpfile_is_split(void)
> {
> return KDUMP_SPLIT();
> @@ -1001,6 +1005,9 @@ is_diskdump(char *file)
> #ifdef SNAPPY
> dd->flags |= SNAPPY_SUPPORTED;
> #endif
> +#ifdef ZSTD
> + dd->flags |= ZSTD_SUPPORTED;
> +#endif
>
> pc->read_vmcoreinfo = vmcoreinfo_read_string;
>
> @@ -1251,6 +1258,33 @@ cache_page(physaddr_t paddr)
> ret);
> return READ_ERROR;
> }
> +#endif
> + } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
> +
> + if (!(dd->flags & ZSTD_SUPPORTED)) {
> + error(INFO, "%s: uncompess failed: no zstd compression support\n",
> + DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
> + return READ_ERROR;
> + }
> +#ifdef ZSTD
> + if (!dctx)
> + dctx = ZSTD_createDCtx();
> +
Usually these two functions ZSTD_createDCtx()/ZSTC_free() are required
to be called in pairs, but this(static definition) seems to simplify
the code.
Thanks.
Lianbo
> + if (!dctx) {
> + error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
> + DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
> + return READ_ERROR;
> + }
> +
> + retlen = ZSTD_decompressDCtx(dctx,
> + dd->page_cache_hdr[i].pg_bufptr, block_size,
> + dd->compressed_page, pd.size);
> + if (ZSTD_isError(retlen) || (retlen != block_size)) {
> + error(INFO, "%s: uncompress failed: %d (%s)\n",
> + DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
> + retlen, ZSTD_getErrorName(retlen));
> + return READ_ERROR;
> + }
> #endif
> } else
> memcpy(dd->page_cache_hdr[i].pg_bufptr,
> @@ -1806,6 +1840,8 @@ __diskdump_memory_dump(FILE *fp)
> fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : "");
> if (dd->flags & SNAPPY_SUPPORTED)
> fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : "");
> + if (dd->flags & ZSTD_SUPPORTED)
> + fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : "");
> fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
> fprintf(fp, " dfd: %d\n", dd->dfd);
> fprintf(fp, " ofp: %lx\n", (ulong)dd->ofp);
> @@ -1872,6 +1908,8 @@ __diskdump_memory_dump(FILE *fp)
> fprintf(fp, "DUMP_DH_COMPRESSED_LZO");
> if (dh->status & DUMP_DH_COMPRESSED_SNAPPY)
> fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY");
> + if (dh->status & DUMP_DH_COMPRESSED_ZSTD)
> + fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD");
> if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE)
> fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE");
> if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP)
> diff --git a/diskdump.h b/diskdump.h
> index 28713407b841..c152c7b86616 100644
> --- a/diskdump.h
> +++ b/diskdump.h
> @@ -86,6 +86,7 @@ struct kdump_sub_header {
> #define DUMP_DH_COMPRESSED_SNAPPY 0x4 /* page is compressed with snappy */
> #define DUMP_DH_COMPRESSED_INCOMPLETE 0x8 /* dumpfile is incomplete */
> #define DUMP_DH_EXCLUDED_VMEMMAP 0x10 /* unused vmemmap pages are excluded */
> +#define DUMP_DH_COMPRESSED_ZSTD 0x20 /* page is compressed with zstd */
>
> /* descriptor of each page for vmcore */
> typedef struct page_desc {
> diff --git a/help.c b/help.c
> index 6c262a3ffcbb..f34838d59908 100644
> --- a/help.c
> +++ b/help.c
> @@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY,
> " Traditionally when vmcores are compressed via the makedumpfile(8) facility",
> " the libz compression library is used, and by default the crash utility",
> " only supports libz. Recently makedumpfile has been enhanced to optionally",
> -" use either the LZO or snappy compression libraries. To build crash with",
> -" either or both of those libraries, type \"make lzo\" or \"make snappy\".",
> +" use the LZO, snappy or zstd compression libraries. To build crash with any",
> +" or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".",
> "",
> " crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
> " To build crash with this feature enabled, type \"make valgrind\" and then run",
> --
> 2.27.0
>
3 years, 3 months