From: Miroslav Benes <mbenes@suse.cz>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: A bug in ftrace - dynamic fops
Date: Tue, 9 Aug 2016 10:16:00 +0200 (CEST) [thread overview]
Message-ID: <alpine.LNX.2.00.1608090952540.3919@pobox.suse.cz> (raw)
In-Reply-To: <20160808105303.16bf85ed@gandalf.local.home>
On Mon, 8 Aug 2016, Steven Rostedt wrote:
> On Mon, 8 Aug 2016 10:57:45 +0200 (CEST)
> Miroslav Benes <mbenes@suse.cz> wrote:
>
> > Hi Steven,
> >
> > I am afraid there is a bug in the current mainline's ftrace when dynamic
> > fops are involved.
>
> I'm sorry but I don't see it.
>
> >
> > ftrace_shutdown() relies on schedule_on_each_cpu() which should ensure
> > that no task stays in a ftrace handler. This was sufficient for a long
> > time because every handler was called with the preemption disabled thanks
> > to ftrace_ops_list_func (or ftrace_ops_assist_func). Dynamic trampolines
> > did not change the behaviour because !PREEMPT was required (commit
> > 12cce594fa8f ("ftrace/x86: Allow !CONFIG_PREEMPT dynamic ops to use
> > allocated trampolines")).
> >
> > Situation changed with the commit 00ccbf2f5b75 ("ftrace/x86: Let dynamic
> > trampolines call ops->func even for dynamic fops"). The purpose of the
> > patch is clear - to call ops->func whenever possible and thus gain an
> > advantage of dynamic trampolines. But it also allows the handler (that
> > very ops->func) to sleep because no atomic context is enforced. This
> > breaks the assumption for schedule_on_each_cpu() in ftrace_shutdown() and
> > one can crash the kernel quite easily.
>
> Not when CONFIG_PREEMPT is not enabled. This is because the kernel does
> not preempt unless it specifically asks to be preempted. If ops->func()
> calls a mutex, or sleeps, then *THAT* is a bug! ops->func() is more
> sensitive than interrupt handlers, and all ops->func()s must use extra
> care. This sounds like a "doctor it hurts me when I do this" bug (where
> the doctor replies "well, don't do that").
I agree it is kind of shooting oneself in the foot bug, because explicit
call to a sleeping function may not be the brightest thing to do. However
I see two (closely related) issues with this.
1. It is a change in behaviour. Ftrace silently relies on an atomicity of
ops->func(). I don't see it documented anywhere, but it did not matter
because the atomicity was always guaranteed as described above. Now there
is a possibility to achieve a situation which breaks the assumption. It
makes me worried.
2. Previously if someone called a function which could sleep he was
immediately warned not to do so via "sleeping in atomic context" BUG. Now
he wouldn't know. That's because in_atomic() and might_sleep()
infrastructure does not work in ops->func(). in_atomic() gives 0 even if
it is an atomic context in fact. But well, the comment for in_atomic() in
linux/preempt.h warns about exactly this situation I guess.
Anyway, it is your call.
> If something registers an ops->func() that can sleep, then it MUST limit
> the functions that it can be registered to, and also must handle any
> synchronization of the ops itself being freed. This isn't the ftrace
> infrastructure's responsibility.
>
> >
> > It suffices to register dynamic fops with FTRACE_OPS_FL_RECURSION_SAFE set
> > (because otherwise ftrace_ops_assist_func() is used which also disables
> > preemption), sleep in the handler and meanwhile remove it.
> >
> > I can imagine two reasonable solutions...
> >
> > 1. introduce something similar to ftrace_ops_assist_func() which would
> > just disable preemption before calling ops->func and enable it afterwards.
>
> With CONFIG_PREEMPT disabled, how can ops->func() sleep? It can't,
> unless it specifically calls a function that can. I don't see the bug
> you mention here.
>
> >
> > or
> >
> > 2. implement the whole thing through RCU_TASKS. This would also enable
> > dynamic trampolines for PREEMPT kernels.
>
> That said, this has been on my todo list for too long, and will soon be
> implemented. I want CONFIG_PREEMPT to allow dynamic trampolines for
> dynamic ops too. Not to mention, RCU_TASKS was specifically written for
> me to do this. I dropped the ball on this one. :-p
That is great to hear. Looking forward to seeing that.
Thanks,
Miroslav
next prev parent reply other threads:[~2016-08-09 8:16 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-08 8:57 Miroslav Benes
2016-08-08 14:53 ` Steven Rostedt
2016-08-09 8:16 ` Miroslav Benes [this message]
2016-08-09 12:17 ` Steven Rostedt
2016-08-11 8:46 ` Miroslav Benes
2016-08-11 14:01 ` Steven Rostedt
2016-08-11 14:08 ` Miroslav Benes
2016-08-11 14:33 ` Steven Rostedt
2016-08-11 14:54 ` Miroslav Benes
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=alpine.LNX.2.00.1608090952540.3919@pobox.suse.cz \
--to=mbenes@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=rostedt@goodmis.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®