* [PATCH 1/4] LoongArch: Add guess unwinder support
2022-08-01 12:17 [PATCH 0/4] LoongArch: Add unwinder support Qing Zhang
@ 2022-08-01 12:17 ` Qing Zhang
2022-08-01 15:28 ` Huacai Chen
2022-08-01 12:17 ` [PATCH 2/4] LoongArch: Add prologue " Qing Zhang
` (3 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Qing Zhang @ 2022-08-01 12:17 UTC (permalink / raw)
To: Huacai Chen
Cc: WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang, hejinyang, zhangqing
Name "guess unwinder" comes from x86, It scans the stack and reports
every kernel text address it finds.
Three stages when we do unwind,
(1)unwind_start(), the prapare of unwinding, fill unwind_state.
(2)unwind_done(), judge whether the unwind process is finished or not.
(3)unwind_next_frame(), unwind the next frame.
Make the dump_stack process go through unwind process.
Add get_stack_info() to get stack info. At present we have irq stack and
task stack. Maybe add another type in future. The next_sp means the key
info between this type stack and next type stack.
Dividing unwinder helps to add new unwinders in the future.
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
arch/loongarch/Kconfig.debug | 9 ++++
arch/loongarch/include/asm/stacktrace.h | 17 +++++++
arch/loongarch/include/asm/unwind.h | 37 ++++++++++++++
arch/loongarch/kernel/Makefile | 2 +
arch/loongarch/kernel/process.c | 61 +++++++++++++++++++++++
arch/loongarch/kernel/traps.c | 22 ++++-----
arch/loongarch/kernel/unwind_guess.c | 65 +++++++++++++++++++++++++
7 files changed, 202 insertions(+), 11 deletions(-)
create mode 100644 arch/loongarch/include/asm/unwind.h
create mode 100644 arch/loongarch/kernel/unwind_guess.c
diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
index e69de29bb2d1..68634d4fa27b 100644
--- a/arch/loongarch/Kconfig.debug
+++ b/arch/loongarch/Kconfig.debug
@@ -0,0 +1,9 @@
+config UNWINDER_GUESS
+ bool "Guess unwinder"
+ help
+ This option enables the "guess" unwinder for unwinding kernel stack
+ traces. It scans the stack and reports every kernel text address it
+ finds. Some of the addresses it reports may be incorrect.
+
+ While this option often produces false positives, it can still be
+ useful in many cases.
diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
index 6b5c2a7aa706..49cb89213aeb 100644
--- a/arch/loongarch/include/asm/stacktrace.h
+++ b/arch/loongarch/include/asm/stacktrace.h
@@ -10,6 +10,23 @@
#include <asm/loongarch.h>
#include <linux/stringify.h>
+enum stack_type {
+ STACK_TYPE_UNKNOWN,
+ STACK_TYPE_TASK,
+ STACK_TYPE_IRQ,
+};
+
+struct stack_info {
+ enum stack_type type;
+ unsigned long begin, end, next_sp;
+};
+
+bool in_task_stack(unsigned long stack, struct task_struct *task,
+ struct stack_info *info);
+bool in_irq_stack(unsigned long stack, struct stack_info *info);
+int get_stack_info(unsigned long stack, struct task_struct *task,
+ struct stack_info *info);
+
#define STR_LONG_L __stringify(LONG_L)
#define STR_LONG_S __stringify(LONG_S)
#define STR_LONGSIZE __stringify(LONGSIZE)
diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
new file mode 100644
index 000000000000..243330b39d0d
--- /dev/null
+++ b/arch/loongarch/include/asm/unwind.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Most of this ideas comes from x86.
+ *
+ * Copyright (C) 2022 Loongson Technology Corporation Limited
+ */
+#ifndef _ASM_UNWIND_H
+#define _ASM_UNWIND_H
+
+#include <linux/sched.h>
+
+#include <asm/stacktrace.h>
+
+struct unwind_state {
+ struct stack_info stack_info;
+ struct task_struct *task;
+ unsigned long sp, pc;
+ bool first;
+ bool error;
+};
+
+void unwind_start(struct unwind_state *state, struct task_struct *task,
+ struct pt_regs *regs);
+bool unwind_next_frame(struct unwind_state *state);
+unsigned long unwind_get_return_address(struct unwind_state *state);
+
+static inline bool unwind_done(struct unwind_state *state)
+{
+ return state->stack_info.type == STACK_TYPE_UNKNOWN;
+}
+
+static inline bool unwind_error(struct unwind_state *state)
+{
+ return state->error;
+}
+
+#endif /* _ASM_UNWIND_H */
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 940de9173542..c5fa4adb23b6 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -22,4 +22,6 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_NUMA) += numa.o
+obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
+
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index bfa0dfe8b7d7..709b7a1664f8 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -44,6 +44,7 @@
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/reg.h>
+#include <asm/unwind.h>
#include <asm/vdso.h>
/*
@@ -183,6 +184,66 @@ unsigned long __get_wchan(struct task_struct *task)
return 0;
}
+bool in_task_stack(unsigned long stack, struct task_struct *task,
+ struct stack_info *info)
+{
+ unsigned long begin = (unsigned long)task_stack_page(task);
+ unsigned long end = begin + THREAD_SIZE - 32;
+
+ if (stack < begin || stack >= end)
+ return false;
+
+ info->type = STACK_TYPE_TASK;
+ info->begin = begin;
+ info->end = end;
+ info->next_sp = 0;
+
+ return true;
+}
+
+bool in_irq_stack(unsigned long stack, struct stack_info *info)
+{
+ unsigned long nextsp;
+ unsigned long begin = (unsigned long)this_cpu_read(irq_stack);
+ unsigned long end = begin + IRQ_STACK_START;
+
+ if (stack < begin || stack >= end)
+ return false;
+
+ nextsp = *(unsigned long *)end;
+ if (nextsp & (SZREG - 1))
+ return false;
+
+ info->type = STACK_TYPE_IRQ;
+ info->begin = begin;
+ info->end = end;
+ info->next_sp = nextsp;
+
+ return true;
+}
+
+int get_stack_info(unsigned long stack, struct task_struct *task,
+ struct stack_info *info)
+{
+ task = task ? : current;
+
+ if (!stack || stack & (SZREG - 1))
+ goto unknown;
+
+ if (in_task_stack(stack, task, info))
+ return 0;
+
+ if (task != current)
+ goto unknown;
+
+ if (in_irq_stack(stack, info))
+ return 0;
+
+unknown:
+ info->type = STACK_TYPE_UNKNOWN;
+ return -EINVAL;
+}
+
unsigned long stack_top(void)
{
unsigned long top = TASK_SIZE & PAGE_MASK;
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index 1bf58c65e2bf..ef2c3aeb1dab 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -43,6 +43,7 @@
#include <asm/stacktrace.h>
#include <asm/tlb.h>
#include <asm/types.h>
+#include <asm/unwind.h>
#include "access-helper.h"
@@ -64,19 +65,18 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
const char *loglvl, bool user)
{
unsigned long addr;
- unsigned long *sp = (unsigned long *)(regs->regs[3] & ~3);
+ struct unwind_state state;
+ struct pt_regs *pregs = (struct pt_regs *)regs;
+
+ if (!task)
+ task = current;
+
+ unwind_start(&state, task, pregs);
printk("%sCall Trace:", loglvl);
-#ifdef CONFIG_KALLSYMS
- printk("%s\n", loglvl);
-#endif
- while (!kstack_end(sp)) {
- if (__get_addr(&addr, sp++, user)) {
- printk("%s (Bad stack address)", loglvl);
- break;
- }
- if (__kernel_text_address(addr))
- print_ip_sym(loglvl, addr);
+ for (; !unwind_done(&state); unwind_next_frame(&state)) {
+ addr = unwind_get_return_address(&state);
+ print_ip_sym(loglvl, addr);
}
printk("%s\n", loglvl);
}
diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/unwind_guess.c
new file mode 100644
index 000000000000..7eeb3e1a989d
--- /dev/null
+++ b/arch/loongarch/kernel/unwind_guess.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Loongson Technology Corporation Limited
+ */
+#include <linux/kernel.h>
+
+#include <asm/unwind.h>
+
+unsigned long unwind_get_return_address(struct unwind_state *state)
+{
+ if (unwind_done(state))
+ return 0;
+ else if (state->first)
+ return state->pc;
+
+ return *(unsigned long *)(state->sp);
+}
+EXPORT_SYMBOL_GPL(unwind_get_return_address);
+
+bool unwind_next_frame(struct unwind_state *state)
+{
+ struct stack_info *info = &state->stack_info;
+ unsigned long addr;
+
+ if (unwind_done(state))
+ return false;
+
+ if (state->first)
+ state->first = false;
+
+ do {
+ for (state->sp += sizeof(unsigned long);
+ state->sp < info->end;
+ state->sp += sizeof(unsigned long)) {
+ addr = *(unsigned long *)(state->sp);
+
+ if (__kernel_text_address(addr))
+ return true;
+ }
+
+ state->sp = info->next_sp;
+
+ } while (!get_stack_info(state->sp, state->task, info));
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(unwind_next_frame);
+
+void unwind_start(struct unwind_state *state, struct task_struct *task,
+ struct pt_regs *regs)
+{
+ memset(state, 0, sizeof(*state));
+
+ state->task = task;
+
+ state->sp = regs->regs[3];
+ state->pc = regs->csr_era;
+ state->first = true;
+
+ get_stack_info(state->sp, state->task, &state->stack_info);
+
+ if (!unwind_done(state) && !__kernel_text_address(state->pc))
+ unwind_next_frame(state);
+}
+EXPORT_SYMBOL_GPL(unwind_start);
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/4] LoongArch: Add guess unwinder support
2022-08-01 12:17 ` [PATCH 1/4] LoongArch: Add guess " Qing Zhang
@ 2022-08-01 15:28 ` Huacai Chen
0 siblings, 0 replies; 21+ messages in thread
From: Huacai Chen @ 2022-08-01 15:28 UTC (permalink / raw)
To: Qing Zhang; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>
> Name "guess unwinder" comes from x86, It scans the stack and reports
> every kernel text address it finds.
>
> Three stages when we do unwind,
> (1)unwind_start(), the prapare of unwinding, fill unwind_state.
> (2)unwind_done(), judge whether the unwind process is finished or not.
> (3)unwind_next_frame(), unwind the next frame.
>
> Make the dump_stack process go through unwind process.
> Add get_stack_info() to get stack info. At present we have irq stack and
> task stack. Maybe add another type in future. The next_sp means the key
> info between this type stack and next type stack.
>
> Dividing unwinder helps to add new unwinders in the future.
>
> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> ---
> arch/loongarch/Kconfig.debug | 9 ++++
> arch/loongarch/include/asm/stacktrace.h | 17 +++++++
> arch/loongarch/include/asm/unwind.h | 37 ++++++++++++++
> arch/loongarch/kernel/Makefile | 2 +
> arch/loongarch/kernel/process.c | 61 +++++++++++++++++++++++
> arch/loongarch/kernel/traps.c | 22 ++++-----
> arch/loongarch/kernel/unwind_guess.c | 65 +++++++++++++++++++++++++
> 7 files changed, 202 insertions(+), 11 deletions(-)
> create mode 100644 arch/loongarch/include/asm/unwind.h
> create mode 100644 arch/loongarch/kernel/unwind_guess.c
>
> diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
> index e69de29bb2d1..68634d4fa27b 100644
> --- a/arch/loongarch/Kconfig.debug
> +++ b/arch/loongarch/Kconfig.debug
> @@ -0,0 +1,9 @@
> +config UNWINDER_GUESS
> + bool "Guess unwinder"
> + help
> + This option enables the "guess" unwinder for unwinding kernel stack
> + traces. It scans the stack and reports every kernel text address it
> + finds. Some of the addresses it reports may be incorrect.
> +
> + While this option often produces false positives, it can still be
> + useful in many cases.
> diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
> index 6b5c2a7aa706..49cb89213aeb 100644
> --- a/arch/loongarch/include/asm/stacktrace.h
> +++ b/arch/loongarch/include/asm/stacktrace.h
> @@ -10,6 +10,23 @@
> #include <asm/loongarch.h>
> #include <linux/stringify.h>
>
> +enum stack_type {
> + STACK_TYPE_UNKNOWN,
> + STACK_TYPE_TASK,
> + STACK_TYPE_IRQ,
> +};
> +
> +struct stack_info {
> + enum stack_type type;
> + unsigned long begin, end, next_sp;
> +};
> +
> +bool in_task_stack(unsigned long stack, struct task_struct *task,
> + struct stack_info *info);
> +bool in_irq_stack(unsigned long stack, struct stack_info *info);
> +int get_stack_info(unsigned long stack, struct task_struct *task,
> + struct stack_info *info);
> +
> #define STR_LONG_L __stringify(LONG_L)
> #define STR_LONG_S __stringify(LONG_S)
> #define STR_LONGSIZE __stringify(LONGSIZE)
> diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
> new file mode 100644
> index 000000000000..243330b39d0d
> --- /dev/null
> +++ b/arch/loongarch/include/asm/unwind.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Most of this ideas comes from x86.
> + *
> + * Copyright (C) 2022 Loongson Technology Corporation Limited
> + */
> +#ifndef _ASM_UNWIND_H
> +#define _ASM_UNWIND_H
> +
> +#include <linux/sched.h>
> +
> +#include <asm/stacktrace.h>
> +
> +struct unwind_state {
> + struct stack_info stack_info;
> + struct task_struct *task;
> + unsigned long sp, pc;
> + bool first;
> + bool error;
> +};
> +
> +void unwind_start(struct unwind_state *state, struct task_struct *task,
> + struct pt_regs *regs);
> +bool unwind_next_frame(struct unwind_state *state);
> +unsigned long unwind_get_return_address(struct unwind_state *state);
> +
> +static inline bool unwind_done(struct unwind_state *state)
> +{
> + return state->stack_info.type == STACK_TYPE_UNKNOWN;
> +}
> +
> +static inline bool unwind_error(struct unwind_state *state)
> +{
> + return state->error;
> +}
> +
> +#endif /* _ASM_UNWIND_H */
> diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
> index 940de9173542..c5fa4adb23b6 100644
> --- a/arch/loongarch/kernel/Makefile
> +++ b/arch/loongarch/kernel/Makefile
> @@ -22,4 +22,6 @@ obj-$(CONFIG_SMP) += smp.o
>
> obj-$(CONFIG_NUMA) += numa.o
>
> +obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
> +
> CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
> diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
> index bfa0dfe8b7d7..709b7a1664f8 100644
> --- a/arch/loongarch/kernel/process.c
> +++ b/arch/loongarch/kernel/process.c
> @@ -44,6 +44,7 @@
> #include <asm/pgtable.h>
> #include <asm/processor.h>
> #include <asm/reg.h>
> +#include <asm/unwind.h>
> #include <asm/vdso.h>
>
> /*
> @@ -183,6 +184,66 @@ unsigned long __get_wchan(struct task_struct *task)
> return 0;
> }
>
> +bool in_task_stack(unsigned long stack, struct task_struct *task,
> + struct stack_info *info)
> +{
> + unsigned long begin = (unsigned long)task_stack_page(task);
> + unsigned long end = begin + THREAD_SIZE - 32;
> +
> + if (stack < begin || stack >= end)
> + return false;
> +
> + info->type = STACK_TYPE_TASK;
> + info->begin = begin;
> + info->end = end;
> + info->next_sp = 0;
> +
> + return true;
> +}
> +
> +bool in_irq_stack(unsigned long stack, struct stack_info *info)
> +{
> + unsigned long nextsp;
> + unsigned long begin = (unsigned long)this_cpu_read(irq_stack);
> + unsigned long end = begin + IRQ_STACK_START;
> +
> + if (stack < begin || stack >= end)
> + return false;
> +
> + nextsp = *(unsigned long *)end;
> + if (nextsp & (SZREG - 1))
> + return false;
> +
> + info->type = STACK_TYPE_IRQ;
> + info->begin = begin;
> + info->end = end;
> + info->next_sp = nextsp;
> +
> + return true;
> +}
> +
> +int get_stack_info(unsigned long stack, struct task_struct *task,
> + struct stack_info *info)
> +{
> + task = task ? : current;
> +
> + if (!stack || stack & (SZREG - 1))
> + goto unknown;
> +
> + if (in_task_stack(stack, task, info))
> + return 0;
> +
> + if (task != current)
> + goto unknown;
> +
> + if (in_irq_stack(stack, info))
> + return 0;
> +
> +unknown:
> + info->type = STACK_TYPE_UNKNOWN;
> + return -EINVAL;
> +}
> +
> unsigned long stack_top(void)
> {
> unsigned long top = TASK_SIZE & PAGE_MASK;
> diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
> index 1bf58c65e2bf..ef2c3aeb1dab 100644
> --- a/arch/loongarch/kernel/traps.c
> +++ b/arch/loongarch/kernel/traps.c
> @@ -43,6 +43,7 @@
> #include <asm/stacktrace.h>
> #include <asm/tlb.h>
> #include <asm/types.h>
> +#include <asm/unwind.h>
>
> #include "access-helper.h"
>
> @@ -64,19 +65,18 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
> const char *loglvl, bool user)
> {
> unsigned long addr;
> - unsigned long *sp = (unsigned long *)(regs->regs[3] & ~3);
> + struct unwind_state state;
> + struct pt_regs *pregs = (struct pt_regs *)regs;
> +
> + if (!task)
> + task = current;
> +
> + unwind_start(&state, task, pregs);
>
> printk("%sCall Trace:", loglvl);
> -#ifdef CONFIG_KALLSYMS
> - printk("%s\n", loglvl);
> -#endif
They should be after unwind_start()? If not, moving unwind_start() to
the for-loop seems better.
> - while (!kstack_end(sp)) {
> - if (__get_addr(&addr, sp++, user)) {
> - printk("%s (Bad stack address)", loglvl);
> - break;
> - }
> - if (__kernel_text_address(addr))
> - print_ip_sym(loglvl, addr);
> + for (; !unwind_done(&state); unwind_next_frame(&state)) {
> + addr = unwind_get_return_address(&state);
> + print_ip_sym(loglvl, addr);
> }
> printk("%s\n", loglvl);
> }
> diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/unwind_guess.c
> new file mode 100644
> index 000000000000..7eeb3e1a989d
> --- /dev/null
> +++ b/arch/loongarch/kernel/unwind_guess.c
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 Loongson Technology Corporation Limited
> + */
> +#include <linux/kernel.h>
> +
> +#include <asm/unwind.h>
> +
> +unsigned long unwind_get_return_address(struct unwind_state *state)
> +{
> + if (unwind_done(state))
> + return 0;
> + else if (state->first)
> + return state->pc;
> +
> + return *(unsigned long *)(state->sp);
> +}
> +EXPORT_SYMBOL_GPL(unwind_get_return_address);
> +
> +bool unwind_next_frame(struct unwind_state *state)
> +{
> + struct stack_info *info = &state->stack_info;
> + unsigned long addr;
> +
> + if (unwind_done(state))
> + return false;
> +
> + if (state->first)
> + state->first = false;
> +
> + do {
> + for (state->sp += sizeof(unsigned long);
> + state->sp < info->end;
> + state->sp += sizeof(unsigned long)) {
> + addr = *(unsigned long *)(state->sp);
> +
> + if (__kernel_text_address(addr))
> + return true;
> + }
> +
> + state->sp = info->next_sp;
> +
> + } while (!get_stack_info(state->sp, state->task, info));
> +
> + return false;
> +}
> +EXPORT_SYMBOL_GPL(unwind_next_frame);
Move this function after unwind_start() seems more natural.
Huacai
> +
> +void unwind_start(struct unwind_state *state, struct task_struct *task,
> + struct pt_regs *regs)
> +{
> + memset(state, 0, sizeof(*state));
> +
> + state->task = task;
> +
> + state->sp = regs->regs[3];
> + state->pc = regs->csr_era;
> + state->first = true;
> +
> + get_stack_info(state->sp, state->task, &state->stack_info);
> +
> + if (!unwind_done(state) && !__kernel_text_address(state->pc))
> + unwind_next_frame(state);
> +}
> +EXPORT_SYMBOL_GPL(unwind_start);
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-01 12:17 [PATCH 0/4] LoongArch: Add unwinder support Qing Zhang
2022-08-01 12:17 ` [PATCH 1/4] LoongArch: Add guess " Qing Zhang
@ 2022-08-01 12:17 ` Qing Zhang
2022-08-01 15:26 ` Huacai Chen
2022-08-01 12:17 ` [PATCH 3/4] LoongArch: Add stacktrace support Qing Zhang
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Qing Zhang @ 2022-08-01 12:17 UTC (permalink / raw)
To: Huacai Chen
Cc: WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang, hejinyang, zhangqing
It unwind the stack frame based on prologue code analyze.
CONFIG_KALLSYMS is needed, at least the address and length
of each function.
Three stages when we do unwind,
(1)unwind_start(), the prapare of unwinding, fill unwind_state.
(2)unwind_done(), judge whether the unwind process is finished or not.
(3)unwind_next_frame(), unwind the next frame.
Dividing unwinder helps to add new unwinders in the future, eg:
unwind_frame, unwind_orc .etc
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
arch/loongarch/Kconfig.debug | 19 +++
arch/loongarch/include/asm/inst.h | 52 +++++++
arch/loongarch/include/asm/unwind.h | 8 ++
arch/loongarch/kernel/Makefile | 1 +
arch/loongarch/kernel/traps.c | 5 +
arch/loongarch/kernel/unwind_prologue.c | 172 ++++++++++++++++++++++++
6 files changed, 257 insertions(+)
create mode 100644 arch/loongarch/kernel/unwind_prologue.c
diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
index 68634d4fa27b..57cdbe0cfd98 100644
--- a/arch/loongarch/Kconfig.debug
+++ b/arch/loongarch/Kconfig.debug
@@ -1,3 +1,11 @@
+choice
+ prompt "Choose kernel unwinder"
+ default UNWINDER_PROLOGUE if KALLSYMS
+ help
+ This determines which method will be used for unwinding kernel stack
+ traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
+ lockdep, and more.
+
config UNWINDER_GUESS
bool "Guess unwinder"
help
@@ -7,3 +15,14 @@ config UNWINDER_GUESS
While this option often produces false positives, it can still be
useful in many cases.
+
+config UNWINDER_PROLOGUE
+ bool "Prologue unwinder"
+ depends on KALLSYMS
+ help
+ This option enables the "prologue" unwinder for unwinding kernel stack
+ traces. It unwind the stack frame based on prologue code analyze. Symbol
+ information is needed, at least the address and length of each function.
+ Some of the addresses it reports may be incorrect.
+
+endchoice
diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
index 575d1bb66ffb..b876907ca65a 100644
--- a/arch/loongarch/include/asm/inst.h
+++ b/arch/loongarch/include/asm/inst.h
@@ -23,12 +23,33 @@ enum reg1i20_op {
lu32id_op = 0x0b,
};
+enum reg1i21_op {
+ beqz_op = 0x10,
+ bnez_op = 0x11,
+};
+
enum reg2i12_op {
+ addiw_op = 0x0a,
+ addid_op = 0x0b,
lu52id_op = 0x0c,
+ ldb_op = 0xa0,
+ ldh_op = 0xa1,
+ ldw_op = 0xa2,
+ ldd_op = 0xa3,
+ stb_op = 0xa4,
+ sth_op = 0xa5,
+ stw_op = 0xa6,
+ std_op = 0xa7,
};
enum reg2i16_op {
jirl_op = 0x13,
+ beq_op = 0x16,
+ bne_op = 0x17,
+ blt_op = 0x18,
+ bge_op = 0x19,
+ bltu_op = 0x1a,
+ bgeu_op = 0x1b,
};
struct reg0i26_format {
@@ -110,6 +131,37 @@ enum loongarch_gpr {
LOONGARCH_GPR_MAX
};
+#define is_imm12_negative(val) is_imm_negative(val, 12)
+
+static inline bool is_imm_negative(unsigned long val, unsigned int bit)
+{
+ return val & (1UL << (bit - 1));
+}
+
+static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
+{
+ /* addi.d $sp, $sp, -imm */
+ return ip->reg2i12_format.opcode == addid_op &&
+ ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
+ ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
+ is_imm12_negative(ip->reg2i12_format.immediate);
+}
+
+static inline bool is_ra_save_ins(union loongarch_instruction *ip)
+{
+ /* st.d $ra, $sp, offset */
+ return ip->reg2i12_format.opcode == std_op &&
+ ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
+ ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
+ !is_imm12_negative(ip->reg2i12_format.immediate);
+}
+
+static inline bool is_branch_insn(union loongarch_instruction insn)
+{
+ return insn.reg1i21_format.opcode >= beqz_op &&
+ insn.reg1i21_format.opcode <= bgeu_op;
+}
+
u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest);
diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
index 243330b39d0d..f9f73a26504e 100644
--- a/arch/loongarch/include/asm/unwind.h
+++ b/arch/loongarch/include/asm/unwind.h
@@ -14,6 +14,14 @@
struct unwind_state {
struct stack_info stack_info;
struct task_struct *task;
+#if defined(CONFIG_UNWINDER_PROLOGUE)
+ unsigned long ra;
+ bool enable;
+ /*
+ * Enable is the prologue analysis method
+ * otherwise is the way to guess.
+ */
+#endif
unsigned long sp, pc;
bool first;
bool error;
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index c5fa4adb23b6..918600e7b30f 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -23,5 +23,6 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
+obj-$(CONFIG_UNWINDER_PROLOGUE) += unwind_prologue.o
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index ef2c3aeb1dab..3e904fa12d48 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -73,6 +73,11 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
unwind_start(&state, task, pregs);
+#ifdef CONFIG_UNWINDER_PROLOGUE
+ if (user_mode(regs))
+ state.enable = false;
+#endif
+
printk("%sCall Trace:", loglvl);
for (; !unwind_done(&state); unwind_next_frame(&state)) {
addr = unwind_get_return_address(&state);
diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
new file mode 100644
index 000000000000..072d1f7bf4ac
--- /dev/null
+++ b/arch/loongarch/kernel/unwind_prologue.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Loongson Technology Corporation Limited
+ */
+#include <linux/kallsyms.h>
+
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/unwind.h>
+
+unsigned long unwind_get_return_address(struct unwind_state *state)
+{
+
+ if (unwind_done(state))
+ return 0;
+ else if (state->enable)
+ return state->pc;
+ else if (state->first)
+ return state->pc;
+
+ return *(unsigned long *)(state->sp);
+
+}
+EXPORT_SYMBOL_GPL(unwind_get_return_address);
+
+static bool unwind_by_prologue(struct unwind_state *state)
+{
+ struct stack_info *info = &state->stack_info;
+ union loongarch_instruction *ip, *ip_end;
+ unsigned long frame_size = 0, frame_ra = -1;
+ unsigned long size, offset, pc = state->pc;
+
+ if (state->sp >= info->end || state->sp < info->begin)
+ return false;
+
+ if (!kallsyms_lookup_size_offset(pc, &size, &offset))
+ return false;
+
+ ip = (union loongarch_instruction *)(pc - offset);
+ ip_end = (union loongarch_instruction *)pc;
+
+ while (ip < ip_end) {
+ if (is_stack_alloc_ins(ip)) {
+ frame_size = (1 << 12) - ip->reg2i12_format.immediate;
+ ip++;
+ break;
+ }
+ ip++;
+ }
+
+ if (!frame_size) {
+ if (state->first)
+ goto first;
+
+ return false;
+ }
+
+ while (ip < ip_end) {
+ if (is_ra_save_ins(ip)) {
+ frame_ra = ip->reg2i12_format.immediate;
+ break;
+ }
+ if (is_branch_insn(*ip))
+ break;
+ ip++;
+ }
+
+ if (frame_ra < 0) {
+ if (state->first) {
+ state->sp = state->sp + frame_size;
+ goto first;
+ }
+ return false;
+ }
+
+ if (state->first)
+ state->first = false;
+
+ state->pc = *(unsigned long *)(state->sp + frame_ra);
+ state->sp = state->sp + frame_size;
+ return !!__kernel_text_address(state->pc);
+
+first:
+ state->first = false;
+ if (state->pc == state->ra)
+ return false;
+
+ state->pc = state->ra;
+
+ return !!__kernel_text_address(state->ra);
+}
+
+static bool unwind_by_guess(struct unwind_state *state)
+{
+ struct stack_info *info = &state->stack_info;
+ unsigned long addr;
+
+ for (state->sp += sizeof(unsigned long);
+ state->sp < info->end;
+ state->sp += sizeof(unsigned long)) {
+ addr = *(unsigned long *)(state->sp);
+ if (__kernel_text_address(addr))
+ return true;
+ }
+
+ return false;
+}
+
+bool unwind_next_frame(struct unwind_state *state)
+{
+ struct stack_info *info = &state->stack_info;
+ struct pt_regs *regs;
+ unsigned long pc;
+
+ if (unwind_done(state))
+ return false;
+
+ do {
+ if (state->enable) {
+ if (unwind_by_prologue(state))
+ return true;
+
+ if (info->type == STACK_TYPE_IRQ &&
+ info->end == state->sp) {
+ regs = (struct pt_regs *)info->next_sp;
+ pc = regs->csr_era;
+ if (user_mode(regs) || !__kernel_text_address(pc))
+ return false;
+
+ state->pc = pc;
+ state->sp = regs->regs[3];
+ state->ra = regs->regs[1];
+ state->first = true;
+ get_stack_info(state->sp, state->task, info);
+
+ return true;
+ }
+ } else {
+ if (state->first)
+ state->first = false;
+ else if (unwind_by_guess(state))
+ return true;
+ }
+
+ state->sp = info->next_sp;
+
+ } while (!get_stack_info(state->sp, state->task, info));
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(unwind_next_frame);
+
+void unwind_start(struct unwind_state *state, struct task_struct *task,
+ struct pt_regs *regs)
+{
+ memset(state, 0, sizeof(*state));
+
+ if (__kernel_text_address(regs->csr_era))
+ state->enable = true;
+
+ state->task = task;
+ state->pc = regs->csr_era;
+ state->sp = regs->regs[3];
+ state->ra = regs->regs[1];
+ state->first = true;
+
+ get_stack_info(state->sp, state->task, &state->stack_info);
+
+ if (!unwind_done(state) && !__kernel_text_address(state->pc))
+ unwind_next_frame(state);
+}
+EXPORT_SYMBOL_GPL(unwind_start);
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-01 12:17 ` [PATCH 2/4] LoongArch: Add prologue " Qing Zhang
@ 2022-08-01 15:26 ` Huacai Chen
2022-08-02 1:30 ` Youling Tang
0 siblings, 1 reply; 21+ messages in thread
From: Huacai Chen @ 2022-08-01 15:26 UTC (permalink / raw)
To: Qing Zhang; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>
> It unwind the stack frame based on prologue code analyze.
> CONFIG_KALLSYMS is needed, at least the address and length
> of each function.
>
> Three stages when we do unwind,
> (1)unwind_start(), the prapare of unwinding, fill unwind_state.
> (2)unwind_done(), judge whether the unwind process is finished or not.
> (3)unwind_next_frame(), unwind the next frame.
>
> Dividing unwinder helps to add new unwinders in the future, eg:
> unwind_frame, unwind_orc .etc
>
> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> ---
> arch/loongarch/Kconfig.debug | 19 +++
> arch/loongarch/include/asm/inst.h | 52 +++++++
> arch/loongarch/include/asm/unwind.h | 8 ++
> arch/loongarch/kernel/Makefile | 1 +
> arch/loongarch/kernel/traps.c | 5 +
> arch/loongarch/kernel/unwind_prologue.c | 172 ++++++++++++++++++++++++
> 6 files changed, 257 insertions(+)
> create mode 100644 arch/loongarch/kernel/unwind_prologue.c
>
> diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
> index 68634d4fa27b..57cdbe0cfd98 100644
> --- a/arch/loongarch/Kconfig.debug
> +++ b/arch/loongarch/Kconfig.debug
> @@ -1,3 +1,11 @@
> +choice
> + prompt "Choose kernel unwinder"
> + default UNWINDER_PROLOGUE if KALLSYMS
> + help
> + This determines which method will be used for unwinding kernel stack
> + traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
> + lockdep, and more.
> +
> config UNWINDER_GUESS
> bool "Guess unwinder"
> help
> @@ -7,3 +15,14 @@ config UNWINDER_GUESS
>
> While this option often produces false positives, it can still be
> useful in many cases.
> +
> +config UNWINDER_PROLOGUE
> + bool "Prologue unwinder"
> + depends on KALLSYMS
> + help
> + This option enables the "prologue" unwinder for unwinding kernel stack
> + traces. It unwind the stack frame based on prologue code analyze. Symbol
> + information is needed, at least the address and length of each function.
> + Some of the addresses it reports may be incorrect.
> +
> +endchoice
> diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
> index 575d1bb66ffb..b876907ca65a 100644
> --- a/arch/loongarch/include/asm/inst.h
> +++ b/arch/loongarch/include/asm/inst.h
> @@ -23,12 +23,33 @@ enum reg1i20_op {
> lu32id_op = 0x0b,
> };
>
> +enum reg1i21_op {
> + beqz_op = 0x10,
> + bnez_op = 0x11,
> +};
> +
> enum reg2i12_op {
> + addiw_op = 0x0a,
> + addid_op = 0x0b,
> lu52id_op = 0x0c,
> + ldb_op = 0xa0,
> + ldh_op = 0xa1,
> + ldw_op = 0xa2,
> + ldd_op = 0xa3,
> + stb_op = 0xa4,
> + sth_op = 0xa5,
> + stw_op = 0xa6,
> + std_op = 0xa7,
> };
>
> enum reg2i16_op {
> jirl_op = 0x13,
> + beq_op = 0x16,
> + bne_op = 0x17,
> + blt_op = 0x18,
> + bge_op = 0x19,
> + bltu_op = 0x1a,
> + bgeu_op = 0x1b,
> };
>
> struct reg0i26_format {
> @@ -110,6 +131,37 @@ enum loongarch_gpr {
> LOONGARCH_GPR_MAX
> };
>
> +#define is_imm12_negative(val) is_imm_negative(val, 12)
> +
> +static inline bool is_imm_negative(unsigned long val, unsigned int bit)
> +{
> + return val & (1UL << (bit - 1));
> +}
> +
> +static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
> +{
> + /* addi.d $sp, $sp, -imm */
> + return ip->reg2i12_format.opcode == addid_op &&
> + ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
> + ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
> + is_imm12_negative(ip->reg2i12_format.immediate);
> +}
> +
> +static inline bool is_ra_save_ins(union loongarch_instruction *ip)
> +{
> + /* st.d $ra, $sp, offset */
> + return ip->reg2i12_format.opcode == std_op &&
> + ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
> + ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
> + !is_imm12_negative(ip->reg2i12_format.immediate);
> +}
> +
> +static inline bool is_branch_insn(union loongarch_instruction insn)
> +{
> + return insn.reg1i21_format.opcode >= beqz_op &&
> + insn.reg1i21_format.opcode <= bgeu_op;
> +}
> +
> u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
> u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
> u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest);
> diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
> index 243330b39d0d..f9f73a26504e 100644
> --- a/arch/loongarch/include/asm/unwind.h
> +++ b/arch/loongarch/include/asm/unwind.h
> @@ -14,6 +14,14 @@
> struct unwind_state {
> struct stack_info stack_info;
> struct task_struct *task;
> +#if defined(CONFIG_UNWINDER_PROLOGUE)
> + unsigned long ra;
> + bool enable;
> + /*
> + * Enable is the prologue analysis method
> + * otherwise is the way to guess.
> + */
> +#endif
> unsigned long sp, pc;
> bool first;
> bool error;
This data struct makes me very uncomfortable, especially "enable" and
the #ifdef, maybe we can rework it like this?
#define UNWINDER_GUESS 0
#define UNWINDER_PROLOGURE 1
struct unwind_state {
char type; /* UNWINDER_xxx */
bool first, error;
unsigned long sp, pc, ra;
struct task_struct *task;
struct stack_info stack_info;
};
Huacai
> diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
> index c5fa4adb23b6..918600e7b30f 100644
> --- a/arch/loongarch/kernel/Makefile
> +++ b/arch/loongarch/kernel/Makefile
> @@ -23,5 +23,6 @@ obj-$(CONFIG_SMP) += smp.o
> obj-$(CONFIG_NUMA) += numa.o
>
> obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
> +obj-$(CONFIG_UNWINDER_PROLOGUE) += unwind_prologue.o
>
> CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
> diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
> index ef2c3aeb1dab..3e904fa12d48 100644
> --- a/arch/loongarch/kernel/traps.c
> +++ b/arch/loongarch/kernel/traps.c
> @@ -73,6 +73,11 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
>
> unwind_start(&state, task, pregs);
>
> +#ifdef CONFIG_UNWINDER_PROLOGUE
> + if (user_mode(regs))
> + state.enable = false;
> +#endif
> +
> printk("%sCall Trace:", loglvl);
> for (; !unwind_done(&state); unwind_next_frame(&state)) {
> addr = unwind_get_return_address(&state);
> diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
> new file mode 100644
> index 000000000000..072d1f7bf4ac
> --- /dev/null
> +++ b/arch/loongarch/kernel/unwind_prologue.c
> @@ -0,0 +1,172 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 Loongson Technology Corporation Limited
> + */
> +#include <linux/kallsyms.h>
> +
> +#include <asm/inst.h>
> +#include <asm/ptrace.h>
> +#include <asm/unwind.h>
> +
> +unsigned long unwind_get_return_address(struct unwind_state *state)
> +{
> +
> + if (unwind_done(state))
> + return 0;
> + else if (state->enable)
> + return state->pc;
> + else if (state->first)
> + return state->pc;
> +
> + return *(unsigned long *)(state->sp);
> +
> +}
> +EXPORT_SYMBOL_GPL(unwind_get_return_address);
> +
> +static bool unwind_by_prologue(struct unwind_state *state)
> +{
> + struct stack_info *info = &state->stack_info;
> + union loongarch_instruction *ip, *ip_end;
> + unsigned long frame_size = 0, frame_ra = -1;
> + unsigned long size, offset, pc = state->pc;
> +
> + if (state->sp >= info->end || state->sp < info->begin)
> + return false;
> +
> + if (!kallsyms_lookup_size_offset(pc, &size, &offset))
> + return false;
> +
> + ip = (union loongarch_instruction *)(pc - offset);
> + ip_end = (union loongarch_instruction *)pc;
> +
> + while (ip < ip_end) {
> + if (is_stack_alloc_ins(ip)) {
> + frame_size = (1 << 12) - ip->reg2i12_format.immediate;
> + ip++;
> + break;
> + }
> + ip++;
> + }
> +
> + if (!frame_size) {
> + if (state->first)
> + goto first;
> +
> + return false;
> + }
> +
> + while (ip < ip_end) {
> + if (is_ra_save_ins(ip)) {
> + frame_ra = ip->reg2i12_format.immediate;
> + break;
> + }
> + if (is_branch_insn(*ip))
> + break;
> + ip++;
> + }
> +
> + if (frame_ra < 0) {
> + if (state->first) {
> + state->sp = state->sp + frame_size;
> + goto first;
> + }
> + return false;
> + }
> +
> + if (state->first)
> + state->first = false;
> +
> + state->pc = *(unsigned long *)(state->sp + frame_ra);
> + state->sp = state->sp + frame_size;
> + return !!__kernel_text_address(state->pc);
> +
> +first:
> + state->first = false;
> + if (state->pc == state->ra)
> + return false;
> +
> + state->pc = state->ra;
> +
> + return !!__kernel_text_address(state->ra);
> +}
> +
> +static bool unwind_by_guess(struct unwind_state *state)
> +{
> + struct stack_info *info = &state->stack_info;
> + unsigned long addr;
> +
> + for (state->sp += sizeof(unsigned long);
> + state->sp < info->end;
> + state->sp += sizeof(unsigned long)) {
> + addr = *(unsigned long *)(state->sp);
> + if (__kernel_text_address(addr))
> + return true;
> + }
> +
> + return false;
> +}
> +
> +bool unwind_next_frame(struct unwind_state *state)
> +{
> + struct stack_info *info = &state->stack_info;
> + struct pt_regs *regs;
> + unsigned long pc;
> +
> + if (unwind_done(state))
> + return false;
> +
> + do {
> + if (state->enable) {
> + if (unwind_by_prologue(state))
> + return true;
> +
> + if (info->type == STACK_TYPE_IRQ &&
> + info->end == state->sp) {
> + regs = (struct pt_regs *)info->next_sp;
> + pc = regs->csr_era;
> + if (user_mode(regs) || !__kernel_text_address(pc))
> + return false;
> +
> + state->pc = pc;
> + state->sp = regs->regs[3];
> + state->ra = regs->regs[1];
> + state->first = true;
> + get_stack_info(state->sp, state->task, info);
> +
> + return true;
> + }
> + } else {
> + if (state->first)
> + state->first = false;
> + else if (unwind_by_guess(state))
> + return true;
> + }
> +
> + state->sp = info->next_sp;
> +
> + } while (!get_stack_info(state->sp, state->task, info));
> +
> + return false;
> +}
> +EXPORT_SYMBOL_GPL(unwind_next_frame);
> +
> +void unwind_start(struct unwind_state *state, struct task_struct *task,
> + struct pt_regs *regs)
> +{
> + memset(state, 0, sizeof(*state));
> +
> + if (__kernel_text_address(regs->csr_era))
> + state->enable = true;
> +
> + state->task = task;
> + state->pc = regs->csr_era;
> + state->sp = regs->regs[3];
> + state->ra = regs->regs[1];
> + state->first = true;
> +
> + get_stack_info(state->sp, state->task, &state->stack_info);
> +
> + if (!unwind_done(state) && !__kernel_text_address(state->pc))
> + unwind_next_frame(state);
> +}
> +EXPORT_SYMBOL_GPL(unwind_start);
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-01 15:26 ` Huacai Chen
@ 2022-08-02 1:30 ` Youling Tang
2022-08-02 1:34 ` Huacai Chen
0 siblings, 1 reply; 21+ messages in thread
From: Youling Tang @ 2022-08-02 1:30 UTC (permalink / raw)
To: Huacai Chen, Qing Zhang
Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On 08/01/2022 11:26 PM, Huacai Chen wrote:
>> diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
>> index 243330b39d0d..f9f73a26504e 100644
>> --- a/arch/loongarch/include/asm/unwind.h
>> +++ b/arch/loongarch/include/asm/unwind.h
>> @@ -14,6 +14,14 @@
>> struct unwind_state {
>> struct stack_info stack_info;
>> struct task_struct *task;
>> +#if defined(CONFIG_UNWINDER_PROLOGUE)
>> + unsigned long ra;
>> + bool enable;
>> + /*
>> + * Enable is the prologue analysis method
>> + * otherwise is the way to guess.
>> + */
>> +#endif
>> unsigned long sp, pc;
>> bool first;
>> bool error;
> This data struct makes me very uncomfortable, especially "enable" and
> the #ifdef, maybe we can rework it like this?
>
> #define UNWINDER_GUESS 0
> #define UNWINDER_PROLOGURE 1
Maybe it's better to define with enum type?
enum unwind_type {
UNWINDER_GUESS,
UNWINDER_PROLOGURE,
};
Youling
> struct unwind_state {
> char type; /* UNWINDER_xxx */
> bool first, error;
> unsigned long sp, pc, ra;
> struct task_struct *task;
> struct stack_info stack_info;
> };
>
> Huacai
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-02 1:30 ` Youling Tang
@ 2022-08-02 1:34 ` Huacai Chen
2022-08-02 1:39 ` Xi Ruoyao
0 siblings, 1 reply; 21+ messages in thread
From: Huacai Chen @ 2022-08-02 1:34 UTC (permalink / raw)
To: Youling Tang
Cc: Qing Zhang, WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Youling,
On Tue, Aug 2, 2022 at 9:30 AM Youling Tang <tangyouling@loongson.cn> wrote:
>
>
>
> On 08/01/2022 11:26 PM, Huacai Chen wrote:
> >> diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
> >> index 243330b39d0d..f9f73a26504e 100644
> >> --- a/arch/loongarch/include/asm/unwind.h
> >> +++ b/arch/loongarch/include/asm/unwind.h
> >> @@ -14,6 +14,14 @@
> >> struct unwind_state {
> >> struct stack_info stack_info;
> >> struct task_struct *task;
> >> +#if defined(CONFIG_UNWINDER_PROLOGUE)
> >> + unsigned long ra;
> >> + bool enable;
> >> + /*
> >> + * Enable is the prologue analysis method
> >> + * otherwise is the way to guess.
> >> + */
> >> +#endif
> >> unsigned long sp, pc;
> >> bool first;
> >> bool error;
> > This data struct makes me very uncomfortable, especially "enable" and
> > the #ifdef, maybe we can rework it like this?
> >
> > #define UNWINDER_GUESS 0
> > #define UNWINDER_PROLOGURE 1
>
> Maybe it's better to define with enum type?
> enum unwind_type {
> UNWINDER_GUESS,
> UNWINDER_PROLOGURE,
> };
Both macro and enum are acceptable, but enum is essentially "int",
while the "type" member is "char" here.
Huacai
>
> Youling
>
> > struct unwind_state {
> > char type; /* UNWINDER_xxx */
> > bool first, error;
> > unsigned long sp, pc, ra;
> > struct task_struct *task;
> > struct stack_info stack_info;
> > };
> >
> > Huacai
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-02 1:34 ` Huacai Chen
@ 2022-08-02 1:39 ` Xi Ruoyao
2022-08-02 1:53 ` Huacai Chen
0 siblings, 1 reply; 21+ messages in thread
From: Xi Ruoyao @ 2022-08-02 1:39 UTC (permalink / raw)
To: Huacai Chen, Youling Tang
Cc: Qing Zhang, WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On Tue, 2022-08-02 at 09:34 +0800, Huacai Chen wrote:
> > > #define UNWINDER_GUESS 0
> > > #define UNWINDER_PROLOGURE 1
> >
> > Maybe it's better to define with enum type?
> > enum unwind_type {
> > UNWINDER_GUESS,
> > UNWINDER_PROLOGURE,
> > };
> Both macro and enum are acceptable, but enum is essentially "int",
> while the "type" member is "char" here.
"0" or "1" will also be "int" (C99 6.4.4.1 para 5).
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/4] LoongArch: Add prologue unwinder support
2022-08-02 1:39 ` Xi Ruoyao
@ 2022-08-02 1:53 ` Huacai Chen
0 siblings, 0 replies; 21+ messages in thread
From: Huacai Chen @ 2022-08-02 1:53 UTC (permalink / raw)
To: Xi Ruoyao
Cc: Youling Tang, Qing Zhang, WANG Xuerui, loongarch, LKML,
Jiaxun Yang, Jinyang He
Hi, Ruoyao,
On Tue, Aug 2, 2022 at 9:39 AM Xi Ruoyao <xry111@xry111.site> wrote:
>
> On Tue, 2022-08-02 at 09:34 +0800, Huacai Chen wrote:
> > > > #define UNWINDER_GUESS 0
> > > > #define UNWINDER_PROLOGURE 1
> > >
> > > Maybe it's better to define with enum type?
> > > enum unwind_type {
> > > UNWINDER_GUESS,
> > > UNWINDER_PROLOGURE,
> > > };
> > Both macro and enum are acceptable, but enum is essentially "int",
> > while the "type" member is "char" here.
>
> "0" or "1" will also be "int" (C99 6.4.4.1 para 5).
OK, then Zhang Qing has her rights to choose. :)
Huacai
>
> --
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-01 12:17 [PATCH 0/4] LoongArch: Add unwinder support Qing Zhang
2022-08-01 12:17 ` [PATCH 1/4] LoongArch: Add guess " Qing Zhang
2022-08-01 12:17 ` [PATCH 2/4] LoongArch: Add prologue " Qing Zhang
@ 2022-08-01 12:17 ` Qing Zhang
2022-08-01 15:30 ` Huacai Chen
` (2 more replies)
2022-08-01 12:17 ` [PATCH 4/4] LoongArch: Add USER_STACKTRACE support Qing Zhang
2022-08-01 15:34 ` [PATCH 0/4] LoongArch: Add unwinder support Huacai Chen
4 siblings, 3 replies; 21+ messages in thread
From: Qing Zhang @ 2022-08-01 12:17 UTC (permalink / raw)
To: Huacai Chen
Cc: WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang, hejinyang, zhangqing
Use common arch_stack_walk infrastructure to avoid duplicated code and
avoid taking care of the stack storage and filtering.
Add sra (means __schedule return address) and scfa (means __schedule call
frame address) to thread_info and store it in switch_to().
Now we can print the process stack by cat /proc/*/stack and can better
support ftrace.
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
arch/loongarch/Kconfig | 5 ++++
arch/loongarch/include/asm/processor.h | 9 +++++++
arch/loongarch/include/asm/switch_to.h | 14 ++++++----
arch/loongarch/include/asm/uaccess.h | 4 +--
arch/loongarch/kernel/Makefile | 1 +
arch/loongarch/kernel/asm-offsets.c | 2 ++
arch/loongarch/kernel/process.c | 3 +++
arch/loongarch/kernel/stacktrace.c | 37 ++++++++++++++++++++++++++
arch/loongarch/kernel/switch.S | 2 ++
9 files changed, 70 insertions(+), 7 deletions(-)
create mode 100644 arch/loongarch/kernel/stacktrace.c
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 62b5b07fa4e1..85d0fa3147cd 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -38,6 +38,7 @@ config LOONGARCH
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
+ select ARCH_STACKWALK
select ARCH_SPARSEMEM_ENABLE
select ARCH_SUPPORTS_ACPI
select ARCH_SUPPORTS_ATOMIC_RMW
@@ -140,6 +141,10 @@ config LOCKDEP_SUPPORT
bool
default y
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
# MACH_LOONGSON32 and MACH_LOONGSON64 are delibrately carried over from the
# MIPS Loongson code, to preserve Loongson-specific code paths in drivers that
# are shared between architectures, and specifically expecting the symbols.
diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/include/asm/processor.h
index 57ec45aa078e..1c4b4308378d 100644
--- a/arch/loongarch/include/asm/processor.h
+++ b/arch/loongarch/include/asm/processor.h
@@ -101,6 +101,10 @@ struct thread_struct {
unsigned long reg23, reg24, reg25, reg26; /* s0-s3 */
unsigned long reg27, reg28, reg29, reg30, reg31; /* s4-s8 */
+ /* __schedule() return address / call frame address */
+ unsigned long sched_ra;
+ unsigned long sched_cfa;
+
/* CSR registers */
unsigned long csr_prmd;
unsigned long csr_crmd;
@@ -129,6 +133,9 @@ struct thread_struct {
struct loongarch_fpu fpu FPU_ALIGN;
};
+#define thread_saved_ra(tsk) (tsk->thread.sched_ra)
+#define thread_saved_fp(tsk) (tsk->thread.sched_cfa)
+
#define INIT_THREAD { \
/* \
* Main processor registers \
@@ -145,6 +152,8 @@ struct thread_struct {
.reg29 = 0, \
.reg30 = 0, \
.reg31 = 0, \
+ .sched_ra = 0, \
+ .sched_cfa = 0, \
.csr_crmd = 0, \
.csr_prmd = 0, \
.csr_euen = 0, \
diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/include/asm/switch_to.h
index 2a8d04375574..43a5ab162d38 100644
--- a/arch/loongarch/include/asm/switch_to.h
+++ b/arch/loongarch/include/asm/switch_to.h
@@ -15,12 +15,15 @@ struct task_struct;
* @prev: The task previously executed.
* @next: The task to begin executing.
* @next_ti: task_thread_info(next).
+ * @sched_ra: __schedule return address.
+ * @sched_cfa: __schedule call frame address.
*
* This function is used whilst scheduling to save the context of prev & load
* the context of next. Returns prev.
*/
extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *next, struct thread_info *next_ti);
+ struct task_struct *next, struct thread_info *next_ti,
+ void *sched_ra, void *sched_cfa);
/*
* For newly created kernel threads switch_to() will return to
@@ -28,10 +31,11 @@ extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
* That is, everything following __switch_to() will be skipped for new threads.
* So everything that matters to new threads should be placed before __switch_to().
*/
-#define switch_to(prev, next, last) \
-do { \
- lose_fpu_inatomic(1, prev); \
- (last) = __switch_to(prev, next, task_thread_info(next)); \
+#define switch_to(prev, next, last) \
+do { \
+ lose_fpu_inatomic(1, prev); \
+ (last) = __switch_to(prev, next, task_thread_info(next), \
+ __builtin_return_address(0), __builtin_frame_address(0)); \
} while (0)
#endif /* _ASM_SWITCH_TO_H */
diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index 2b44edc604a2..a8ae2af4025a 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -229,13 +229,13 @@ extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
static inline unsigned long __must_check
raw_copy_from_user(void *to, const void __user *from, unsigned long n)
{
- return __copy_user(to, from, n);
+ return __copy_user(to, (__force const void *)from, n);
}
static inline unsigned long __must_check
raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
- return __copy_user(to, from, n);
+ return __copy_user((__force void *)to, from, n);
}
#define INLINE_COPY_FROM_USER
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 918600e7b30f..7449513eb08d 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_EFI) += efi.o
obj-$(CONFIG_CPU_HAS_FPU) += fpu.o
obj-$(CONFIG_MODULES) += module.o module-sections.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
index 20cd9e16a95a..eb350f3ffae5 100644
--- a/arch/loongarch/kernel/asm-offsets.c
+++ b/arch/loongarch/kernel/asm-offsets.c
@@ -103,6 +103,8 @@ void output_thread_defines(void)
OFFSET(THREAD_REG29, task_struct, thread.reg29);
OFFSET(THREAD_REG30, task_struct, thread.reg30);
OFFSET(THREAD_REG31, task_struct, thread.reg31);
+ OFFSET(THREAD_SCHED_RA, task_struct, thread.sched_ra);
+ OFFSET(THREAD_SCHED_CFA, task_struct, thread.sched_cfa);
OFFSET(THREAD_CSRCRMD, task_struct,
thread.csr_crmd);
OFFSET(THREAD_CSRPRMD, task_struct,
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index 709b7a1664f8..34c3f2148714 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -135,6 +135,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs = (struct pt_regs *) childksp - 1;
/* Put the stack after the struct pt_regs. */
childksp = (unsigned long) childregs;
+ p->thread.sched_cfa = 0;
p->thread.csr_euen = 0;
p->thread.csr_crmd = csr_read32(LOONGARCH_CSR_CRMD);
p->thread.csr_prmd = csr_read32(LOONGARCH_CSR_PRMD);
@@ -145,6 +146,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.reg23 = (unsigned long)args->fn;
p->thread.reg24 = (unsigned long)args->fn_arg;
p->thread.reg01 = (unsigned long)ret_from_kernel_thread;
+ p->thread.sched_ra = (unsigned long)ret_from_kernel_thread;
memset(childregs, 0, sizeof(struct pt_regs));
childregs->csr_euen = p->thread.csr_euen;
childregs->csr_crmd = p->thread.csr_crmd;
@@ -161,6 +163,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.reg03 = (unsigned long) childregs;
p->thread.reg01 = (unsigned long) ret_from_fork;
+ p->thread.sched_ra = (unsigned long) ret_from_fork;
/*
* New tasks lose permission to use the fpu. This accelerates context
diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
new file mode 100644
index 000000000000..f4f4b8ad3917
--- /dev/null
+++ b/arch/loongarch/kernel/stacktrace.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Stack trace management functions
+ *
+ * Copyright (C) 2022 Loongson Technology Corporation Limited
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include <asm/stacktrace.h>
+#include <asm/unwind.h>
+
+void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
+ struct task_struct *task, struct pt_regs *regs)
+{
+ struct pt_regs dummyregs;
+ struct unwind_state state;
+ unsigned long addr;
+
+ regs = &dummyregs;
+
+ if (task == current) {
+ regs->csr_era = (unsigned long)__builtin_return_address(0);
+ regs->regs[3] = (unsigned long)__builtin_frame_address(0);
+ } else {
+ regs->csr_era = thread_saved_ra(task);
+ regs->regs[3] = thread_saved_fp(task);
+ }
+
+ regs->regs[1] = 0;
+ for (unwind_start(&state, task, regs);
+ !unwind_done(&state); unwind_next_frame(&state)) {
+ addr = unwind_get_return_address(&state);
+ if (!addr || !consume_entry(cookie, addr))
+ break;
+ }
+}
diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S
index 37e84ac8ffc2..43ebbc3990f7 100644
--- a/arch/loongarch/kernel/switch.S
+++ b/arch/loongarch/kernel/switch.S
@@ -21,6 +21,8 @@ SYM_FUNC_START(__switch_to)
cpu_save_nonscratch a0
stptr.d ra, a0, THREAD_REG01
+ stptr.d a3, a0, THREAD_SCHED_RA
+ stptr.d a4, a0, THREAD_SCHED_CFA
move tp, a2
cpu_restore_nonscratch a1
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-01 12:17 ` [PATCH 3/4] LoongArch: Add stacktrace support Qing Zhang
@ 2022-08-01 15:30 ` Huacai Chen
2022-08-02 1:19 ` zhangqing
2022-08-13 22:29 ` kernel test robot
2022-08-14 5:31 ` kernel test robot
2 siblings, 1 reply; 21+ messages in thread
From: Huacai Chen @ 2022-08-01 15:30 UTC (permalink / raw)
To: Qing Zhang; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>
> Use common arch_stack_walk infrastructure to avoid duplicated code and
> avoid taking care of the stack storage and filtering.
> Add sra (means __schedule return address) and scfa (means __schedule call
> frame address) to thread_info and store it in switch_to().
>
> Now we can print the process stack by cat /proc/*/stack and can better
> support ftrace.
>
> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> ---
> arch/loongarch/Kconfig | 5 ++++
> arch/loongarch/include/asm/processor.h | 9 +++++++
> arch/loongarch/include/asm/switch_to.h | 14 ++++++----
> arch/loongarch/include/asm/uaccess.h | 4 +--
> arch/loongarch/kernel/Makefile | 1 +
> arch/loongarch/kernel/asm-offsets.c | 2 ++
> arch/loongarch/kernel/process.c | 3 +++
> arch/loongarch/kernel/stacktrace.c | 37 ++++++++++++++++++++++++++
> arch/loongarch/kernel/switch.S | 2 ++
> 9 files changed, 70 insertions(+), 7 deletions(-)
> create mode 100644 arch/loongarch/kernel/stacktrace.c
>
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 62b5b07fa4e1..85d0fa3147cd 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -38,6 +38,7 @@ config LOONGARCH
> select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
> select ARCH_MIGHT_HAVE_PC_PARPORT
> select ARCH_MIGHT_HAVE_PC_SERIO
> + select ARCH_STACKWALK
> select ARCH_SPARSEMEM_ENABLE
> select ARCH_SUPPORTS_ACPI
> select ARCH_SUPPORTS_ATOMIC_RMW
> @@ -140,6 +141,10 @@ config LOCKDEP_SUPPORT
> bool
> default y
>
> +config STACKTRACE_SUPPORT
> + bool
> + default y
> +
> # MACH_LOONGSON32 and MACH_LOONGSON64 are delibrately carried over from the
> # MIPS Loongson code, to preserve Loongson-specific code paths in drivers that
> # are shared between architectures, and specifically expecting the symbols.
> diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/include/asm/processor.h
> index 57ec45aa078e..1c4b4308378d 100644
> --- a/arch/loongarch/include/asm/processor.h
> +++ b/arch/loongarch/include/asm/processor.h
> @@ -101,6 +101,10 @@ struct thread_struct {
> unsigned long reg23, reg24, reg25, reg26; /* s0-s3 */
> unsigned long reg27, reg28, reg29, reg30, reg31; /* s4-s8 */
>
> + /* __schedule() return address / call frame address */
> + unsigned long sched_ra;
> + unsigned long sched_cfa;
> +
> /* CSR registers */
> unsigned long csr_prmd;
> unsigned long csr_crmd;
> @@ -129,6 +133,9 @@ struct thread_struct {
> struct loongarch_fpu fpu FPU_ALIGN;
> };
>
> +#define thread_saved_ra(tsk) (tsk->thread.sched_ra)
> +#define thread_saved_fp(tsk) (tsk->thread.sched_cfa)
> +
> #define INIT_THREAD { \
> /* \
> * Main processor registers \
> @@ -145,6 +152,8 @@ struct thread_struct {
> .reg29 = 0, \
> .reg30 = 0, \
> .reg31 = 0, \
> + .sched_ra = 0, \
> + .sched_cfa = 0, \
> .csr_crmd = 0, \
> .csr_prmd = 0, \
> .csr_euen = 0, \
> diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/include/asm/switch_to.h
> index 2a8d04375574..43a5ab162d38 100644
> --- a/arch/loongarch/include/asm/switch_to.h
> +++ b/arch/loongarch/include/asm/switch_to.h
> @@ -15,12 +15,15 @@ struct task_struct;
> * @prev: The task previously executed.
> * @next: The task to begin executing.
> * @next_ti: task_thread_info(next).
> + * @sched_ra: __schedule return address.
> + * @sched_cfa: __schedule call frame address.
> *
> * This function is used whilst scheduling to save the context of prev & load
> * the context of next. Returns prev.
> */
> extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
> - struct task_struct *next, struct thread_info *next_ti);
> + struct task_struct *next, struct thread_info *next_ti,
> + void *sched_ra, void *sched_cfa);
>
> /*
> * For newly created kernel threads switch_to() will return to
> @@ -28,10 +31,11 @@ extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
> * That is, everything following __switch_to() will be skipped for new threads.
> * So everything that matters to new threads should be placed before __switch_to().
> */
> -#define switch_to(prev, next, last) \
> -do { \
> - lose_fpu_inatomic(1, prev); \
> - (last) = __switch_to(prev, next, task_thread_info(next)); \
> +#define switch_to(prev, next, last) \
> +do { \
> + lose_fpu_inatomic(1, prev); \
> + (last) = __switch_to(prev, next, task_thread_info(next), \
> + __builtin_return_address(0), __builtin_frame_address(0)); \
> } while (0)
>
> #endif /* _ASM_SWITCH_TO_H */
> diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
> index 2b44edc604a2..a8ae2af4025a 100644
> --- a/arch/loongarch/include/asm/uaccess.h
> +++ b/arch/loongarch/include/asm/uaccess.h
> @@ -229,13 +229,13 @@ extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
> static inline unsigned long __must_check
> raw_copy_from_user(void *to, const void __user *from, unsigned long n)
> {
> - return __copy_user(to, from, n);
> + return __copy_user(to, (__force const void *)from, n);
> }
>
> static inline unsigned long __must_check
> raw_copy_to_user(void __user *to, const void *from, unsigned long n)
> {
> - return __copy_user(to, from, n);
> + return __copy_user((__force void *)to, from, n);
Why this? Does it have something to do with stacktrace?
Huacai
> }
>
> #define INLINE_COPY_FROM_USER
> diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
> index 918600e7b30f..7449513eb08d 100644
> --- a/arch/loongarch/kernel/Makefile
> +++ b/arch/loongarch/kernel/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_EFI) += efi.o
> obj-$(CONFIG_CPU_HAS_FPU) += fpu.o
>
> obj-$(CONFIG_MODULES) += module.o module-sections.o
> +obj-$(CONFIG_STACKTRACE) += stacktrace.o
>
> obj-$(CONFIG_PROC_FS) += proc.o
>
> diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
> index 20cd9e16a95a..eb350f3ffae5 100644
> --- a/arch/loongarch/kernel/asm-offsets.c
> +++ b/arch/loongarch/kernel/asm-offsets.c
> @@ -103,6 +103,8 @@ void output_thread_defines(void)
> OFFSET(THREAD_REG29, task_struct, thread.reg29);
> OFFSET(THREAD_REG30, task_struct, thread.reg30);
> OFFSET(THREAD_REG31, task_struct, thread.reg31);
> + OFFSET(THREAD_SCHED_RA, task_struct, thread.sched_ra);
> + OFFSET(THREAD_SCHED_CFA, task_struct, thread.sched_cfa);
> OFFSET(THREAD_CSRCRMD, task_struct,
> thread.csr_crmd);
> OFFSET(THREAD_CSRPRMD, task_struct,
> diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
> index 709b7a1664f8..34c3f2148714 100644
> --- a/arch/loongarch/kernel/process.c
> +++ b/arch/loongarch/kernel/process.c
> @@ -135,6 +135,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
> childregs = (struct pt_regs *) childksp - 1;
> /* Put the stack after the struct pt_regs. */
> childksp = (unsigned long) childregs;
> + p->thread.sched_cfa = 0;
> p->thread.csr_euen = 0;
> p->thread.csr_crmd = csr_read32(LOONGARCH_CSR_CRMD);
> p->thread.csr_prmd = csr_read32(LOONGARCH_CSR_PRMD);
> @@ -145,6 +146,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
> p->thread.reg23 = (unsigned long)args->fn;
> p->thread.reg24 = (unsigned long)args->fn_arg;
> p->thread.reg01 = (unsigned long)ret_from_kernel_thread;
> + p->thread.sched_ra = (unsigned long)ret_from_kernel_thread;
> memset(childregs, 0, sizeof(struct pt_regs));
> childregs->csr_euen = p->thread.csr_euen;
> childregs->csr_crmd = p->thread.csr_crmd;
> @@ -161,6 +163,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
>
> p->thread.reg03 = (unsigned long) childregs;
> p->thread.reg01 = (unsigned long) ret_from_fork;
> + p->thread.sched_ra = (unsigned long) ret_from_fork;
>
> /*
> * New tasks lose permission to use the fpu. This accelerates context
> diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
> new file mode 100644
> index 000000000000..f4f4b8ad3917
> --- /dev/null
> +++ b/arch/loongarch/kernel/stacktrace.c
> @@ -0,0 +1,37 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Stack trace management functions
> + *
> + * Copyright (C) 2022 Loongson Technology Corporation Limited
> + */
> +#include <linux/sched.h>
> +#include <linux/stacktrace.h>
> +
> +#include <asm/stacktrace.h>
> +#include <asm/unwind.h>
> +
> +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
> + struct task_struct *task, struct pt_regs *regs)
> +{
> + struct pt_regs dummyregs;
> + struct unwind_state state;
> + unsigned long addr;
> +
> + regs = &dummyregs;
> +
> + if (task == current) {
> + regs->csr_era = (unsigned long)__builtin_return_address(0);
> + regs->regs[3] = (unsigned long)__builtin_frame_address(0);
> + } else {
> + regs->csr_era = thread_saved_ra(task);
> + regs->regs[3] = thread_saved_fp(task);
> + }
> +
> + regs->regs[1] = 0;
> + for (unwind_start(&state, task, regs);
> + !unwind_done(&state); unwind_next_frame(&state)) {
> + addr = unwind_get_return_address(&state);
> + if (!addr || !consume_entry(cookie, addr))
> + break;
> + }
> +}
> diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S
> index 37e84ac8ffc2..43ebbc3990f7 100644
> --- a/arch/loongarch/kernel/switch.S
> +++ b/arch/loongarch/kernel/switch.S
> @@ -21,6 +21,8 @@ SYM_FUNC_START(__switch_to)
>
> cpu_save_nonscratch a0
> stptr.d ra, a0, THREAD_REG01
> + stptr.d a3, a0, THREAD_SCHED_RA
> + stptr.d a4, a0, THREAD_SCHED_CFA
> move tp, a2
> cpu_restore_nonscratch a1
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-01 15:30 ` Huacai Chen
@ 2022-08-02 1:19 ` zhangqing
2022-08-02 1:30 ` Huacai Chen
0 siblings, 1 reply; 21+ messages in thread
From: zhangqing @ 2022-08-02 1:19 UTC (permalink / raw)
To: Huacai Chen; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On 2022/8/1 下午11:30, Huacai Chen wrote:
> Hi, Qing,
>
> On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>>
>> Use common arch_stack_walk infrastructure to avoid duplicated code and
>> avoid taking care of the stack storage and filtering.
>> Add sra (means __schedule return address) and scfa (means __schedule call
>> frame address) to thread_info and store it in switch_to().
>>
>> Now we can print the process stack by cat /proc/*/stack and can better
>> support ftrace.
>>
>> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
>> ---
>> arch/loongarch/Kconfig | 5 ++++
>> arch/loongarch/include/asm/processor.h | 9 +++++++
>> arch/loongarch/include/asm/switch_to.h | 14 ++++++----
>> arch/loongarch/include/asm/uaccess.h | 4 +--
>> arch/loongarch/kernel/Makefile | 1 +
>> arch/loongarch/kernel/asm-offsets.c | 2 ++
>> arch/loongarch/kernel/process.c | 3 +++
>> arch/loongarch/kernel/stacktrace.c | 37 ++++++++++++++++++++++++++
>> arch/loongarch/kernel/switch.S | 2 ++
>> 9 files changed, 70 insertions(+), 7 deletions(-)
>> create mode 100644 arch/loongarch/kernel/stacktrace.c
>>
>> diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
>> index 2b44edc604a2..a8ae2af4025a 100644
>> --- a/arch/loongarch/include/asm/uaccess.h
>> +++ b/arch/loongarch/include/asm/uaccess.h
>> @@ -229,13 +229,13 @@ extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
>> static inline unsigned long __must_check
>> raw_copy_from_user(void *to, const void __user *from, unsigned long n)
>> {
>> - return __copy_user(to, from, n);
>> + return __copy_user(to, (__force const void *)from, n);
>> }
>>
>> static inline unsigned long __must_check
>> raw_copy_to_user(void __user *to, const void *from, unsigned long n)
>> {
>> - return __copy_user(to, from, n);
>> + return __copy_user((__force void *)to, from, n);
> Why this? Does it have something to do with stacktrace?
>
> Huacai
Hi, huacai
This is kernel test robot report sparse warnings:
I reproduced locally and found that other architectures calling
__copy_user also use __force conversion, Is this modification appropriate?
kernel/trace/trace_events_user.c: note: in included file (through
include/linux/uaccess.h, include/linux/sched/task.h,
include/linux/sched/signal.h, ...):
arch/loongarch/include/asm/uaccess.h:232:32: sparse: sparse:
incorrect type in argument 2 (different address spaces) @@ expected
void const *from @@ got void const [noderef] __user *from @@
arch/loongarch/include/asm/uaccess.h:232:32: sparse: expected
void const *from
arch/loongarch/include/asm/uaccess.h:232:32: sparse: got void
const [noderef] __user *from
Thanks,
-Qing
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-02 1:19 ` zhangqing
@ 2022-08-02 1:30 ` Huacai Chen
2022-08-02 2:01 ` Qing Zhang
0 siblings, 1 reply; 21+ messages in thread
From: Huacai Chen @ 2022-08-02 1:30 UTC (permalink / raw)
To: zhangqing; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
On Tue, Aug 2, 2022 at 9:20 AM zhangqing <zhangqing@loongson.cn> wrote:
>
>
>
> On 2022/8/1 下午11:30, Huacai Chen wrote:
> > Hi, Qing,
> >
> > On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
> >>
> >> Use common arch_stack_walk infrastructure to avoid duplicated code and
> >> avoid taking care of the stack storage and filtering.
> >> Add sra (means __schedule return address) and scfa (means __schedule call
> >> frame address) to thread_info and store it in switch_to().
> >>
> >> Now we can print the process stack by cat /proc/*/stack and can better
> >> support ftrace.
> >>
> >> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> >> ---
> >> arch/loongarch/Kconfig | 5 ++++
> >> arch/loongarch/include/asm/processor.h | 9 +++++++
> >> arch/loongarch/include/asm/switch_to.h | 14 ++++++----
> >> arch/loongarch/include/asm/uaccess.h | 4 +--
> >> arch/loongarch/kernel/Makefile | 1 +
> >> arch/loongarch/kernel/asm-offsets.c | 2 ++
> >> arch/loongarch/kernel/process.c | 3 +++
> >> arch/loongarch/kernel/stacktrace.c | 37 ++++++++++++++++++++++++++
> >> arch/loongarch/kernel/switch.S | 2 ++
> >> 9 files changed, 70 insertions(+), 7 deletions(-)
> >> create mode 100644 arch/loongarch/kernel/stacktrace.c
> >>
> >> diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
> >> index 2b44edc604a2..a8ae2af4025a 100644
> >> --- a/arch/loongarch/include/asm/uaccess.h
> >> +++ b/arch/loongarch/include/asm/uaccess.h
> >> @@ -229,13 +229,13 @@ extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
> >> static inline unsigned long __must_check
> >> raw_copy_from_user(void *to, const void __user *from, unsigned long n)
> >> {
> >> - return __copy_user(to, from, n);
> >> + return __copy_user(to, (__force const void *)from, n);
> >> }
> >>
> >> static inline unsigned long __must_check
> >> raw_copy_to_user(void __user *to, const void *from, unsigned long n)
> >> {
> >> - return __copy_user(to, from, n);
> >> + return __copy_user((__force void *)to, from, n);
> > Why this? Does it have something to do with stacktrace?
> >
> > Huacai
>
> Hi, huacai
>
> This is kernel test robot report sparse warnings:
> I reproduced locally and found that other architectures calling
> __copy_user also use __force conversion, Is this modification appropriate?
>
> kernel/trace/trace_events_user.c: note: in included file (through
> include/linux/uaccess.h, include/linux/sched/task.h,
> include/linux/sched/signal.h, ...):
> arch/loongarch/include/asm/uaccess.h:232:32: sparse: sparse:
> incorrect type in argument 2 (different address spaces) @@ expected
> void const *from @@ got void const [noderef] __user *from @@
> arch/loongarch/include/asm/uaccess.h:232:32: sparse: expected
> void const *from
> arch/loongarch/include/asm/uaccess.h:232:32: sparse: got void
> const [noderef] __user *from
The modification might be correct, but should it be in this patch?
Huacai
>
> Thanks,
> -Qing
>
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-02 1:30 ` Huacai Chen
@ 2022-08-02 2:01 ` Qing Zhang
0 siblings, 0 replies; 21+ messages in thread
From: Qing Zhang @ 2022-08-02 2:01 UTC (permalink / raw)
To: Huacai Chen; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On 2022/8/2 上午9:30, Huacai Chen wrote:
> Hi, Qing,
>
> On Tue, Aug 2, 2022 at 9:20 AM zhangqing <zhangqing@loongson.cn> wrote:
>>
>>
>>
>> On 2022/8/1 下午11:30, Huacai Chen wrote:
>>> Hi, Qing,
>>>
>>> On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>>>>
>>>> Use common arch_stack_walk infrastructure to avoid duplicated code and
>>>> avoid taking care of the stack storage and filtering.
>>>> Add sra (means __schedule return address) and scfa (means __schedule call
>>>> frame address) to thread_info and store it in switch_to().
>>>>
>>>> Now we can print the process stack by cat /proc/*/stack and can better
>>>> support ftrace.
>>>>
>>>> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
>>>> ---
>>>> arch/loongarch/Kconfig | 5 ++++
>>>> arch/loongarch/include/asm/processor.h | 9 +++++++
>>>> arch/loongarch/include/asm/switch_to.h | 14 ++++++----
>>>> arch/loongarch/include/asm/uaccess.h | 4 +--
>>>> arch/loongarch/kernel/Makefile | 1 +
>>>> arch/loongarch/kernel/asm-offsets.c | 2 ++
>>>> arch/loongarch/kernel/process.c | 3 +++
>>>> arch/loongarch/kernel/stacktrace.c | 37 ++++++++++++++++++++++++++
>>>> arch/loongarch/kernel/switch.S | 2 ++
>>>> 9 files changed, 70 insertions(+), 7 deletions(-)
>>>> create mode 100644 arch/loongarch/kernel/stacktrace.c
>>>>
>>>> diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
>>>> index 2b44edc604a2..a8ae2af4025a 100644
>>>> --- a/arch/loongarch/include/asm/uaccess.h
>>>> +++ b/arch/loongarch/include/asm/uaccess.h
>>>> @@ -229,13 +229,13 @@ extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
>>>> static inline unsigned long __must_check
>>>> raw_copy_from_user(void *to, const void __user *from, unsigned long n)
>>>> {
>>>> - return __copy_user(to, from, n);
>>>> + return __copy_user(to, (__force const void *)from, n);
>>>> }
>>>>
>>>> static inline unsigned long __must_check
>>>> raw_copy_to_user(void __user *to, const void *from, unsigned long n)
>>>> {
>>>> - return __copy_user(to, from, n);
>>>> + return __copy_user((__force void *)to, from, n);
>>> Why this? Does it have something to do with stacktrace?
>>>
>>> Huacai
>>
>> Hi, huacai
>>
>> This is kernel test robot report sparse warnings:
>> I reproduced locally and found that other architectures calling
>> __copy_user also use __force conversion, Is this modification appropriate?
>>
>> kernel/trace/trace_events_user.c: note: in included file (through
>> include/linux/uaccess.h, include/linux/sched/task.h,
>> include/linux/sched/signal.h, ...):
>> arch/loongarch/include/asm/uaccess.h:232:32: sparse: sparse:
>> incorrect type in argument 2 (different address spaces) @@ expected
>> void const *from @@ got void const [noderef] __user *from @@
>> arch/loongarch/include/asm/uaccess.h:232:32: sparse: expected
>> void const *from
>> arch/loongarch/include/asm/uaccess.h:232:32: sparse: got void
>> const [noderef] __user *from
> The modification might be correct, but should it be in this patch?
>
> Huacai
I will send this patch separately, it has nothing to do with the series
patch.
arch/loongarch/kernel/ptrace.c: note: in included file (through
include/linux/uaccess.h, include/linux/sched/task.h,
include/linux/sched/signal.h, include/linux/ptrace.h, include/linux/audit.h)
-Qing
>>
>> Thanks,
>> -Qing
>>
>>
>>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-01 12:17 ` [PATCH 3/4] LoongArch: Add stacktrace support Qing Zhang
2022-08-01 15:30 ` Huacai Chen
@ 2022-08-13 22:29 ` kernel test robot
2022-08-14 5:31 ` kernel test robot
2 siblings, 0 replies; 21+ messages in thread
From: kernel test robot @ 2022-08-13 22:29 UTC (permalink / raw)
To: Qing Zhang, Huacai Chen
Cc: kbuild-all, WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang,
hejinyang, zhangqing
Hi Qing,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.19]
[cannot apply to next-20220812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qing-Zhang/LoongArch-Add-unwinder-support/20220801-204020
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3d7cb6b04c3f3115719235cc6866b10326de34cd
config: loongarch-randconfig-s041-20220814 (https://download.01.org/0day-ci/archive/20220814/202208140621.UKarxp6n-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/102a43b57dafc9c0058a458a62d4133eb8020cbc
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Qing-Zhang/LoongArch-Add-unwinder-support/20220801-204020
git checkout 102a43b57dafc9c0058a458a62d4133eb8020cbc
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=loongarch SHELL=/bin/bash kernel/time/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got int [noderef] __percpu *
>> kernel/time/tick-sched.c:1151:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/tick-sched.c:1151:9: sparse: expected void *ptr
kernel/time/tick-sched.c:1151:9: sparse: got int [noderef] __percpu *
vim +1151 kernel/time/tick-sched.c
554c8aa8ecade2 Rafael J. Wysocki 2018-04-03 1141
0e7767687fdabf Rafael J. Wysocki 2018-04-05 1142 /**
0e7767687fdabf Rafael J. Wysocki 2018-04-05 1143 * tick_nohz_idle_enter - prepare for entering idle on the current CPU
2bbb6817c0ac1b Frederic Weisbecker 2011-10-08 1144 *
0e7767687fdabf Rafael J. Wysocki 2018-04-05 1145 * Called when we start the idle loop.
280f06774afedf Frederic Weisbecker 2011-10-07 1146 */
1268fbc746ea1c Frederic Weisbecker 2011-11-17 1147 void tick_nohz_idle_enter(void)
280f06774afedf Frederic Weisbecker 2011-10-07 1148 {
280f06774afedf Frederic Weisbecker 2011-10-07 1149 struct tick_sched *ts;
280f06774afedf Frederic Weisbecker 2011-10-07 1150
ebf3adbad012b8 Frederic Weisbecker 2017-11-06 @1151 lockdep_assert_irqs_enabled();
0db49b72bce263 Linus Torvalds 2012-01-06 1152
1268fbc746ea1c Frederic Weisbecker 2011-11-17 1153 local_irq_disable();
1268fbc746ea1c Frederic Weisbecker 2011-11-17 1154
22127e93c587af Christoph Lameter 2014-08-17 1155 ts = this_cpu_ptr(&tick_cpu_sched);
23a8d888107ce4 Rafael J. Wysocki 2018-04-05 1156
23a8d888107ce4 Rafael J. Wysocki 2018-04-05 1157 WARN_ON_ONCE(ts->timer_expires_base);
23a8d888107ce4 Rafael J. Wysocki 2018-04-05 1158
280f06774afedf Frederic Weisbecker 2011-10-07 1159 ts->inidle = 1;
0e7767687fdabf Rafael J. Wysocki 2018-04-05 1160 tick_nohz_start_idle(ts);
1268fbc746ea1c Frederic Weisbecker 2011-11-17 1161
1268fbc746ea1c Frederic Weisbecker 2011-11-17 1162 local_irq_enable();
280f06774afedf Frederic Weisbecker 2011-10-07 1163 }
280f06774afedf Frederic Weisbecker 2011-10-07 1164
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4] LoongArch: Add stacktrace support
2022-08-01 12:17 ` [PATCH 3/4] LoongArch: Add stacktrace support Qing Zhang
2022-08-01 15:30 ` Huacai Chen
2022-08-13 22:29 ` kernel test robot
@ 2022-08-14 5:31 ` kernel test robot
2 siblings, 0 replies; 21+ messages in thread
From: kernel test robot @ 2022-08-14 5:31 UTC (permalink / raw)
To: Qing Zhang, Huacai Chen
Cc: kbuild-all, WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang,
hejinyang, zhangqing
Hi Qing,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.19]
[cannot apply to next-20220812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qing-Zhang/LoongArch-Add-unwinder-support/20220801-204020
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3d7cb6b04c3f3115719235cc6866b10326de34cd
config: loongarch-randconfig-s033-20220814 (https://download.01.org/0day-ci/archive/20220814/202208141339.jCYoEcIL-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/102a43b57dafc9c0058a458a62d4133eb8020cbc
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Qing-Zhang/LoongArch-Add-unwinder-support/20220801-204020
git checkout 102a43b57dafc9c0058a458a62d4133eb8020cbc
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=loongarch SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got int [noderef] __percpu *
>> kernel/smp.c:571:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:571:9: sparse: expected void *ptr
kernel/smp.c:571:9: sparse: got int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got int [noderef] __percpu *
kernel/smp.c:895:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:895:9: sparse: expected void *ptr
kernel/smp.c:895:9: sparse: got int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got unsigned int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got int [noderef] __percpu *
kernel/smp.c:905:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/smp.c:905:17: sparse: expected void *ptr
kernel/smp.c:905:17: sparse: got int [noderef] __percpu *
--
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got int [noderef] __percpu *
>> kernel/sched/fair.c:6475:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/fair.c:6475:9: sparse: expected void *ptr
kernel/sched/fair.c:6475:9: sparse: got int [noderef] __percpu *
kernel/sched/fair.c:930:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_entity *se @@ got struct sched_entity [noderef] __rcu * @@
kernel/sched/fair.c:930:34: sparse: expected struct sched_entity *se
kernel/sched/fair.c:930:34: sparse: got struct sched_entity [noderef] __rcu *
kernel/sched/fair.c:10928:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:10928:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:10928:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:5591:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:5591:38: sparse: expected struct task_struct *curr
kernel/sched/fair.c:5591:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:5846:1: sparse: sparse: symbol '__pcpu_scope_load_balance_mask' was not declared. Should it be static?
kernel/sched/fair.c:5847:1: sparse: sparse: symbol '__pcpu_scope_select_idle_mask' was not declared. Should it be static?
kernel/sched/fair.c:6774:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:6774:20: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:6774:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:6908:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:6908:9: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/fair.c:6908:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:7106:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:7106:38: sparse: expected struct task_struct *curr
kernel/sched/fair.c:7106:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:7404:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:7404:38: sparse: expected struct task_struct *curr
kernel/sched/fair.c:7404:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:8389:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/fair.c:8389:40: sparse: expected struct sched_domain *child
kernel/sched/fair.c:8389:40: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/fair.c:8933:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/fair.c:8933:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/fair.c:8933:22: sparse: struct task_struct *
kernel/sched/fair.c:10203:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:10203:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:10203:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:9863:44: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *sd_parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:9863:44: sparse: expected struct sched_domain *sd_parent
kernel/sched/fair.c:9863:44: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:10299:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:10299:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:10299:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:5520:35: sparse: sparse: marked inline, but without a definition
kernel/sched/fair.c: note: in included file:
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
--
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got int [noderef] __percpu *
>> kernel/sched/core.c:597:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/sched/core.c:597:9: sparse: expected void *ptr
kernel/sched/core.c:597:9: sparse: got int [noderef] __percpu *
kernel/sched/core.c:780:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:780:48: sparse: expected struct task_struct *p
kernel/sched/core.c:780:48: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:1033:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:1033:38: sparse: expected struct task_struct *curr
kernel/sched/core.c:1033:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:1091:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/core.c:1091:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/core.c:1091:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/core.c:2197:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:2197:33: sparse: expected struct task_struct *p
kernel/sched/core.c:2197:33: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:2197:68: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:2197:68: sparse: expected struct task_struct *tsk
kernel/sched/core.c:2197:68: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:3597:17: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/core.c:3597:17: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/core.c:3597:17: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/core.c:3794:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct const *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:3794:28: sparse: expected struct task_struct const *p
kernel/sched/core.c:3794:28: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:9084:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *push_task @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:9084:43: sparse: expected struct task_struct *push_task
kernel/sched/core.c:9084:43: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:5404:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:5404:38: sparse: expected struct task_struct *curr
kernel/sched/core.c:5404:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:5495:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:5495:14: sparse: expected struct task_struct *curr
kernel/sched/core.c:5495:14: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:6350:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct task_struct *prev @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:6350:14: sparse: expected struct task_struct *prev
kernel/sched/core.c:6350:14: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:6872:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:6872:17: sparse: struct task_struct *
kernel/sched/core.c:6872:17: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:7076:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:7076:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:7076:22: sparse: struct task_struct *
kernel/sched/core.c:11116:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:11116:25: sparse: expected struct task_struct *p
kernel/sched/core.c:11116:25: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:537:6: sparse: sparse: context imbalance in 'raw_spin_rq_lock_nested' - wrong count at exit
kernel/sched/core.c:562:6: sparse: sparse: context imbalance in 'raw_spin_rq_trylock' - wrong count at exit
kernel/sched/core.c:586:6: sparse: sparse: context imbalance in 'raw_spin_rq_unlock' - unexpected unlock
kernel/sched/core.c:624:36: sparse: sparse: context imbalance in '__task_rq_lock' - wrong count at exit
kernel/sched/core.c:665:36: sparse: sparse: context imbalance in 'task_rq_lock' - wrong count at exit
kernel/sched/core.c: note: in included file:
kernel/sched/pelt.h:78:13: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct const *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/pelt.h:78:13: sparse: expected struct task_struct const *p
kernel/sched/pelt.h:78:13: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:780:11: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2188:33: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2189:19: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2190:18: sparse: sparse: dereference of noderef expression
kernel/sched/core.c: note: in included file:
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/core.c:2163:38: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:2163:38: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:2163:38: sparse: struct task_struct const *
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/core.c: note: in included file (through arch/loongarch/include/asm/cpu-info.h, arch/loongarch/include/asm/processor.h, ...):
arch/loongarch/include/asm/loongarch.h:242:9: sparse: sparse: undefined identifier '__builtin_loongarch_csrwr_w'
arch/loongarch/include/asm/loongarch.h:242:9: sparse: sparse: cast from unknown type
arch/loongarch/include/asm/loongarch.h:247:9: sparse: sparse: undefined identifier '__builtin_loongarch_csrwr_d'
arch/loongarch/include/asm/loongarch.h:247:9: sparse: sparse: cast from unknown type
arch/loongarch/include/asm/loongarch.h:247:9: sparse: sparse: cast from unknown type
arch/loongarch/include/asm/loongarch.h:232:16: sparse: sparse: undefined identifier '__builtin_loongarch_csrrd_w'
arch/loongarch/include/asm/loongarch.h:232:16: sparse: sparse: cast from unknown type
arch/loongarch/include/asm/loongarch.h:242:9: sparse: sparse: cast from unknown type
kernel/sched/core.c: note: in included file:
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2018:25: sparse: struct task_struct *
kernel/sched/sched.h:2176:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2176:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2176:9: sparse: struct task_struct *
kernel/sched/sched.h:2018:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2018:25: sparse: struct task_struct [noderef] __rcu *
--
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got int [noderef] __percpu *
>> kernel/locking/mutex.c:357:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:357:9: sparse: expected void *ptr
kernel/locking/mutex.c:357:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got unsigned int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
kernel/locking/mutex.c:397:9: sparse: got int [noderef] __percpu *
kernel/locking/mutex.c:397:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/mutex.c:397:9: sparse: expected void *ptr
--
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got int [noderef] __percpu *
>> kernel/locking/rwsem.c:751:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/locking/rwsem.c:751:9: sparse: expected void *ptr
kernel/locking/rwsem.c:751:9: sparse: got int [noderef] __percpu *
--
kernel/rcu/tree.c: note: in included file:
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_exp.h:807:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_exp.h:807:9: sparse: expected void *ptr
kernel/rcu/tree_exp.h:807:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree.c: note: in included file:
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_plugin.h:720:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:720:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:720:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_plugin.h:1242:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_plugin.h:1242:9: sparse: expected void *ptr
kernel/rcu/tree_plugin.h:1242:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree.c: note: in included file:
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_nocb.h:377:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:377:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:377:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:154:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:154:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:154:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:167:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:167:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:167:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:180:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:180:17: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:180:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_nocb.h:190:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_nocb.h:190:9: sparse: expected void *ptr
kernel/rcu/tree_nocb.h:190:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree.c: note: in included file:
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got unsigned int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got int [noderef] __percpu *
>> kernel/rcu/tree_stall.h:224:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:224:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:224:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:700:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:700:9: sparse: expected void *ptr
kernel/rcu/tree_stall.h:700:9: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:941:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:941:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:941:17: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:957:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:957:25: sparse: expected void *ptr
kernel/rcu/tree_stall.h:957:25: sparse: got int [noderef] __percpu *
kernel/rcu/tree_stall.h:958:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:958:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:958:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:958:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:958:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:958:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:958:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/rcu/tree_stall.h:958:17: sparse: expected void *ptr
kernel/rcu/tree_stall.h:958:17: sparse: got unsigned int [noderef] __percpu *
kernel/rcu/tree_stall.h:958:17: sparse: sparse: too many warnings
--
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got unsigned int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got unsigned int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got int [noderef] __percpu *
>> kernel/time/timer.c:1432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *ptr @@ got int [noderef] __percpu * @@
kernel/time/timer.c:1432:17: sparse: expected void *ptr
kernel/time/timer.c:1432:17: sparse: got int [noderef] __percpu *
vim +571 kernel/smp.c
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 549
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 550 /**
16bf5a5e1ec564 Thomas Gleixner 2022-04-13 551 * __flush_smp_call_function_queue - Flush pending smp-call-function callbacks
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 552 *
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 553 * @warn_cpu_offline: If set to 'true', warn if callbacks were queued on an
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 554 * offline CPU. Skip this check if set to 'false'.
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 555 *
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 556 * Flush any pending smp-call-function callbacks queued on this CPU. This is
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 557 * invoked by the generic IPI handler, as well as by a CPU about to go offline,
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 558 * to ensure that all pending IPI callbacks are run before it goes completely
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 559 * offline.
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 560 *
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 561 * Loop through the call_single_queue and run all the queued callbacks.
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 562 * Must be called with interrupts disabled.
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 563 */
16bf5a5e1ec564 Thomas Gleixner 2022-04-13 564 static void __flush_smp_call_function_queue(bool warn_cpu_offline)
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 565 {
966a967116e699 Ying Huang 2017-08-08 566 call_single_data_t *csd, *csd_next;
52103be07d8b08 Peter Zijlstra 2020-05-26 567 struct llist_node *entry, *prev;
52103be07d8b08 Peter Zijlstra 2020-05-26 568 struct llist_head *head;
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 569 static bool warned;
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 570
83efcbd028ad3a Frederic Weisbecker 2017-11-06 @571 lockdep_assert_irqs_disabled();
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 572
bb964a92ce70ac Christoph Lameter 2014-08-17 573 head = this_cpu_ptr(&call_single_queue);
a5aabace5fb8ab Juergen Gross 2021-03-01 574 cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->handle, CFD_SEQ_NOCPU,
a5aabace5fb8ab Juergen Gross 2021-03-01 575 smp_processor_id(), CFD_SEQ_HANDLE);
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 576 entry = llist_del_all(head);
a5aabace5fb8ab Juergen Gross 2021-03-01 577 cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->dequeue,
a5aabace5fb8ab Juergen Gross 2021-03-01 578 /* Special meaning of source cpu: 0 == queue empty */
a5aabace5fb8ab Juergen Gross 2021-03-01 579 entry ? CFD_SEQ_NOCPU : 0,
a5aabace5fb8ab Juergen Gross 2021-03-01 580 smp_processor_id(), CFD_SEQ_DEQUEUE);
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 581 entry = llist_reverse_order(entry);
3d4422332711ef Jens Axboe 2008-06-26 582
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 583 /* There shouldn't be any pending callbacks on an offline CPU. */
8d056c48e48624 Srivatsa S. Bhat 2014-06-23 584 if (unlikely(warn_cpu_offline && !cpu_online(smp_processor_id()) &&
9e949a3886356f Nadav Amit 2022-03-19 585 !warned && entry != NULL)) {
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 586 warned = true;
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 587 WARN(1, "IPI on offline CPU %d\n", smp_processor_id());
269c861baa2fe7 Suresh Siddha 2009-08-19 588
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 589 /*
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 590 * We don't have to use the _safe() variant here
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 591 * because we are not invoking the IPI handlers yet.
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 592 */
545b8c8df41f9e Peter Zijlstra 2020-06-15 593 llist_for_each_entry(csd, entry, node.llist) {
4b44a21dd640b6 Peter Zijlstra 2020-05-26 594 switch (CSD_TYPE(csd)) {
4b44a21dd640b6 Peter Zijlstra 2020-05-26 595 case CSD_TYPE_ASYNC:
4b44a21dd640b6 Peter Zijlstra 2020-05-26 596 case CSD_TYPE_SYNC:
4b44a21dd640b6 Peter Zijlstra 2020-05-26 597 case CSD_TYPE_IRQ_WORK:
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 598 pr_warn("IPI callback %pS sent to offline CPU\n",
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 599 csd->func);
4b44a21dd640b6 Peter Zijlstra 2020-05-26 600 break;
4b44a21dd640b6 Peter Zijlstra 2020-05-26 601
a148866489fbe2 Peter Zijlstra 2020-05-26 602 case CSD_TYPE_TTWU:
a148866489fbe2 Peter Zijlstra 2020-05-26 603 pr_warn("IPI task-wakeup sent to offline CPU\n");
a148866489fbe2 Peter Zijlstra 2020-05-26 604 break;
a148866489fbe2 Peter Zijlstra 2020-05-26 605
4b44a21dd640b6 Peter Zijlstra 2020-05-26 606 default:
4b44a21dd640b6 Peter Zijlstra 2020-05-26 607 pr_warn("IPI callback, unknown type %d, sent to offline CPU\n",
4b44a21dd640b6 Peter Zijlstra 2020-05-26 608 CSD_TYPE(csd));
4b44a21dd640b6 Peter Zijlstra 2020-05-26 609 break;
4b44a21dd640b6 Peter Zijlstra 2020-05-26 610 }
4b44a21dd640b6 Peter Zijlstra 2020-05-26 611 }
a219ccf4637396 Srivatsa S. Bhat 2014-06-06 612 }
3d4422332711ef Jens Axboe 2008-06-26 613
52103be07d8b08 Peter Zijlstra 2020-05-26 614 /*
52103be07d8b08 Peter Zijlstra 2020-05-26 615 * First; run all SYNC callbacks, people are waiting for us.
52103be07d8b08 Peter Zijlstra 2020-05-26 616 */
52103be07d8b08 Peter Zijlstra 2020-05-26 617 prev = NULL;
545b8c8df41f9e Peter Zijlstra 2020-06-15 618 llist_for_each_entry_safe(csd, csd_next, entry, node.llist) {
4b44a21dd640b6 Peter Zijlstra 2020-05-26 619 /* Do we wait until *after* callback? */
4b44a21dd640b6 Peter Zijlstra 2020-05-26 620 if (CSD_TYPE(csd) == CSD_TYPE_SYNC) {
8053871d0f7f67 Linus Torvalds 2015-02-11 621 smp_call_func_t func = csd->func;
8053871d0f7f67 Linus Torvalds 2015-02-11 622 void *info = csd->info;
8053871d0f7f67 Linus Torvalds 2015-02-11 623
52103be07d8b08 Peter Zijlstra 2020-05-26 624 if (prev) {
545b8c8df41f9e Peter Zijlstra 2020-06-15 625 prev->next = &csd_next->node.llist;
52103be07d8b08 Peter Zijlstra 2020-05-26 626 } else {
545b8c8df41f9e Peter Zijlstra 2020-06-15 627 entry = &csd_next->node.llist;
52103be07d8b08 Peter Zijlstra 2020-05-26 628 }
4b44a21dd640b6 Peter Zijlstra 2020-05-26 629
35feb60474bf4f Paul E. McKenney 2020-06-30 630 csd_lock_record(csd);
8053871d0f7f67 Linus Torvalds 2015-02-11 631 func(info);
8053871d0f7f67 Linus Torvalds 2015-02-11 632 csd_unlock(csd);
35feb60474bf4f Paul E. McKenney 2020-06-30 633 csd_lock_record(NULL);
8053871d0f7f67 Linus Torvalds 2015-02-11 634 } else {
545b8c8df41f9e Peter Zijlstra 2020-06-15 635 prev = &csd->node.llist;
52103be07d8b08 Peter Zijlstra 2020-05-26 636 }
52103be07d8b08 Peter Zijlstra 2020-05-26 637 }
52103be07d8b08 Peter Zijlstra 2020-05-26 638
a5aabace5fb8ab Juergen Gross 2021-03-01 639 if (!entry) {
a5aabace5fb8ab Juergen Gross 2021-03-01 640 cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->hdlend,
a5aabace5fb8ab Juergen Gross 2021-03-01 641 0, smp_processor_id(),
a5aabace5fb8ab Juergen Gross 2021-03-01 642 CFD_SEQ_HDLEND);
a148866489fbe2 Peter Zijlstra 2020-05-26 643 return;
a5aabace5fb8ab Juergen Gross 2021-03-01 644 }
a148866489fbe2 Peter Zijlstra 2020-05-26 645
52103be07d8b08 Peter Zijlstra 2020-05-26 646 /*
52103be07d8b08 Peter Zijlstra 2020-05-26 647 * Second; run all !SYNC callbacks.
52103be07d8b08 Peter Zijlstra 2020-05-26 648 */
a148866489fbe2 Peter Zijlstra 2020-05-26 649 prev = NULL;
545b8c8df41f9e Peter Zijlstra 2020-06-15 650 llist_for_each_entry_safe(csd, csd_next, entry, node.llist) {
4b44a21dd640b6 Peter Zijlstra 2020-05-26 651 int type = CSD_TYPE(csd);
4b44a21dd640b6 Peter Zijlstra 2020-05-26 652
a148866489fbe2 Peter Zijlstra 2020-05-26 653 if (type != CSD_TYPE_TTWU) {
a148866489fbe2 Peter Zijlstra 2020-05-26 654 if (prev) {
545b8c8df41f9e Peter Zijlstra 2020-06-15 655 prev->next = &csd_next->node.llist;
a148866489fbe2 Peter Zijlstra 2020-05-26 656 } else {
545b8c8df41f9e Peter Zijlstra 2020-06-15 657 entry = &csd_next->node.llist;
a148866489fbe2 Peter Zijlstra 2020-05-26 658 }
a148866489fbe2 Peter Zijlstra 2020-05-26 659
4b44a21dd640b6 Peter Zijlstra 2020-05-26 660 if (type == CSD_TYPE_ASYNC) {
52103be07d8b08 Peter Zijlstra 2020-05-26 661 smp_call_func_t func = csd->func;
52103be07d8b08 Peter Zijlstra 2020-05-26 662 void *info = csd->info;
52103be07d8b08 Peter Zijlstra 2020-05-26 663
35feb60474bf4f Paul E. McKenney 2020-06-30 664 csd_lock_record(csd);
e1d12f327037a5 Andrew Morton 2013-04-30 665 csd_unlock(csd);
8053871d0f7f67 Linus Torvalds 2015-02-11 666 func(info);
35feb60474bf4f Paul E. McKenney 2020-06-30 667 csd_lock_record(NULL);
4b44a21dd640b6 Peter Zijlstra 2020-05-26 668 } else if (type == CSD_TYPE_IRQ_WORK) {
4b44a21dd640b6 Peter Zijlstra 2020-05-26 669 irq_work_single(csd);
4b44a21dd640b6 Peter Zijlstra 2020-05-26 670 }
a148866489fbe2 Peter Zijlstra 2020-05-26 671
a148866489fbe2 Peter Zijlstra 2020-05-26 672 } else {
545b8c8df41f9e Peter Zijlstra 2020-06-15 673 prev = &csd->node.llist;
8053871d0f7f67 Linus Torvalds 2015-02-11 674 }
3d4422332711ef Jens Axboe 2008-06-26 675 }
478850160636c4 Frederic Weisbecker 2014-05-08 676
478850160636c4 Frederic Weisbecker 2014-05-08 677 /*
a148866489fbe2 Peter Zijlstra 2020-05-26 678 * Third; only CSD_TYPE_TTWU is left, issue those.
478850160636c4 Frederic Weisbecker 2014-05-08 679 */
a148866489fbe2 Peter Zijlstra 2020-05-26 680 if (entry)
a148866489fbe2 Peter Zijlstra 2020-05-26 681 sched_ttwu_pending(entry);
a5aabace5fb8ab Juergen Gross 2021-03-01 682
a5aabace5fb8ab Juergen Gross 2021-03-01 683 cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->hdlend, CFD_SEQ_NOCPU,
a5aabace5fb8ab Juergen Gross 2021-03-01 684 smp_processor_id(), CFD_SEQ_HDLEND);
a148866489fbe2 Peter Zijlstra 2020-05-26 685 }
a148866489fbe2 Peter Zijlstra 2020-05-26 686
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 4/4] LoongArch: Add USER_STACKTRACE support
2022-08-01 12:17 [PATCH 0/4] LoongArch: Add unwinder support Qing Zhang
` (2 preceding siblings ...)
2022-08-01 12:17 ` [PATCH 3/4] LoongArch: Add stacktrace support Qing Zhang
@ 2022-08-01 12:17 ` Qing Zhang
2022-08-01 15:31 ` Huacai Chen
2022-08-01 15:34 ` [PATCH 0/4] LoongArch: Add unwinder support Huacai Chen
4 siblings, 1 reply; 21+ messages in thread
From: Qing Zhang @ 2022-08-01 12:17 UTC (permalink / raw)
To: Huacai Chen
Cc: WANG Xuerui, loongarch, linux-kernel, Jiaxun Yang, hejinyang, zhangqing
To get the best output you can compile your userspace programs with
frame pointers (at least glibc + the app you are tracing export "CC
=gcc -fno-omit-frame-pointer".
...
echo 'p:malloc /usr/lib64/libc.so.6:0x0a4704 size=%r4:u64'
> uprobe_events
echo 'p:free /usr/lib64/libc.so.6:0x0a4d50 ptr=%r4:x64'
>> uprobe_events
echo 'comm == "demo"' > ./events/uprobes/malloc/filter
echo 'comm == "demo"' > ./events/uprobes/free/filter
echo 1 > ./options/userstacktrace
echo 1 > ./options/sym-userobj
...
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/stacktrace.h | 5 +++
arch/loongarch/kernel/stacktrace.c | 42 +++++++++++++++++++++++++
3 files changed, 48 insertions(+)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 85d0fa3147cd..05906384d564 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -107,6 +107,7 @@ config LOONGARCH
select SWIOTLB
select TRACE_IRQFLAGS_SUPPORT
select USE_PERCPU_NUMA_NODE_ID
+ select USER_STACKTRACE_SUPPORT
select ZONE_DMA32
select MMU_GATHER_MERGE_VMAS if MMU
diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
index 49cb89213aeb..77fdb8ad662d 100644
--- a/arch/loongarch/include/asm/stacktrace.h
+++ b/arch/loongarch/include/asm/stacktrace.h
@@ -21,6 +21,11 @@ struct stack_info {
unsigned long begin, end, next_sp;
};
+struct stack_frame {
+ unsigned long fp;
+ unsigned long ra;
+};
+
bool in_task_stack(unsigned long stack, struct task_struct *task,
struct stack_info *info);
bool in_irq_stack(unsigned long stack, struct stack_info *info);
diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
index f4f4b8ad3917..344224c7cb0e 100644
--- a/arch/loongarch/kernel/stacktrace.c
+++ b/arch/loongarch/kernel/stacktrace.c
@@ -6,6 +6,7 @@
*/
#include <linux/sched.h>
#include <linux/stacktrace.h>
+#include <linux/uaccess.h>
#include <asm/stacktrace.h>
#include <asm/unwind.h>
@@ -35,3 +36,44 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
break;
}
}
+
+static int
+copy_stack_frame(unsigned long fp, struct stack_frame *frame)
+{
+ int ret;
+ unsigned long err;
+ unsigned long __user *user_frame_tail;
+
+ user_frame_tail = (unsigned long *)(fp - sizeof(struct stack_frame));
+ if (!access_ok(user_frame_tail, sizeof(*frame)))
+ return 0;
+
+ ret = 1;
+ pagefault_disable();
+ err = (__copy_from_user_inatomic(frame, user_frame_tail, sizeof(*frame)));
+ if (err || (unsigned long)user_frame_tail >= frame->fp)
+ ret = 0;
+ pagefault_enable();
+
+ return ret;
+}
+
+void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
+ const struct pt_regs *regs)
+{
+ unsigned long fp = regs->regs[22];
+
+ while (fp && !((unsigned long)fp & 0xf)) {
+ struct stack_frame frame;
+
+ frame.fp = 0;
+ frame.ra = 0;
+ if (!copy_stack_frame(fp, &frame))
+ break;
+ if (!frame.ra)
+ break;
+ if (!consume_entry(cookie, frame.ra))
+ break;
+ fp = frame.fp;
+ }
+}
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 4/4] LoongArch: Add USER_STACKTRACE support
2022-08-01 12:17 ` [PATCH 4/4] LoongArch: Add USER_STACKTRACE support Qing Zhang
@ 2022-08-01 15:31 ` Huacai Chen
0 siblings, 0 replies; 21+ messages in thread
From: Huacai Chen @ 2022-08-01 15:31 UTC (permalink / raw)
To: Qing Zhang; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>
> To get the best output you can compile your userspace programs with
> frame pointers (at least glibc + the app you are tracing export "CC
> =gcc -fno-omit-frame-pointer".
>
> ...
> echo 'p:malloc /usr/lib64/libc.so.6:0x0a4704 size=%r4:u64'
> > uprobe_events
> echo 'p:free /usr/lib64/libc.so.6:0x0a4d50 ptr=%r4:x64'
> >> uprobe_events
> echo 'comm == "demo"' > ./events/uprobes/malloc/filter
> echo 'comm == "demo"' > ./events/uprobes/free/filter
> echo 1 > ./options/userstacktrace
> echo 1 > ./options/sym-userobj
> ...
>
> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> ---
> arch/loongarch/Kconfig | 1 +
> arch/loongarch/include/asm/stacktrace.h | 5 +++
> arch/loongarch/kernel/stacktrace.c | 42 +++++++++++++++++++++++++
> 3 files changed, 48 insertions(+)
>
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 85d0fa3147cd..05906384d564 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -107,6 +107,7 @@ config LOONGARCH
> select SWIOTLB
> select TRACE_IRQFLAGS_SUPPORT
> select USE_PERCPU_NUMA_NODE_ID
> + select USER_STACKTRACE_SUPPORT
> select ZONE_DMA32
> select MMU_GATHER_MERGE_VMAS if MMU
>
> diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
> index 49cb89213aeb..77fdb8ad662d 100644
> --- a/arch/loongarch/include/asm/stacktrace.h
> +++ b/arch/loongarch/include/asm/stacktrace.h
> @@ -21,6 +21,11 @@ struct stack_info {
> unsigned long begin, end, next_sp;
> };
>
> +struct stack_frame {
> + unsigned long fp;
> + unsigned long ra;
> +};
> +
> bool in_task_stack(unsigned long stack, struct task_struct *task,
> struct stack_info *info);
> bool in_irq_stack(unsigned long stack, struct stack_info *info);
> diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
> index f4f4b8ad3917..344224c7cb0e 100644
> --- a/arch/loongarch/kernel/stacktrace.c
> +++ b/arch/loongarch/kernel/stacktrace.c
> @@ -6,6 +6,7 @@
> */
> #include <linux/sched.h>
> #include <linux/stacktrace.h>
> +#include <linux/uaccess.h>
>
> #include <asm/stacktrace.h>
> #include <asm/unwind.h>
> @@ -35,3 +36,44 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
> break;
> }
> }
> +
> +static int
> +copy_stack_frame(unsigned long fp, struct stack_frame *frame)
> +{
> + int ret;
> + unsigned long err;
> + unsigned long __user *user_frame_tail;
> +
> + user_frame_tail = (unsigned long *)(fp - sizeof(struct stack_frame));
> + if (!access_ok(user_frame_tail, sizeof(*frame)))
> + return 0;
> +
> + ret = 1;
Maybe initializing it at its definition is better?
Huacai
> + pagefault_disable();
> + err = (__copy_from_user_inatomic(frame, user_frame_tail, sizeof(*frame)));
> + if (err || (unsigned long)user_frame_tail >= frame->fp)
> + ret = 0;
> + pagefault_enable();
> +
> + return ret;
> +}
> +
> +void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
> + const struct pt_regs *regs)
> +{
> + unsigned long fp = regs->regs[22];
> +
> + while (fp && !((unsigned long)fp & 0xf)) {
> + struct stack_frame frame;
> +
> + frame.fp = 0;
> + frame.ra = 0;
> + if (!copy_stack_frame(fp, &frame))
> + break;
> + if (!frame.ra)
> + break;
> + if (!consume_entry(cookie, frame.ra))
> + break;
> + fp = frame.fp;
> + }
> +}
> --
> 2.20.1
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/4] LoongArch: Add unwinder support
2022-08-01 12:17 [PATCH 0/4] LoongArch: Add unwinder support Qing Zhang
` (3 preceding siblings ...)
2022-08-01 12:17 ` [PATCH 4/4] LoongArch: Add USER_STACKTRACE support Qing Zhang
@ 2022-08-01 15:34 ` Huacai Chen
2022-08-02 1:15 ` Xi Ruoyao
2022-08-02 1:35 ` zhangqing
4 siblings, 2 replies; 21+ messages in thread
From: Huacai Chen @ 2022-08-01 15:34 UTC (permalink / raw)
To: Qing Zhang; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
Hi, Qing,
I think we don't need to CC linux-kernel; on the other hand, CC
linux-arch and Arnd is worthy.
BTW, it seems you are missing V2 in the title.
Huacai
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.cn> wrote:
>
> This series in order to add stacktrace suport, Some upcoming features require
> these changes, like trace, divide unwinder into guess unwinder and prologue
> unwinder is to add new unwinders in the future, eg:unwind_frame, unwind_orc .etc.
> Three stages when we do unwind,
> 1) unwind_start(), the prapare of unwinding, fill unwind_state.
> 2) unwind_done(), judge whether the unwind process is finished or not.
> 3) unwind_next_frame(), unwind the next frame.
>
> you can test them by:
> 1) echo t > /proc/sysrq-trigger
> 2) cat /proc/*/stack
> 4) ftrace: function graph
> 5) uprobe: echo 1 > ./options/userstacktrace
>
> Changes from v1 to v2:
>
> - Add the judgment of the offset value of ra in the prologue.
> (Suggested by Youling).
> - Create an inline function to check the sign bit, which is convenient
> for extending other types of immediates. (Suggested by Jinyang).
> - Fix sparse warning :
> arch/loongarch/include/asm/uaccess.h:232:32: sparse: sparse: incorrect
> type in argument 2 (different address spaces) @@ expected void const
> *from @@ got void const [noderef] __user *from @@
> - Add USER_STACKTRACE support as a series.
>
> Qing Zhang (4):
> LoongArch: Add guess unwinder support
> LoongArch: Add prologue unwinder support
> LoongArch: Add stacktrace support
> LoongArch: Add USER_STACKTRACE support
>
> arch/loongarch/Kconfig | 6 +
> arch/loongarch/Kconfig.debug | 28 ++++
> arch/loongarch/include/asm/inst.h | 52 +++++++
> arch/loongarch/include/asm/processor.h | 9 ++
> arch/loongarch/include/asm/stacktrace.h | 22 +++
> arch/loongarch/include/asm/switch_to.h | 14 +-
> arch/loongarch/include/asm/uaccess.h | 4 +-
> arch/loongarch/include/asm/unwind.h | 45 +++++++
> arch/loongarch/kernel/Makefile | 4 +
> arch/loongarch/kernel/asm-offsets.c | 2 +
> arch/loongarch/kernel/process.c | 64 +++++++++
> arch/loongarch/kernel/stacktrace.c | 79 +++++++++++
> arch/loongarch/kernel/switch.S | 2 +
> arch/loongarch/kernel/traps.c | 27 ++--
> arch/loongarch/kernel/unwind_guess.c | 65 +++++++++
> arch/loongarch/kernel/unwind_prologue.c | 172 ++++++++++++++++++++++++
> 16 files changed, 577 insertions(+), 18 deletions(-)
> create mode 100644 arch/loongarch/include/asm/unwind.h
> create mode 100644 arch/loongarch/kernel/stacktrace.c
> create mode 100644 arch/loongarch/kernel/unwind_guess.c
> create mode 100644 arch/loongarch/kernel/unwind_prologue.c
>
> --
> 2.20.1
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/4] LoongArch: Add unwinder support
2022-08-01 15:34 ` [PATCH 0/4] LoongArch: Add unwinder support Huacai Chen
@ 2022-08-02 1:15 ` Xi Ruoyao
2022-08-02 1:35 ` zhangqing
1 sibling, 0 replies; 21+ messages in thread
From: Xi Ruoyao @ 2022-08-02 1:15 UTC (permalink / raw)
To: Huacai Chen, Qing Zhang
Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On Mon, 2022-08-01 at 23:34 +0800, Huacai Chen wrote:
> Hi, Qing,
>
> I think we don't need to CC linux-kernel; on the other hand, CC
> linux-arch and Arnd is worthy.
> BTW, it seems you are missing V2 in the title.
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#select-the-recipients-for-your-patch:
"linux-kernel@vger.kernel.org should be used by default for all
patches".
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/4] LoongArch: Add unwinder support
2022-08-01 15:34 ` [PATCH 0/4] LoongArch: Add unwinder support Huacai Chen
2022-08-02 1:15 ` Xi Ruoyao
@ 2022-08-02 1:35 ` zhangqing
1 sibling, 0 replies; 21+ messages in thread
From: zhangqing @ 2022-08-02 1:35 UTC (permalink / raw)
To: Huacai Chen; +Cc: WANG Xuerui, loongarch, LKML, Jiaxun Yang, Jinyang He
On 2022/8/1 下午11:34, Huacai Chen wrote:
> Hi, Qing,
>
> I think we don't need to CC linux-kernel; on the other hand, CC
> linux-arch and Arnd is worthy.
> BTW, it seems you are missing V2 in the title.
>
> Huacai
Hi, Huacai
Made a careless error...
Thanks,
-Qing
^ permalink raw reply [flat|nested] 21+ messages in thread