Update to the latest upstream <68870c83d299>

Release: crash-7.3.0-5

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
Lianbo Jiang 2021-11-06 14:37:20 +08:00
parent f1cd67284d
commit e1f6e2b6fb
10 changed files with 867 additions and 1 deletions

View File

@ -0,0 +1,151 @@
From 2fab8fbc0c4f1c4cbe889de4cead5f7457a19f77 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:11 +0800
Subject: [PATCH 1/9] symbols: Implement install and remove operations for
mod_symname_hash
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 series
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 series.
This patch indroduces mod_symname_hash, and its install/remove operations.
Since symbol_search() has to return the lowest address symbol and
symbol_search_next() returns the next lowest symbol, thus the installation
should be sorted ascendingly.
In mod_symname_hash_install_range() scenario, spn are already arranged
ascendingly, so for mod_symname_hash_install():
Install spn previous to sp:
If sp is the start of bucket, or
1) spn->value is smaller than sp->value.
Install spn next to sp:
1) sp->name_hash_next is NULL, or
2) sp->name_hash_next->value is larger than spn->value
spn->value is the kernel address of the symbol and will not change.
So we use it mainly to determine the sequence. When spn->value equals
sp->value, they must be symbols within a kernel module.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 1 +
symbols.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/defs.h b/defs.h
index cbd45e52f9da..bbdca799f72d 100644
--- a/defs.h
+++ b/defs.h
@@ -2755,6 +2755,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/symbols.c b/symbols.c
index 69dccdb09d5f..ad12d1c22225 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1157,6 +1157,79 @@ symname_hash_install(struct syment *spn)
}
}
+/*
+ * Install a single kernel module symbol into the mod_symname_hash.
+ */
+static void
+mod_symname_hash_install(struct syment *spn)
+{
+ struct syment *sp;
+ int index;
+
+ if (!spn)
+ return;
+
+ index = SYMNAME_HASH_INDEX(spn->name);
+
+ sp = st->mod_symname_hash[index];
+
+ if (!sp || (spn->value < sp->value)) {
+ st->mod_symname_hash[index] = spn;
+ spn->name_hash_next = sp;
+ return;
+ }
+ for (; sp; sp = sp->name_hash_next) {
+ if (!sp->name_hash_next ||
+ spn->value < sp->name_hash_next->value) {
+ spn->name_hash_next = sp->name_hash_next;
+ sp->name_hash_next = spn;
+ return;
+ }
+ }
+}
+
+static void
+mod_symname_hash_remove(struct syment *spn)
+{
+ struct syment *sp;
+ int index;
+
+ if (!spn)
+ return;
+
+ index = SYMNAME_HASH_INDEX(spn->name);
+
+ if (st->mod_symname_hash[index] == spn) {
+ st->mod_symname_hash[index] = spn->name_hash_next;
+ return;
+ }
+
+ for (sp = st->mod_symname_hash[index]; sp; sp = sp->name_hash_next) {
+ if (sp->name_hash_next == spn) {
+ sp->name_hash_next = spn->name_hash_next;
+ return;
+ }
+ }
+}
+
+static void
+mod_symtable_hash_install_range(struct syment *from, struct syment *to)
+{
+ struct syment *sp;
+
+ for (sp = from; sp <= to; sp++)
+ mod_symname_hash_install(sp);
+}
+
+static void
+mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
+{
+ struct syment *sp;
+
+ for (sp = from; sp <= to; sp++)
+ mod_symname_hash_remove(sp);
+}
+
/*
* Static kernel symbol value search
*/
--
2.30.2

View File

@ -0,0 +1,103 @@
From 214f9bf3727c3350401b3f4b4389258c24486e06 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:12 +0800
Subject: [PATCH 2/9] symbols: Integrate symbol_search() with mod_symname_hash
search
This patch introduces mod_symname_hash search to symbol_search(),
to get a better searching performance.
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
symbols.c | 58 ++++++++++++++++++-------------------------------------
1 file changed, 19 insertions(+), 39 deletions(-)
diff --git a/symbols.c b/symbols.c
index ad12d1c22225..c4ad31fe926f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -4551,6 +4551,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 = FALSE;
+
+ 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 = TRUE;
+ return skip;
+}
/*
* Return the syment of a symbol.
@@ -4558,10 +4569,7 @@ 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);
@@ -4570,43 +4578,15 @@ symbol_search(char *s)
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)
+ sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
+ while (sp) {
+ if (skip_symbols(sp, s)) {
+ sp = sp->name_hash_next;
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);
}
+ if (STREQ(sp->name, s))
+ return sp;
+ sp = sp->name_hash_next;
}
return((struct syment *)NULL);
--
2.30.2

View File

@ -0,0 +1,82 @@
From 340c6ad1a0a7ce76eb5d9397833bfc6a049e2b3b Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:13 +0800
Subject: [PATCH 3/9] symbols: Extend symname_hash_search() with hash table
select
Previously symname_hash_search() can only search symbols from kernel's
symname_hash. This patch add hash table pointer as parameter for
symname_hash_search(). Thus symname_hash_search() can be used both for
symname_hash and mod_symname_hash searching.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
symbols.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/symbols.c b/symbols.c
index c4ad31fe926f..83393f09270d 100644
--- a/symbols.c
+++ b/symbols.c
@@ -65,7 +65,7 @@ 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 struct syment *symname_hash_search(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 *);
@@ -1234,11 +1234,11 @@ mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
* Static kernel symbol value search
*/
static struct syment *
-symname_hash_search(char *name)
+symname_hash_search(struct syment *table[], char *name)
{
struct syment *sp;
- sp = st->symname_hash[SYMNAME_HASH_INDEX(name)];
+ sp = table[SYMNAME_HASH_INDEX(name)];
while (sp) {
if (STREQ(sp->name, name))
@@ -4571,7 +4571,7 @@ symbol_search(char *s)
{
struct syment *sp_hashed, *sp;
- sp_hashed = symname_hash_search(s);
+ sp_hashed = symname_hash_search(st->symname_hash, s);
for (sp = sp_hashed ? sp_hashed : st->symtable; sp < st->symend; sp++) {
if (STREQ(s, sp->name))
@@ -5485,7 +5485,7 @@ symbol_exists(char *symbol)
struct syment *sp, *sp_end;
struct load_module *lm;
- if ((sp = symname_hash_search(symbol)))
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
return TRUE;
for (i = 0; i < st->mods_installed; i++) {
@@ -5564,7 +5564,7 @@ kernel_symbol_exists(char *symbol)
{
struct syment *sp;
- if ((sp = symname_hash_search(symbol)))
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
return TRUE;
else
return FALSE;
@@ -5576,7 +5576,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);
}
/*
--
2.30.2

View File

@ -0,0 +1,74 @@
From f3bee9375ed32b85e7f81a5e46a0040620553ae0 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:14 +0800
Subject: [PATCH 4/9] symbols: Intergrate symbol_exists() with mod_symname_hash
search
This patch introduces mod_symname_hash search to symbol_exists()
to improve its performance. And code refactoring for
kernel_symbol_exists().
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
symbols.c | 35 ++++-------------------------------
1 file changed, 4 insertions(+), 31 deletions(-)
diff --git a/symbols.c b/symbols.c
index 83393f09270d..8d3dd95f737b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -5481,33 +5481,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(st->symname_hash, symbol)))
+ if (symname_hash_search(st->symname_hash, symbol))
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))
+ return TRUE;
return(FALSE);
}
@@ -5562,12 +5540,7 @@ per_cpu_symbol_search(char *symbol)
int
kernel_symbol_exists(char *symbol)
{
- struct syment *sp;
-
- if ((sp = symname_hash_search(st->symname_hash, symbol)))
- return TRUE;
- else
- return FALSE;
+ return !!symname_hash_search(st->symname_hash, symbol);
}
/*
--
2.30.2

View File

@ -0,0 +1,92 @@
From 1e23335dab6bf9f6219a23bf0be4ad9f433f4f43 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:15 +0800
Subject: [PATCH 5/9] symbols: Sync module symbols into mod_symtable whenever
module symbols change
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
kernel.c | 1 +
symbols.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/kernel.c b/kernel.c
index 3ead4bbb172e..f10b8b216571 100644
--- a/kernel.c
+++ b/kernel.c
@@ -4661,6 +4661,7 @@ reinit_modules(void)
st->ext_module_symtable = NULL;
st->load_modules = NULL;
kt->mods_installed = 0;
+ memset(st->mod_symname_hash, 0, sizeof(st->mod_symname_hash));
module_init();
}
diff --git a/symbols.c b/symbols.c
index 8d3dd95f737b..5603a2efd61f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1668,6 +1668,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;
@@ -2148,6 +2149,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;
@@ -12478,8 +12481,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;
@@ -12509,6 +12514,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,
@@ -12518,6 +12524,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;
@@ -12546,6 +12553,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,
@@ -12555,6 +12563,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.30.2

View File

@ -0,0 +1,121 @@
From df0049d12b2ced1b6ff7350ee3c0ca28c3f7cd52 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:16 +0800
Subject: [PATCH 6/9] symbols: Refactor SYMNAME_HASH_INDEX macro to be a
function
SYMNAME_HASH_INDEX is used as the index of symname hash table. It will
be out of range if SYMNAME_HASH_INDEX is negative. This patch avoids
the risk by changing the marco into a function, and casting and calculating
the numbers as unsigned.
Suggested-by: Lianbo Jiang <lijiang@redhat.com>
Suggested-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 2 --
symbols.c | 31 +++++++++++++++++++++++--------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/defs.h b/defs.h
index bbdca799f72d..8b356d5e8959 100644
--- a/defs.h
+++ b/defs.h
@@ -2728,8 +2728,6 @@ struct downsized {
(((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
#define SYMNAME_HASH (512)
-#define SYMNAME_HASH_INDEX(name) \
- ((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH)
#define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
#define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
diff --git a/symbols.c b/symbols.c
index 5603a2efd61f..67b701454563 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1127,6 +1127,21 @@ symname_hash_init(void)
st->__per_cpu_end = sp->value;
}
+static unsigned int
+symname_hash_index(char *name)
+{
+ unsigned int len, value;
+ unsigned char *array = (unsigned char *)name;
+
+ len = strlen(name);
+ if (!len)
+ error(FATAL, "The length of the symbol name is zero!\n");
+
+ value = array[len - 1] * array[len / 2];
+
+ return (array[0] ^ value) % SYMNAME_HASH;
+}
+
/*
* Install a single static kernel symbol into the symname_hash.
*/
@@ -1134,9 +1149,9 @@ static void
symname_hash_install(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
spn->cnt = 1;
if ((sp = st->symname_hash[index]) == NULL)
@@ -1164,12 +1179,12 @@ static void
mod_symname_hash_install(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
if (!spn)
return;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
sp = st->mod_symname_hash[index];
@@ -1192,12 +1207,12 @@ static void
mod_symname_hash_remove(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
if (!spn)
return;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
if (st->mod_symname_hash[index] == spn) {
st->mod_symname_hash[index] = spn->name_hash_next;
@@ -1238,7 +1253,7 @@ symname_hash_search(struct syment *table[], char *name)
{
struct syment *sp;
- sp = table[SYMNAME_HASH_INDEX(name)];
+ sp = table[symname_hash_index(name)];
while (sp) {
if (STREQ(sp->name, name))
@@ -4581,7 +4596,7 @@ symbol_search(char *s)
return(sp);
}
- sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
+ sp = st->mod_symname_hash[symname_hash_index(s)];
while (sp) {
if (skip_symbols(sp, s)) {
sp = sp->name_hash_next;
--
2.30.2

View File

@ -0,0 +1,99 @@
From 5c04a6f3f923af7c50f0d853477044802b3fa6ec Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:17 +0800
Subject: [PATCH 7/9] symbols: Add mod_symname_hash table dump to help -s
Previously, help -s only print out the dump status of symname_hash
table. Since we have mod_symname_hash table introduced, let's print
out mod_symname_hash in help -s as well.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
symbols.c | 57 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 22 deletions(-)
diff --git a/symbols.c b/symbols.c
index 67b701454563..73baa953217a 100644
--- a/symbols.c
+++ b/symbols.c
@@ -3219,13 +3219,40 @@ kallsyms_module_function_size(struct syment *sp, struct load_module *lm, ulong *
return FALSE;
}
+static void
+dump_symname_hash_table(struct syment *table[])
+{
+ int i, cnt, tot;
+ struct syment *sp;
+
+ fprintf(fp, " ");
+ for (i = tot = 0; i < SYMNAME_HASH; i++) {
+ fprintf(fp, "[%3d]: ", i);
+ if ((sp = table[i]) == NULL)
+ fprintf(fp, "%3d ", 0);
+ else {
+ cnt = 1;
+ while (sp->name_hash_next) {
+ cnt++;
+ sp = sp->name_hash_next;
+ }
+ fprintf(fp, "%3d ", cnt);
+ tot += cnt;
+ }
+ if (i && (((i+1) % 6) == 0))
+ fprintf(fp, "\n ");
+ }
+ if (SYMNAME_HASH % 6)
+ fprintf(fp, "\n");
+}
+
/*
* "help -s" output
*/
void
dump_symbol_table(void)
{
- int i, s, cnt, tot;
+ int i, s, cnt;
struct load_module *lm;
struct syment *sp;
struct downsized *ds;
@@ -3355,28 +3382,14 @@ dump_symbol_table(void)
fprintf(fp, " symname_hash[%d]: %lx\n", SYMNAME_HASH,
(ulong)&st->symname_hash[0]);
+ if (CRASHDEBUG(1))
+ dump_symname_hash_table(st->symname_hash);
+
+ fprintf(fp, "mod_symname_hash[%d]: %lx\n", SYMNAME_HASH,
+ (ulong)&st->mod_symname_hash[0]);
+ if (CRASHDEBUG(1))
+ dump_symname_hash_table(st->mod_symname_hash);
- if (CRASHDEBUG(1)) {
- fprintf(fp, " ");
- for (i = tot = 0; i < SYMNAME_HASH; i++) {
- fprintf(fp, "[%3d]: ", i);
- if ((sp = st->symname_hash[i]) == NULL)
- fprintf(fp, "%3d ", 0);
- else {
- cnt = 1;
- while (sp->name_hash_next) {
- cnt++;
- sp = sp->name_hash_next;
- }
- fprintf(fp, "%3d ", cnt);
- tot += cnt;
- }
- if (i && (((i+1) % 6) == 0))
- fprintf(fp, "\n ");
- }
- if (SYMNAME_HASH % 6)
- fprintf(fp, "\n");
- }
fprintf(fp, " symbol_namespace: ");
fprintf(fp, "address: %lx ", (ulong)st->kernel_namespace.address);
fprintf(fp, "index: %ld ", st->kernel_namespace.index);
--
2.30.2

View File

@ -0,0 +1,66 @@
From c180a63f2cb370da6097ad97eb07333c07aa988b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 25 Oct 2021 16:53:26 +0900
Subject: [PATCH 8/9] arm64: Use VA_BITS for page_offset calculation
Commit 167d37e347fe ("arm64: assign page_offset with VA_BITS kernel
configuration value") changed the page_offset calculation from
using VA_BITS_ACTUAL to CONFIG_ARM64_VA_BITS. This caused an error
for ramdumps without vmcoreinfo like this:
crash: vmlinux and /var/tmp/ramdump_elf_XUtCMT do not match!
Set the vmcoreinfo value to VA_BITS if available, and use VA_BITS
for page_offset calculation instead.
Also remove ARM64_FLIP_PAGE_OFFSET_ACTUAL because it's not used
actually.
Reported-by: Ankur Bansal <er.ankurbansal@gmail.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
arm64.c | 5 ++++-
defs.h | 4 +---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arm64.c b/arm64.c
index 7069312671cf..3dcbcc642fda 100644
--- a/arm64.c
+++ b/arm64.c
@@ -404,7 +404,7 @@ arm64_init(int when)
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET);
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
@@ -4031,6 +4031,9 @@ arm64_calc_VA_BITS(void)
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
+ if (machdep->machspec->CONFIG_ARM64_VA_BITS)
+ machdep->machspec->VA_BITS = machdep->machspec->CONFIG_ARM64_VA_BITS;
+
/*
* The mm flip commit is introduced before 52-bits VA, which is before the
* commit to export NUMBER(TCR_EL1_T1SZ)
diff --git a/defs.h b/defs.h
index 8b356d5e8959..971005596506 100644
--- a/defs.h
+++ b/defs.h
@@ -3238,9 +3238,7 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
/* kernels >= v5.4 the kernel VA space is flipped */
-#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
-#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- - ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->VA_BITS)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
#define ARM64_USERSPACE_TOP_ACTUAL ((1UL) << machdep->machspec->VA_BITS_ACTUAL)
--
2.30.2

View File

@ -0,0 +1,57 @@
From 68870c83d299603c07785e3530e33c13045c87ef Mon Sep 17 00:00:00 2001
From: Alexander Egorenkov <egorenar@linux.ibm.com>
Date: Wed, 13 Oct 2021 10:56:39 +0200
Subject: [PATCH 9/9] Handle task_struct cpu member changes for kernels >=
5.16-rc1
Kernel commit bcf9033e5449bdcaa9bed46467a7141a8049dadb
("sched: move CPU field back into thread_info if THREAD_INFO_IN_TASK=y")
moved the member cpu of task_struct back into thread_info.
Without the patch, crash fails with the following error message
during session initialization:
crash: invalid structure member offset: task_struct_cpu
FILE: task.c LINE: 2904 FUNCTION: add_context()
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
task.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/task.c b/task.c
index 672b41697e75..bb6a5da8ad33 100644
--- a/task.c
+++ b/task.c
@@ -278,8 +278,10 @@ task_init(void)
} else if (VALID_MEMBER(task_struct_stack))
MEMBER_OFFSET_INIT(task_struct_thread_info, "task_struct", "stack");
+ MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
+
if (VALID_MEMBER(task_struct_thread_info)) {
- if (tt->flags & THREAD_INFO_IN_TASK) {
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu)) {
MEMBER_OFFSET_INIT(thread_info_flags, "thread_info", "flags");
/* (unnecessary) reminders */
ASSIGN_OFFSET(thread_info_task) = INVALID_OFFSET;
@@ -315,7 +317,6 @@ task_init(void)
MEMBER_OFFSET_INIT(task_struct_has_cpu, "task_struct", "has_cpu");
MEMBER_OFFSET_INIT(task_struct_cpus_runnable,
"task_struct", "cpus_runnable");
- MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
MEMBER_OFFSET_INIT(task_struct_active_mm, "task_struct", "active_mm");
MEMBER_OFFSET_INIT(task_struct_next_run, "task_struct", "next_run");
MEMBER_OFFSET_INIT(task_struct_flags, "task_struct", "flags");
@@ -2900,7 +2901,7 @@ add_context(ulong task, char *tp)
else
tc->thread_info = ULONG(tp + OFFSET(task_struct_thread_info));
fill_thread_info(tc->thread_info);
- if (tt->flags & THREAD_INFO_IN_TASK)
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu))
processor_addr = (int *) (tp + OFFSET(task_struct_cpu));
else
processor_addr = (int *) (tt->thread_info +
--
2.30.2

View File

@ -4,7 +4,7 @@
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.3.0
Release: 4%{?dist}
Release: 5%{?dist}
License: GPLv3
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
@ -61,6 +61,15 @@ Patch40: 0024-Set-gdb-max-value-size-to-be-unlimited.patch
Patch41: 0025-Fix-tab-completion-issues.patch
Patch42: 0026-Remove-text-value-cache-code.patch
Patch43: 0027-.gitignore-add-gdb-10.2-directory.patch
Patch44: 0001-symbols-Implement-install-and-remove-operations-for-.patch
Patch45: 0002-symbols-Integrate-symbol_search-with-mod_symname_has.patch
Patch46: 0003-symbols-Extend-symname_hash_search-with-hash-table-s.patch
Patch47: 0004-symbols-Intergrate-symbol_exists-with-mod_symname_ha.patch
Patch48: 0005-symbols-Sync-module-symbols-into-mod_symtable-whenev.patch
Patch49: 0006-symbols-Refactor-SYMNAME_HASH_INDEX-macro-to-be-a-fu.patch
Patch50: 0007-symbols-Add-mod_symname_hash-table-dump-to-help-s.patch
Patch51: 0008-arm64-Use-VA_BITS-for-page_offset-calculation.patch
Patch52: 0009-Handle-task_struct-cpu-member-changes-for-kernels-5..patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -124,6 +133,15 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%build
# This package has an internal copy of GDB which has broken configure code for
@ -157,6 +175,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Sat Nov 06 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-5
- Update to the latest upstream: commit <68870c83d299>
* Tue Oct 12 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-4
- Update to gdb-10.2