Hi Steven, I am afraid there is a bug in the current mainline's ftrace when dynamic fops are involved.
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. 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. or 2. implement the whole thing through RCU_TASKS. This would also enable dynamic trampolines for PREEMPT kernels. Revert of 00ccbf2f5b75 commit would be solution as well but there is a drawback. Regards, Miroslav