Commit 370a3b8f authored by Tiezhu Yang's avatar Tiezhu Yang Committed by Huacai Chen
Browse files

LoongArch: Check unwind_error() in arch_stack_walk()



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: default avatarGuenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/all/8a44ad71-68d2-4926-892f-72bfc7a67e2a@roeck-us.net/


Signed-off-by: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent e32b3b82
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;
}
+3 −1
Original line number Diff line number Diff line
@@ -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;
}