]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
LoongArch: Check unwind_error() in arch_stack_walk()
authorTiezhu Yang <yangtiezhu@loongson.cn>
Wed, 19 Apr 2023 04:07:27 +0000 (12:07 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 19 Apr 2023 04:07:27 +0000 (12:07 +0800)
We can see the following messages with CONFIG_PROVE_LOCKING=y on
LoongArch:

  BUG: MAX_STACK_TRACE_ENTRIES too low!
  turning off the locking correctness validator.

This is because stack_trace_save() returns a big value after call
arch_stack_walk(), here is the call trace:

  save_trace()
    stack_trace_save()
      arch_stack_walk()
        stack_trace_consume_entry()

arch_stack_walk() should return immediately if unwind_next_frame()
failed, no need to do the useless loops to increase the value of c->len
in stack_trace_consume_entry(), then we can fix the above problem.

Cc: stable@vger.kernel.org
Reported-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/all/8a44ad71-68d2-4926-892f-72bfc7a67e2a@roeck-us.net/
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kernel/stacktrace.c
arch/loongarch/kernel/unwind.c
arch/loongarch/kernel/unwind_prologue.c

index 3a690f96f00c1a67edccefd66c8f46f006dd4f4e..2463d2fea21f5f4bc9dd762fd5b1ed3c77c0fc40 100644 (file)
@@ -30,7 +30,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
 
        regs->regs[1] = 0;
        for (unwind_start(&state, task, regs);
-             !unwind_done(&state); unwind_next_frame(&state)) {
+            !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
                addr = unwind_get_return_address(&state);
                if (!addr || !consume_entry(cookie, addr))
                        break;
index a463d6961344c0899aacd72a8951b9cc5d18ea83..ba324ba76fa15605d9ada6c26101ce78aa108df1 100644 (file)
@@ -28,5 +28,6 @@ bool default_next_frame(struct unwind_state *state)
 
        } while (!get_stack_info(state->sp, state->task, info));
 
+       state->error = true;
        return false;
 }
index 9095fde8e55d5c57177c83ab0548ab888c348f16..55afc27320e12a1c52fd98445ef32f383f1d2bf1 100644 (file)
@@ -211,7 +211,7 @@ static bool next_frame(struct unwind_state *state)
                        pc = regs->csr_era;
 
                        if (user_mode(regs) || !__kernel_text_address(pc))
-                               return false;
+                               goto out;
 
                        state->first = true;
                        state->pc = pc;
@@ -226,6 +226,8 @@ static bool next_frame(struct unwind_state *state)
 
        } while (!get_stack_info(state->sp, state->task, info));
 
+out:
+       state->error = true;
        return false;
 }