From: Kees Cook <keescook@chromium.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
x86@kernel.org, linux-kernel@vger.kernel.org,
juri.lelli@redhat.com, vincent.guittot@linaro.org,
dietmar.eggemann@arm.com, rostedt@goodmis.org,
bsegall@google.com, mgorman@suse.de, bristot@redhat.com,
akpm@linux-foundation.org, zhengqi.arch@bytedance.com,
linux@armlinux.org.uk, catalin.marinas@arm.com, will@kernel.org,
mpe@ellerman.id.au, paul.walmsley@sifive.com, palmer@dabbelt.com,
hca@linux.ibm.com, gor@linux.ibm.com, borntraeger@de.ibm.com,
linux-arch@vger.kernel.org, ardb@kernel.org
Subject: Re: [PATCH 2/7] stacktrace,sched: Make stack_trace_save_tsk() more robust
Date: Mon, 25 Oct 2021 13:52:07 -0700 [thread overview]
Message-ID: <202110251351.6B61CE297@keescook> (raw)
In-Reply-To: <YXcVySsxQO4Iakbq@hirez.programming.kicks-ass.net>
On Mon, Oct 25, 2021 at 10:38:33PM +0200, Peter Zijlstra wrote:
> On Fri, Oct 22, 2021 at 07:01:35PM +0200, Peter Zijlstra wrote:
> > On Fri, Oct 22, 2021 at 05:54:31PM +0100, Mark Rutland wrote:
> >
> > > > Pardon my thin understanding of the scheduler, but I assume this change
> > > > doesn't mean stack_trace_save_tsk() stops working for "current", right?
> > > > In trying to answer this for myself, I couldn't convince myself what value
> > > > current->__state have here. Is it one of TASK_(UN)INTERRUPTIBLE ?
> > >
> > > Regardless of that, current->on_rq will be non-zero, so you're right that this
> > > causes stack_trace_save_tsk() to not work for current, e.g.
> > >
> > > | # cat /proc/self/stack
> > > | # wc /proc/self/stack
> > > | 0 0 0 /proc/self/stack
> > >
> > > TBH, I think that (taking a step back from this issue in particular)
> > > stack_trace_save_tsk() *shouldn't* work for current, and callers *should* be
> > > forced to explicitly handle current separately from blocked tasks.
> >
> > That..
>
> So I think I'd prefer the following approach to that (and i'm not
> currently volunteering for it):
>
> - convert all archs to ARCH_STACKWALK; this gets the semantics out of
> arch code and into the single kernel/stacktrace.c file.
>
> - bike-shed a new/improved stack_trace_save*() API and implement it
> *once* in generic code based on arch_stack_walk().
>
> - convert users; delete old etc..
>
> For now, current users of stack_trace_save_tsk() very much expect
> tsk==current to work.
>
> > > So we could fix this in the stacktrace code with:
> > >
> > > | diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c
> > > | index a1cdbf8c3ef8..327af9ff2c55 100644
> > > | --- a/kernel/stacktrace.c
> > > | +++ b/kernel/stacktrace.c
> > > | @@ -149,7 +149,10 @@ unsigned int stack_trace_save_tsk(struct task_struct *tsk, unsigned long *store,
> > > | .skip = skipnr + (current == tsk),
> > > | };
> > > |
> > > | - task_try_func(tsk, try_arch_stack_walk_tsk, &c);
> > > | + if (tsk == current)
> > > | + try_arch_stack_walk_tsk(tsk, &c);
> > > | + else
> > > | + task_try_func(tsk, try_arch_stack_walk_tsk, &c);
> > > |
> > > | return c.len;
> > > | }
> > >
> > > ... and we could rename task_try_func() to blocked_task_try_func(), and
> > > later push the distinction into higher-level callers.
> >
> > I think I favour this fix if we have to. But that's for next week :-)
>
> I ended up with the below delta to this patch.
>
> --- a/kernel/stacktrace.c
> +++ b/kernel/stacktrace.c
> @@ -101,7 +101,7 @@ static bool stack_trace_consume_entry_no
> }
>
> /**
> - * stack_trace_save - Save a stack trace into a storage array
> + * stack_trace_save - Save a stack trace (of current) into a storage array
> * @store: Pointer to storage array
> * @size: Size of the storage array
> * @skipnr: Number of entries to skip at the start of the stack trace
> @@ -132,7 +132,7 @@ static int try_arch_stack_walk_tsk(struc
>
> /**
> * stack_trace_save_tsk - Save a task stack trace into a storage array
> - * @task: The task to examine
> + * @task: The task to examine (current allowed)
> * @store: Pointer to storage array
> * @size: Size of the storage array
> * @skipnr: Number of entries to skip at the start of the stack trace
> @@ -149,13 +149,25 @@ unsigned int stack_trace_save_tsk(struct
> .skip = skipnr + (current == tsk),
> };
>
> - task_try_func(tsk, try_arch_stack_walk_tsk, &c);
> + /*
> + * If the task doesn't have a stack (e.g., a zombie), the stack is
> + * empty.
> + */
> + if (!try_get_task_stack(tsk))
> + return 0;
> +
> + if (tsk == current)
> + try_arch_stack_walk_tsk(tsk, &c);
> + else
> + task_try_func(tsk, try_arch_stack_walk_tsk, &c);
> +
> + put_task_stack(tsk);
>
> return c.len;
> }
>
> /**
> - * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
> + * stack_trace_save_regs - Save a stack trace (of current) based on pt_regs into a storage array
> * @regs: Pointer to pt_regs to examine
> * @store: Pointer to storage array
> * @size: Size of the storage array
Looks good to me, though I did like Mark's idea to name "task_try_func"
to "task_blocked_try_func" or something like that to make the "why can
this fail?" be more self-documenting. *shrug*
Reviewed-by: Kees Cook <keescook@chromium.org>
--
Kees Cook
next prev parent reply other threads:[~2021-10-25 20:52 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-22 15:09 [PATCH 0/7] arch: More wchan fixes Peter Zijlstra
2021-10-22 15:09 ` [PATCH 1/7] x86: Fix __get_wchan() for !STACKTRACE Peter Zijlstra
2021-10-22 16:25 ` Kees Cook
2021-10-26 19:16 ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2021-10-22 15:09 ` [PATCH 2/7] stacktrace,sched: Make stack_trace_save_tsk() more robust Peter Zijlstra
2021-10-22 16:25 ` Kees Cook
2021-10-22 16:45 ` Peter Zijlstra
2021-10-22 16:57 ` Mark Rutland
2021-10-22 16:54 ` Mark Rutland
2021-10-22 17:01 ` Peter Zijlstra
2021-10-25 20:38 ` Peter Zijlstra
2021-10-25 20:52 ` Kees Cook [this message]
2021-10-26 9:33 ` Mark Rutland
2021-10-25 16:27 ` Peter Zijlstra
2021-10-22 15:09 ` [PATCH 3/7] ARM: implement ARCH_STACKWALK Peter Zijlstra
2021-10-22 16:18 ` Kees Cook
2021-10-22 15:09 ` [PATCH 4/7] arch: Make ARCH_STACKWALK independent of STACKTRACE Peter Zijlstra
2021-10-22 16:18 ` Kees Cook
2021-10-22 16:36 ` Peter Zijlstra
2021-10-22 17:06 ` Mark Rutland
2021-10-22 15:09 ` [PATCH 5/7] powerpc, arm64: Mark __switch_to() as __sched Peter Zijlstra
2021-10-22 16:15 ` Kees Cook
2021-10-22 17:40 ` Mark Rutland
2021-10-22 15:09 ` [PATCH 6/7] arch: __get_wchan() || ARCH_STACKWALK Peter Zijlstra
2021-10-22 16:13 ` Kees Cook
2021-10-22 17:52 ` Mark Rutland
2021-10-22 15:09 ` [PATCH 7/7] selftests: proc: Make sure wchan works when it exists Peter Zijlstra
2021-10-22 15:27 ` [PATCH 0/7] arch: More wchan fixes Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202110251351.6B61CE297@keescook \
--to=keescook@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=ardb@kernel.org \
--cc=borntraeger@de.ibm.com \
--cc=bristot@redhat.com \
--cc=bsegall@google.com \
--cc=catalin.marinas@arm.com \
--cc=dietmar.eggemann@arm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=juri.lelli@redhat.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=mark.rutland@arm.com \
--cc=mgorman@suse.de \
--cc=mpe@ellerman.id.au \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=vincent.guittot@linaro.org \
--cc=will@kernel.org \
--cc=x86@kernel.org \
--cc=zhengqi.arch@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.