mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®