On 29.03.2017 09:45, zhouchengming wrote:
On 2017/3/28 23:31, Evgenii Shatokhin wrote:
Hi,
I am not very familiar with the internals of ftrace, hence this question.
Suppose klp_ftrace_handler() is running on one CPU and, at the same
time, klp_disable_func() calls unregister_ftrace_function() and then
ftrace_set_filter_ip() on another CPU.
Is it guaranteed then, that by the time ftrace_set_filter_ip()
returns, klp_ftrace_handler() is no longer running?
Hi, if I understand your question correctly, I think you want to see
this comment in ftrace_shutdown() (called from
unregister_ftrace_function())
/*
* Dynamic ops may be freed, we must make sure that all
* callers are done before leaving this function.
* The same goes for freeing the per_cpu data of the per_cpu
* ops.
*
* Again, normal synchronize_sched() is not good enough.
* We need to do a hard force of sched synchronization.
* This is because we use preempt_disable() to do RCU, but
* the function tracers can be called where RCU is not watching
* (like before user_exit()). We can not rely on the RCU
* infrastructure to do the synchronization, thus we must do it
* ourselves.
*/
if (ops->flags & (FTRACE_OPS_FL_DYNAMIC |
FTRACE_OPS_FL_PER_CPU)) {
schedule_on_each_cpu(ftrace_sync);
arch_ftrace_trampoline_free(ops);
if (ops->flags & FTRACE_OPS_FL_PER_CPU)
per_cpu_ops_free(ops);
}
Thanks.
Looks like this is it, thanks.
schedule_on_each_cpu(ftrace_sync) will return only when all online CPUs
complete ftrace_sync(), so all the previous code has completed by that
time as well. Good, this makes things easier.
klp_disable_func() is written with this assumption in mind as it
kfrees struct klp_ops instance that klp_ftrace_handler() might be using.
Nothing crashed in my experiments with that code so far, it is just
not obvious to me if the above guarantee exists.
Regards,
Evgenii
--
--
To unsubscribe from this list: send the line "unsubscribe live-patching" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html