alistair23-linux/kernel/trace
Steven Rostedt (Red Hat) a949ae560a ftrace/module: Hardcode ftrace_module_init() call into load_module()
A race exists between module loading and enabling of function tracer.

	CPU 1				CPU 2
	-----				-----
  load_module()
   module->state = MODULE_STATE_COMING

				register_ftrace_function()
				 mutex_lock(&ftrace_lock);
				 ftrace_startup()
				  update_ftrace_function();
				   ftrace_arch_code_modify_prepare()
				    set_all_module_text_rw();
				   <enables-ftrace>
				    ftrace_arch_code_modify_post_process()
				     set_all_module_text_ro();

				[ here all module text is set to RO,
				  including the module that is
				  loading!! ]

   blocking_notifier_call_chain(MODULE_STATE_COMING);
    ftrace_init_module()

     [ tries to modify code, but it's RO, and fails!
       ftrace_bug() is called]

When this race happens, ftrace_bug() will produces a nasty warning and
all of the function tracing features will be disabled until reboot.

The simple solution is to treate module load the same way the core
kernel is treated at boot. To hardcode the ftrace function modification
of converting calls to mcount into nops. This is done in init/main.c
there's no reason it could not be done in load_module(). This gives
a better control of the changes and doesn't tie the state of the
module to its notifiers as much. Ftrace is special, it needs to be
treated as such.

The reason this would work, is that the ftrace_module_init() would be
called while the module is in MODULE_STATE_UNFORMED, which is ignored
by the set_all_module_text_ro() call.

Link: http://lkml.kernel.org/r/1395637826-3312-1-git-send-email-indou.takao@jp.fujitsu.com

Reported-by: Takao Indoh <indou.takao@jp.fujitsu.com>
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: stable@vger.kernel.org # 2.6.38+
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2014-04-28 10:37:21 -04:00
..
blktrace.c Most of the changes were largely clean ups, and some documentation. 2014-04-03 10:26:31 -07:00
ftrace.c ftrace/module: Hardcode ftrace_module_init() call into load_module() 2014-04-28 10:37:21 -04:00
Kconfig uprobes: Kconfig dependency fix 2014-03-18 16:39:33 -04:00
Makefile tracing: Add basic event trigger framework 2013-12-20 18:40:22 -05:00
power-traces.c PM / tracing: remove deprecated power trace API 2013-01-26 00:39:12 +01:00
ring_buffer.c trace, ring-buffer: Fix CPU hotplug callback registration 2014-03-20 13:43:48 +01:00
ring_buffer_benchmark.c trace: Replace hardcoding of 19 with MAX_NICE 2014-02-27 12:41:03 +01:00
rpm-traces.c PM / Runtime: Introduce trace points for tracing rpm_* functions 2011-09-27 22:53:27 +02:00
trace.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-04-12 14:49:50 -07:00
trace.h kernel: use macros from compiler.h instead of __attribute__((...)) 2014-04-07 16:36:11 -07:00
trace_branch.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_clock.c tracing: Add "uptime" trace clock that uses jiffies 2013-03-15 00:36:09 -04:00
trace_entries.h tracing: Add trace_puts() for even faster trace_printk() tracing 2013-03-15 00:35:55 -04:00
trace_event_perf.c perf: Disallow user-space stack dumps for function trace events 2014-03-11 11:57:58 +01:00
trace_events.c tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints 2014-04-08 20:43:28 -04:00
trace_events_filter.c tracing: Add and use generic set_trigger_filter() implementation 2013-12-21 22:02:17 -05:00
trace_events_filter_test.h tracing/filter: Add startup tests for events filter 2011-08-19 14:35:59 -04:00
trace_events_trigger.c tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints 2014-04-08 20:43:28 -04:00
trace_export.c tracing: Fix anonymous unions in struct ftrace_event_call 2014-04-09 20:02:55 -04:00
trace_functions.c tracing: Do not try to recreated toplevel set_ftrace_* files 2014-04-16 19:21:53 -04:00
trace_functions_graph.c tracing: Pass trace_array to set_flag callback 2014-02-20 12:13:07 -05:00
trace_irqsoff.c Most of the changes were largely clean ups, and some documentation. 2014-04-03 10:26:31 -07:00
trace_kdb.c tracing: Consolidate max_tr into main trace_array structure 2013-03-15 00:35:40 -04:00
trace_kprobe.c tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints 2014-04-08 20:43:28 -04:00
trace_mmiotrace.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_nop.c tracing: Set up infrastructure to allow tracers for instances 2014-02-20 12:13:10 -05:00
trace_output.c tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints 2014-04-08 20:43:28 -04:00
trace_output.h tracing: Rename trace_event_mutex to trace_event_sem 2013-03-15 13:22:10 -04:00
trace_printk.c tracing: Add __tracepoint_string() to export string pointers 2013-07-26 13:39:44 -04:00
trace_probe.c tracing/uprobes: Add @+file_offset fetch method 2014-01-02 20:57:05 -05:00
trace_probe.h tracing/uprobes: Support ftrace_event_file base multibuffer 2014-02-20 12:30:09 -05:00
trace_sched_switch.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_sched_wakeup.c tracing: Pass trace_array to flag_changed callback 2014-02-20 12:13:08 -05:00
trace_selftest.c sched/deadline: Add latency tracing for SCHED_DEADLINE tasks 2014-01-13 13:41:11 +01:00
trace_selftest_dynamic.c ftrace: Add self-tests for multiple function trace users 2011-05-18 19:24:51 -04:00
trace_stack.c tracing: Add BUG_ON when stack end location is over written 2014-03-24 10:39:11 -04:00
trace_stat.c trace/trace_stat: use rbtree postorder iteration helper instead of opencoding 2013-11-05 16:01:47 -05:00
trace_stat.h tracing/stat: Add stat_release() callback 2009-07-10 12:14:05 +02:00
trace_syscalls.c tracing: Consolidate event trigger code 2014-01-09 21:20:07 -05:00
trace_uprobe.c tracing/uprobes: Fix uprobe_cpu_buffer memory leak 2014-04-17 10:44:42 -04:00