linux/kernel/trace
Steven Rostedt 14e4cb886b ring-buffer: Replace this_cpu_*() with __this_cpu_*()
commit 80a9b64e2c upstream.

It has come to my attention that this_cpu_read/write are horrible on
architectures other than x86. Worse yet, they actually disable
preemption or interrupts! This caused some unexpected tracing results
on ARM.

   101.356868: preempt_count_add <-ring_buffer_lock_reserve
   101.356870: preempt_count_sub <-ring_buffer_lock_reserve

The ring_buffer_lock_reserve has recursion protection that requires
accessing a per cpu variable. But since preempt_disable() is traced, it
too got traced while accessing the variable that is suppose to prevent
recursion like this.

The generic version of this_cpu_read() and write() are:

 #define this_cpu_generic_read(pcp)					\
 ({	typeof(pcp) ret__;						\
	preempt_disable();						\
	ret__ = *this_cpu_ptr(&(pcp));					\
	preempt_enable();						\
	ret__;								\
 })

 #define this_cpu_generic_to_op(pcp, val, op)				\
 do {									\
	unsigned long flags;						\
	raw_local_irq_save(flags);					\
	*__this_cpu_ptr(&(pcp)) op val;					\
	raw_local_irq_restore(flags);					\
 } while (0)

Which is unacceptable for locations that know they are within preempt
disabled or interrupt disabled locations.

Paul McKenney stated that __this_cpu_() versions produce much better code on
other architectures than this_cpu_() does, if we know that the call is done in
a preempt disabled location.

I also changed the recursive_unlock() to use two local variables instead
of accessing the per_cpu variable twice.

Link: http://lkml.kernel.org/r/20150317114411.GE3589@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/20150317104038.312e73d1@gandalf.local.home

Acked-by: Christoph Lameter <cl@linux.com>
Reported-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Tested-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
History 2015-05-05 11:09:32 +01: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: Fix ftrace enable ordering of sysctl ftrace_enabled 2015-03-23 15:16:57 +00:00
Kconfig tracing: Add tracepoint benchmark tracepoint 2014-05-29 22:49:54 -04:00
Makefile tracing: Add tracepoint benchmark tracepoint 2014-05-29 22:49:54 -04:00
power-traces.c PM / tracing: remove deprecated power trace API 2013-01-26 00:39:12 +01:00
ring_buffer.c ring-buffer: Replace this_cpu_*() with __this_cpu_*() 2015-05-05 11:09:32 +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 tracing: Fix unmapping loop in tracing_mark_write 2015-03-02 13:17:11 +00:00
trace.h tracing: Fix check of ftrace_trace_arrays list_empty() check 2014-06-10 13:53:50 -04:00
trace_benchmark.c tracing: Only calculate stats of tracepoint benchmarks for 2^32 times 2014-06-06 00:41:38 -04:00
trace_benchmark.h tracing: Add tracepoint benchmark tracepoint 2014-05-29 22:49:54 -04:00
trace_branch.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_clock.c tracing: Fix wraparound problems in "uptime" trace clock 2014-07-21 09:56:12 -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 kprobes, ftrace: Use NOKPROBE_SYMBOL macro in ftrace 2014-04-24 10:26:39 +02:00
trace_events.c move d_rcu from overlapping d_child to overlapping d_alias 2015-01-15 10:44:58 +00: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 tracing: Use rcu_dereference_sched() for trace event triggers 2014-05-02 23:12:42 -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: Remove mock up poll wait function 2014-04-30 08:40:05 -04:00
trace_functions_graph.c tracing: Add funcgraph_tail option to print function name after closing braces 2014-05-20 23:29:32 -04:00
trace_irqsoff.c tracing: Allow irq/preempt tracers to be used by instances 2014-04-21 13:59:29 -04:00
trace_kdb.c tracing: Consolidate max_tr into main trace_array structure 2013-03-15 00:35:40 -04:00
trace_kprobe.c Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-06-12 19:18:49 -07:00
trace_mmiotrace.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_nop.c tracing: Remove mock up poll wait function 2014-04-30 08:40:05 -04:00
trace_output.c tracing: Add __bitmask() macro to trace events to cpumasks and other bitmasks 2014-05-15 11:29:37 -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 kprobes, ftrace: Use NOKPROBE_SYMBOL macro in ftrace 2014-04-24 10:26:39 +02:00
trace_probe.h kprobes, ftrace: Use NOKPROBE_SYMBOL macro in ftrace 2014-04-24 10:26:39 +02:00
trace_sched_switch.c tracing: Update event filters for multibuffer 2013-11-05 16:50:20 -05:00
trace_sched_wakeup.c tracing: Remove mock up poll wait function 2014-04-30 08:40:05 -04:00
trace_selftest.c tracing: Add static to local functions 2014-04-21 14:00:46 -04: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: Print max callstack on stacktrace bug 2014-06-02 16:43:49 -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/syscalls: Ignore numbers outside NR_syscalls' range 2014-11-13 11:49:02 +00:00
trace_uprobe.c tracing/uprobes: Fix the usage of uprobe_buffer_enable() in probe_event_enable() 2014-06-30 13:22:33 -04:00