[PATCH v3] x86_64: Make ORC_REG_SP and ORC_REG_PREV_SP independent from kernel version
by Tao Liu
Previously ORC_REG_SP and ORC_REG_PREV_SP will depend on kernel version
for their value, however this is fragile since distributions will
backport the upstream patch to a lower kernel version, thus break the
version assumption.
This patch fixes by checking the value of ORC_REG_PREV_SP, which can be
get from orc_fp_entry. ORC_REG_PREV_SP's value can work as the indicator
of whether the current kernel have applied the upstream patch 1735858caa4b
("objtool/x86: Reorder ORC register numbering").
Fixes: d0ee428664f9 ("x86_64: Fix "bt" command to use correct ORC register
values on Linux 7.1 and later")
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
v3 -> v2: Remove data type query of orc_fp_entry, just use kernel_orc_entry_6_4
which already contained in crash utility for bp_reg offset resolving.
---
x86_64.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 55648697baf3..d192f3bcdd20 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -6661,6 +6661,9 @@ x86_64_ORC_init(void)
NULL
};
struct ORC_data *orc;
+ struct gnu_request request, *req;
+ ulong value = 0;
+ req = &request;
MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
@@ -6736,13 +6739,28 @@ x86_64_ORC_init(void)
if (orc->has_signal && !orc->has_end)
machdep->flags |= ORC_6_4;
- /* See kernel commit 1735858caa4b */
- if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
- ORC_REG_SP = 3;
- ORC_REG_PREV_SP = 8;
- } else {
- ORC_REG_SP = 5;
- ORC_REG_PREV_SP = 1;
+ /* Try get ORC_REG_(PREV)_SP */
+ ORC_REG_SP = 5;
+ ORC_REG_PREV_SP = 1;
+
+ if (kernel_symbol_exists("orc_fp_entry")) {
+ /*
+ * kernel_orc_entry_6_4 & kernel_orc_entry have the same
+ * offset of bp_reg.
+ */
+ kernel_orc_entry_6_4 entry = {0};
+ if (try_get_symbol_data("orc_fp_entry", sizeof(entry), &entry)) {
+ /*
+ * orc_fp_entry.bp_reg = ORC_REG_PREV_SP
+ * See kernel commit 1735858caa4b. Use ORC_REG_PREV_SP
+ * as the indicator of the commit.
+ */
+ if (entry.bp_reg == 8) {
+ ORC_REG_SP = 3;
+ ORC_REG_PREV_SP = 8;
+ }
+ } else
+ error(WARNING, "Cannot get orc_fp_entry.bp_reg info");
}
machdep->flags |= ORC;
--
2.54.0
1 week, 4 days
[PATCH v2] symbols: optimize symval_hash_init with O(1) tail insertion
by 启瑞
From: Rui Qi <qirui.001(a)bytedance.com>
Replace the O(n) tail traversal with O(1) tail insertion using a local
per-bucket tail tracking array. The original code traversed the entire
linked list on every insert to find the tail, resulting in O(n^2)
complexity for hash table initialization.
This reduces hash table initialization from O(n^2) to O(n).
Benchmark on an x86_64 machine (kernel 5.10.135, ~112k symbols):
Before: 5.54 s (mean, n=6, sigma=0.12)
After: 5.31 s (mean, n=6, sigma=0.12)
Speedup: 1.04x (-4.1%)
Benchmark on an ARM64 Neoverse-N2 machine (kernel 5.15.152.bsk.4-arm64,
~132k nm symbols):
Before: 3.4113 s (mean, n=48, sigma=0.0698)
After: 2.5073 s (mean, n=48, sigma=0.0394)
Speedup: 1.36x (-26.5%), with improved consistency.
User CPU: 4.1706 s -> 3.2768 s (-21.4%).
Benchmark retest on a RISC-V machine (kernel
6.12.13.bsk.1-rc14-riscv64, ~198k nm symbols):
$ printf 'q\n' | ./crash vmlinux /proc/kcore
Before: 11.934 s (mean, n=3, sigma=0.880; samples: 12.921, 11.231, 11.651)
After: 10.255 s (mean, n=3, sigma=0.835; samples: 11.131, 9.467, 10.168)
Speedup: 1.16x (-14.1%)
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
Changes from V1 [1]:
- Use a separate local tails[] array for tail tracking instead of reusing
val_hash_last, to preserve its original semantics as a last-visited-entry
cache for symval_hash_search(). (Dave Young, Tao Liu)
- Add benchmarks on x86_64 and ARM64 in addition to RISC-V. (Tao Liu)
[1] https://lists.crash-utility.osci.io/archives/list/devel@lists.crash-utili...
---
symbols.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/symbols.c b/symbols.c
index 03511c8cbe8c..42e0058a102e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1085,12 +1085,16 @@ symbol_value_from_proc_kallsyms(char *symname)
/*
* Install all static kernel symbol values into the symval_hash.
+ * Uses val_hash_last for O(1) tail insertion.
*/
static void
symval_hash_init(void)
{
int index;
- struct syment *sp, *sph;
+ struct syment *sp;
+ struct syment *tails[SYMVAL_HASH];
+
+ BZERO(tails, sizeof(tails));
for (sp = st->symtable; sp < st->symend; sp++) {
index = SYMVAL_HASH_INDEX(sp->value);
@@ -1098,14 +1102,9 @@ symval_hash_init(void)
if (st->symval_hash[index].val_hash_head == NULL) {
st->symval_hash[index].val_hash_head = sp;
st->symval_hash[index].val_hash_last = sp;
- continue;
- }
-
- sph = st->symval_hash[index].val_hash_head;
- while (sph->val_hash_next)
- sph = sph->val_hash_next;
-
- sph->val_hash_next = sp;
+ } else
+ tails[index]->val_hash_next = sp;
+ tails[index] = sp;
}
}
--
2.20.1
1 week, 5 days
[RFC PATCH 1/2] add cpu_to_nid function
by Huang Shijie
Add cpu_to_nid function which we can use to get the NUMA node id
by the cpu id.
Signed-off-by: Huang Shijie <huangsj(a)hygon.cn>
---
defs.h | 2 ++
kernel.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
main.c | 1 +
3 files changed, 49 insertions(+)
diff --git a/defs.h b/defs.h
index a4f70b7..98a149b 100644
--- a/defs.h
+++ b/defs.h
@@ -6040,6 +6040,8 @@ ulong do_maple_tree(ulong, int, struct list_pair *);
void help_init(void);
void cmd_usage(char *, int);
void display_version(void);
+int cpu_to_nid(int cpu);
+void numa_init(void);
void display_help_screen(char *);
#ifdef ARM
#define dump_machdep_table(X) arm_dump_machdep_table(X)
diff --git a/kernel.c b/kernel.c
index eb9754c..15254a4 100644
--- a/kernel.c
+++ b/kernel.c
@@ -12207,3 +12207,49 @@ out:
pc->error_fp = error_fp_save;
}
#endif
+
+static int *cpu_to_nid_map;
+
+int
+cpu_to_nid(int cpu)
+{
+ if (!cpu_to_nid_map || cpu < 0 || cpu >= kt->cpus)
+ return -1;
+ if (vt->numnodes == 1)
+ return 0;
+ return cpu_to_nid_map[cpu];
+}
+
+static void
+cpu_to_nid_init(void)
+{
+ int i, j;
+ int fd;
+ char buf[64];
+
+ cpu_to_nid_map = malloc(kt->cpus * sizeof(int));
+ if (vt->numnodes == 1)
+ return;
+
+ memset(cpu_to_nid_map, -1, kt->cpus * sizeof(int));
+
+ for (i = 0; i < kt->cpus; i++) {
+ for (j = 0; j < vt->numnodes; j++) {
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "/sys/devices/system/cpu/cpu%d/node%d", i, j);
+
+ fd = open(buf, O_RDONLY);
+ if (fd > 0) {
+ cpu_to_nid_map[i] = j;
+ close(fd);
+ break;
+ }
+ }
+ }
+}
+
+void
+numa_init(void)
+{
+ cpu_to_nid_init();
+}
diff --git a/main.c b/main.c
index d5f8486..a8c77f8 100644
--- a/main.c
+++ b/main.c
@@ -793,6 +793,7 @@ main_loop(void)
kernel_init();
machdep_init(POST_GDB);
vm_init();
+ numa_init();
machdep_init(POST_VM);
module_init();
help_init();
--
2.53.0
2 weeks, 1 day
[PATCH 0/2] task: Format command names consistently across 'ps' options
by Aaron Tomlin
In the crash utility, the default 'ps' command (and options such as 'ps -k')
displays kernel thread command names enclosed in square brackets
(e.g., [kworker/6:1]) to easily distinguish kernel tasks from user tasks.
However, task listing functions that rely on print_task_header() (such as
'ps -l' and 'ps -m') previously formatted all task command names enclosed
in double quotes (e.g. COMMAND: "kworker/6:1" and COMMAND: "crash").
This patch series unifies task command formatting across
print_task_header() to remove double quotes for all tasks and enclose
kernel thread command names in square brackets.
Before:
crash> ps -l 191918
[b5a7e47c0036] [ID] PID: 191918 TASK: ffff8ac62c188000 CPU: 6 COMMAND: "kworker/6:1"
After:
crash> ps -l 191918
[b5a7e47c0036] [ID] PID: 191918 TASK: ffff8ac62c188000 CPU: 6 COMMAND: [kworker/6:1]
Before:
crash> ps -m 196591
[0 00:00:00.033] [RU] PID: 196591 TASK: ffff8ac4bfac8000 CPU: 0 COMMAND: "crash"
After:
crash> ps -m 196591
[0 00:00:00.033] [RU] PID: 196591 TASK: ffff8ac4bfac8000 CPU: 0 COMMAND: crash
Aaron Tomlin (2):
task: remove double quotes around command name in print_task_header()
task: enclose kernel tasks in square brackets in print_task_header()
help.c | 117 ++++++++++++++++++++++++++++-----------------------------
task.c | 7 +++-
2 files changed, 62 insertions(+), 62 deletions(-)
--
2.55.0
2 weeks, 1 day
Re: [PATCH v2] x86_64: Make ORC_REG_SP and ORC_REG_PREV_SP independent from kernel version
by Tao Liu
Hi MUKESH,
Please check your email settings; the output is misformatted. And for
upstream patch review please cc to the mailing list as well.
On Wed, Aug 5, 2026 at 8:32 PM MUKESH KUMAR PILANIYA
<mpilaniy(a)redhat.com> wrote:
>
>
>
> > On 5 Aug 2026, at 1:59 PM, MUKESH KUMAR PILANIYA <mpilaniy(a)redhat.com> wrote:
> >
> >
> >
> >> On 4 Aug 2026, at 12:59 PM, HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab at nec.com> wrote:
> >>
> >> On 2026/08/04 15:57, Tao Liu wrote:
> >>> Previously ORC_REG_SP and ORC_REG_PREV_SP will depend on kernel version
> >>> for their value, however this is fragile since distributions will
> >>> backport the upstream patch to a lower kernel version, thus break the
> >>> version assumption.
> >>>
> >>> This patch fixes by checking the value of ORC_REG_PREV_SP, which can be
> >>> get from orc_fp_entry. ORC_REG_PREV_SP's value can work as the indicator
> >>> of whether the current kernel have applied the upstream patch 1735858caa4b
> >>> ("objtool/x86: Reorder ORC register numbering").
> >>>
> >>> Fixes: d0ee428664f9 ("x86_64: Fix "bt" command to use correct ORC register
> >>> values on Linux 7.1 and later")
> >>>
> >>> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> >>
> >> thank you for the fix, looks good to me.
> >>
> >> Thanks,
> >> Kazu
> >>
> >>> ---
> >>> v2 -> v1: emit error(WARN) for kernels which doesn't have orc_fp_entry
> >>> symbol.
> >>> ---
> >>> x86_64.c | 30 +++++++++++++++++++++++-------
> >>> 1 file changed, 23 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/x86_64.c b/x86_64.c
> >>> index 55648697baf3..81d20ed419d5 100644
> >>> --- a/x86_64.c
> >>> +++ b/x86_64.c
> >>> @@ -6661,6 +6661,9 @@ x86_64_ORC_init(void)
> >>> NULL
> >>> };
> >>> struct ORC_data *orc;
> >>> + struct gnu_request request, *req;
> >>> + req = &request;
> >>> + ulong value = 0;
> >
> > declaration after statement so that compiler does not give warning as per C90 standards.
> > ulong value = 0;
> > req = &request;
> >
> > This will also works.
> > struct gnu_request request, *req = &request;
> > ulong value = 0;
OK, agreed.
> >
> >>>
> >>> MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
> >>> MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
> >>> @@ -6736,13 +6739,26 @@ x86_64_ORC_init(void)
> >>> if (orc->has_signal && !orc->has_end)
> >>> machdep->flags |= ORC_6_4;
> >>>
> >>> - /* See kernel commit 1735858caa4b */
> >>> - if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
> >>> - ORC_REG_SP = 3;
> >>> - ORC_REG_PREV_SP = 8;
> >>> - } else {
> >>> - ORC_REG_SP = 5;
> >>> - ORC_REG_PREV_SP = 1;
> >>> + /* Try get ORC_REG_(PREV)_SP */
> >>> + ORC_REG_SP = 5;
> >>> + ORC_REG_PREV_SP = 1;
> >>> +
> >>> + if (kernel_symbol_exists("orc_fp_entry")) {
> >
> > If orc_fp_entry doesn't exist in the symbol table (possible on stripped vmlinux without kallsyms, or if a future kernel removes it), the patch silently falls back to old values.
> >
> > Also the kernel declares orc_fp_entry as static in arch/x86/kernel/unwind_orc.c. It's generally available in:
> > - vmlinux with debuginfo (.symtab with STB_LOCAL)
> > - /proc/kallsyms (with CONFIG_KALLSYMS_ALL=y, the default)
> >
> > But it won't be available in fully stripped vmlinux without kallsyms. So it better to implement a fallback logic in else block.
> >
> > else if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
> > ORC_REG_SP = 3;
> > ORC_REG_PREV_SP = 8;
> > }
I'm not a fan of using THIS_KERNEL_VERSION check, this is what the
patch is trying to solve. For crash utility, it relies on debuginfo
stored within vmlinux, if missing, then crash cannot work as expected,
so from my view we needn't consider the missing scenario. If
orc_fp_entry removed in future kernels, then I prefer to let it expose
to address then.
> >
> >>> + if (get_symbol_type("orc_fp_entry", "bp_reg", req) == TYPE_CODE_INT) {
> >
> > Crash utility already defines kernel_orc_entry in defs.h with the identical packed bitfield layout so why not to use directly that will reduce get_symbol_type + manual bitfield extraction work ?
> > The bp_reg bitfield is at the same offset in both kernel_orc_entry and kernel_orc_entry_6_4, so either works.
Good catch, I didn't notice the existing structure in crash utility.
> >
> >>> + get_symbol_data("orc_fp_entry", sizeof(ulong), &value);
> >
> > get_symbol_data() calls readmem() with FAULT_ON_ERROR, which aborts crash if the memory page isn't present in the vmcore. In kdump scenarios, not all pages are necessarily captured. The patch should use try_get_symbol_data() instead, which returns FALSE on failure without aborting.
Agreed.
> >
> >>> + /*
> >>> + * orc_fp_entry.bp_reg = ORC_REG_PREV_SP
> >>> + * See kernel commit 1735858caa4b. Use ORC_REG_PREV_SP as the
> >>> + * indicator of the commit.
> >>> + */
> >>> + value >>= req->member_offset;
> >>> + value &= ((1UL << req->member_length) - 1);
> >>> + if (value == 8) {
> >>> + ORC_REG_SP = 3;
> >>> + ORC_REG_PREV_SP = 8;
> >>> + }
> >>> + } else
> >>> + error(WARNING, "Cannot get orc_fp_entry.bp_reg info");
> >
> > Should not be this is a more user friendly ?
> > error(WARNING, "Cannot determine ORC register numbering from orc_fp_entry; “ "using legacy values (ORC_REG_SP=5, ORC_REG_PREV_SP=1)\n");
Personally I prefer the original way: yours makes the warning message
wordy. Frankly, which value crash utility chooses is irrelevant to
users. To crash developers, a single "cannot get xxx info" is enough
for us to locate the issue.
Thanks,
Tao Liu
> >
> >>> }
> >>>
> >>> machdep->flags |= ORC;
> >
> >
> > Putting it all together.
> > /* Detect ORC register numbering from orc_fp_entry.bp_reg.
> > * See kernel commit 1735858caa4b. Note: orc_fp_entry is static,
> > * so fall back to the version check if the symbol is unavailable.
> > */
> > ORC_REG_SP = 5;
> > ORC_REG_PREV_SP = 1;
> >
> > if (kernel_symbol_exists("orc_fp_entry")) {
> > kernel_orc_entry fp_entry;
> > if (try_get_symbol_data("orc_fp_entry",
> > sizeof(kernel_orc_entry), &fp_entry) &&
> > fp_entry.bp_reg == 8) {
> > ORC_REG_SP = 3;
> > ORC_REG_PREV_SP = 8;
> > }
> > } else if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
> > ORC_REG_SP = 3;
> > ORC_REG_PREV_SP = 8;
> > }
> >
> > Thanks
> > Mukesh Pilaniya
>
2 weeks, 2 days
Bahrain eVisa Types
by Patrick Holmes
Bahrain provides various online visa options designed to meet the needs of travelers visiting for different purposes. Selecting the right category helps applicants prepare the correct documents and complete the application process successfully. The Bahrain eVisa Types include tourist visas for leisure travel, family visit options for meeting relatives and business visas for professional activities. Each visa category has specific conditions, eligibility requirements and permitted stay durations. Travelers should review the details carefully before applying to ensure they choose the appropriate option. The electronic visa system offers a convenient way to submit applications online and supports a smoother travel experience for visitors planning a trip to Bahrain.
website: https://bahrain-visas.com/bahrain-e-visa-types/
2 weeks, 3 days
Bahrain Urgent eVisa
by Patrick Holmes
Travelers with immediate plans to visit Bahrain may need a convenient option to complete their visa arrangements quickly. The online application system helps eligible visitors submit their requests digitally and prepare for their journey with ease. The Bahrain Urgent eVisa is suitable for applicants who require faster processing for upcoming travel needs. Travelers should provide correct personal details, valid documents and complete information to support their application. Processing time may depend on application accuracy and official procedures. Applying with proper documentation can help reduce delays. With approved travel authorization, visitors can manage urgent tourism, business or family trips to Bahrain more efficiently and conveniently.
website:https://bahrain-visas.com/bahrain-urgent-evisa/
2 weeks, 3 days
[PATCH v2] x86_64: Make ORC_REG_SP and ORC_REG_PREV_SP independent from kernel version
by Tao Liu
Previously ORC_REG_SP and ORC_REG_PREV_SP will depend on kernel version
for their value, however this is fragile since distributions will
backport the upstream patch to a lower kernel version, thus break the
version assumption.
This patch fixes by checking the value of ORC_REG_PREV_SP, which can be
get from orc_fp_entry. ORC_REG_PREV_SP's value can work as the indicator
of whether the current kernel have applied the upstream patch 1735858caa4b
("objtool/x86: Reorder ORC register numbering").
Fixes: d0ee428664f9 ("x86_64: Fix "bt" command to use correct ORC register
values on Linux 7.1 and later")
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
v2 -> v1: emit error(WARN) for kernels which doesn't have orc_fp_entry
symbol.
---
x86_64.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 55648697baf3..81d20ed419d5 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -6661,6 +6661,9 @@ x86_64_ORC_init(void)
NULL
};
struct ORC_data *orc;
+ struct gnu_request request, *req;
+ req = &request;
+ ulong value = 0;
MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
@@ -6736,13 +6739,26 @@ x86_64_ORC_init(void)
if (orc->has_signal && !orc->has_end)
machdep->flags |= ORC_6_4;
- /* See kernel commit 1735858caa4b */
- if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
- ORC_REG_SP = 3;
- ORC_REG_PREV_SP = 8;
- } else {
- ORC_REG_SP = 5;
- ORC_REG_PREV_SP = 1;
+ /* Try get ORC_REG_(PREV)_SP */
+ ORC_REG_SP = 5;
+ ORC_REG_PREV_SP = 1;
+
+ if (kernel_symbol_exists("orc_fp_entry")) {
+ if (get_symbol_type("orc_fp_entry", "bp_reg", req) == TYPE_CODE_INT) {
+ get_symbol_data("orc_fp_entry", sizeof(ulong), &value);
+ /*
+ * orc_fp_entry.bp_reg = ORC_REG_PREV_SP
+ * See kernel commit 1735858caa4b. Use ORC_REG_PREV_SP as the
+ * indicator of the commit.
+ */
+ value >>= req->member_offset;
+ value &= ((1UL << req->member_length) - 1);
+ if (value == 8) {
+ ORC_REG_SP = 3;
+ ORC_REG_PREV_SP = 8;
+ }
+ } else
+ error(WARNING, "Cannot get orc_fp_entry.bp_reg info");
}
machdep->flags |= ORC;
--
2.54.0
2 weeks, 4 days
[PATCH] x86_64: Make ORC_REG_SP and ORC_REG_PREV_SP independent from kernel version
by Tao Liu
Previously ORC_REG_SP and ORC_REG_PREV_SP will depend on kernel version
for their value, however this is fragile since distributions will
backport the upstream patch to a lower kernel version, thus break the
version assumption.
This patch fixes by checking the value of ORC_REG_PREV_SP, which can be
get from orc_fp_entry. ORC_REG_PREV_SP's value can work as the indicator
of whether the current kernel have applied the upstream patch 1735858caa4b
("objtool/x86: Reorder ORC register numbering").
Fixes: d0ee428664f9 ("x86_64: Fix "bt" command to use correct ORC register
values on Linux 7.1 and later")
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
x86_64.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 55648697baf3..10e06b942d53 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -6661,6 +6661,9 @@ x86_64_ORC_init(void)
NULL
};
struct ORC_data *orc;
+ struct gnu_request request, *req;
+ req = &request;
+ ulong value = 0;
MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
@@ -6736,14 +6739,26 @@ x86_64_ORC_init(void)
if (orc->has_signal && !orc->has_end)
machdep->flags |= ORC_6_4;
- /* See kernel commit 1735858caa4b */
- if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
- ORC_REG_SP = 3;
- ORC_REG_PREV_SP = 8;
- } else {
- ORC_REG_SP = 5;
- ORC_REG_PREV_SP = 1;
- }
+ /* Try get ORC_REG_(PREV)_SP */
+ ORC_REG_SP = 5;
+ ORC_REG_PREV_SP = 1;
+
+ if (kernel_symbol_exists("orc_fp_entry") &&
+ get_symbol_type("orc_fp_entry", "bp_reg", req) == TYPE_CODE_INT) {
+ get_symbol_data("orc_fp_entry", sizeof(ulong), &value);
+ /*
+ * orc_fp_entry.bp_reg = ORC_REG_PREV_SP
+ * See kernel commit 1735858caa4b. Use ORC_REG_PREV_SP as the
+ * indicator of the commit.
+ */
+ value >>= req->member_offset;
+ value &= ((1UL << req->member_length) - 1);
+ if (value == 8) {
+ ORC_REG_SP = 3;
+ ORC_REG_PREV_SP = 8;
+ }
+ } else
+ error(WARNING, "Cannot get orc_fp_entry info");
machdep->flags |= ORC;
}
--
2.54.0
2 weeks, 4 days
[PATCH] symbols: optimize symval_hash_init with O(1) tail insertion
by 启瑞
From: Rui Qi <qirui.001(a)bytedance.com>
Replace the O(n) tail traversal with O(1) tail insertion using the
existing val_hash_last pointer. The original code traversed the entire
linked list on every insert to find the tail, resulting in O(n^2)
complexity for hash table initialization.
The new implementation uses the val_hash_last pointer that was already
maintained in the data structure:
- Insert at tail in O(1) time
- Update val_hash_last after each insertion
- Set val_hash_next to NULL for each new entry
This reduces hash table initialization from O(n^2) to O(n).
Benchmark on a RISC-V 64-core machine (kernel 6.12.95, ~200k symbols):
$ echo q | ./crash /proc/kcore vmlinux
Before: 44.67 s (mean, n=6, σ=5.61)
After: 36.56 s (mean, n=6, σ=2.30)
Speedup: 1.22x (-18.1%), with improved consistency.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
symbols.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/symbols.c b/symbols.c
index 03511c8..0b564d2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1085,12 +1085,13 @@ symbol_value_from_proc_kallsyms(char *symname)
/*
* Install all static kernel symbol values into the symval_hash.
+ * Uses val_hash_last for O(1) tail insertion.
*/
static void
symval_hash_init(void)
{
int index;
- struct syment *sp, *sph;
+ struct syment *sp;
for (sp = st->symtable; sp < st->symend; sp++) {
index = SYMVAL_HASH_INDEX(sp->value);
@@ -1098,14 +1099,12 @@ symval_hash_init(void)
if (st->symval_hash[index].val_hash_head == NULL) {
st->symval_hash[index].val_hash_head = sp;
st->symval_hash[index].val_hash_last = sp;
- continue;
+ } else {
+ /* O(1) tail insertion using val_hash_last */
+ st->symval_hash[index].val_hash_last->val_hash_next = sp;
+ st->symval_hash[index].val_hash_last = sp;
}
-
- sph = st->symval_hash[index].val_hash_head;
- while (sph->val_hash_next)
- sph = sph->val_hash_next;
-
- sph->val_hash_next = sp;
+ sp->val_hash_next = NULL;
}
}
--
2.47.3
2 weeks, 5 days