On Mon, 2 Nov 2026 21:44:52 -0500
Aaron Tomlin <[email protected]> wrote:
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index e8c4efa8107b..35a56f04e9b3 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -9519,6 +9519,9 @@ static void ftrace_dump_one(struct trace_array *tr,
> enum ftrace_dump_mode dump_m
> else
> iter.cpu_file = RING_BUFFER_ALL_CPUS;
>
> + if (printk_is_tail_full())
> + goto out_enable;
> +
> if (tr == &global_trace)
> printk(KERN_TRACE "Dumping ftrace buffer:\n");
> else
> @@ -9537,10 +9540,13 @@ static void ftrace_dump_one(struct trace_array *tr,
> enum ftrace_dump_mode dump_m
> * and then release the locks again.
> */
>
> - while (!trace_empty(&iter)) {
> + while (!trace_empty(&iter) && !printk_is_tail_full()) {
Wait? Is this to prevent overwriting the printk ring buffer? If so, this
is wrong here!
In your change log, you mention not losing the initial oops or registers.
But if someone is using ftrace_dump_on_oops, that's not what they are
after. They want to know what happened that lead to the crash. That output
is at the *end* of the trace.
By stopping the output of the ftrace buffer early, you just lost the
information you are looking for.
-- Steve
>
> - if (!cnt)
> + if (!cnt) {
> printk(KERN_TRACE
> "---------------------------------\n");
> + if (printk_is_tail_full())
> + break;
> + }
>
> cnt++;
>
> @@ -9551,19 +9557,25 @@ static void ftrace_dump_one(struct trace_array *tr,
> enum ftrace_dump_mode dump_m
> int ret;
>
> ret = print_trace_line(&iter);
> + trace_printk_seq(&iter.seq);
> + if (printk_is_tail_full())
> + break;
> +
> if (ret != TRACE_TYPE_NO_CONSUME)
> trace_consume(&iter);
> -
> - trace_printk_seq(&iter.seq);
> }
> touch_nmi_watchdog();
> }
>
> + if (printk_is_tail_full())
> + goto out_enable;
> +
> if (!cnt)
> printk(KERN_TRACE " (ftrace buffer empty)\n");
> else
> printk(KERN_TRACE "---------------------------------\n");
>
> +out_enable:
> tr->trace_flags |= old_userobj;
>
> tracer_tracing_enable(tr);