瀏覽代碼

rcu: Do not trace rcu_is_watching() functions

As perf uses the rcu_read_lock() primitives for recording into its
ring buffer, perf tracing can not be called when RCU in inactive.
With the perf function tracing, there are functions that can be
traced when RCU is not active, and perf must not have its function
callback called when this is the case.

Luckily, Paul McKenney has created a way to detect when RCU is
active or not with the rcu_is_watching() function. Unfortunately,
this function can also be traced, and if that happens it can cause
a bit of overhead for the perf function calls that do the check.
Recursion protection prevents anything bad from happening, but
there is a bit of added overhead for every function being traced that
must detect that the rcu_is_watching() is also being traced.

As rcu_is_watching() is a helper routine and not part of the
critical logic in RCU, it does not need to be traced in order to
debug RCU itself. Add the "notrace" annotation to all the rcu_is_watching()
calls such that we never trace it.

Link: http://lkml.kernel.org/r/20131104202736.72dd8e45@gandalf.local.home

Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Steven Rostedt 11 年之前
父節點
當前提交
9418fb2080
共有 2 個文件被更改,包括 3 次插入3 次删除
  1. 1 1
      kernel/rcutiny.c
  2. 2 2
      kernel/rcutree.c

+ 1 - 1
kernel/rcutiny.c

@@ -179,7 +179,7 @@ EXPORT_SYMBOL_GPL(rcu_irq_enter);
 /*
 /*
  * Test whether RCU thinks that the current CPU is idle.
  * Test whether RCU thinks that the current CPU is idle.
  */
  */
-bool __rcu_is_watching(void)
+bool notrace __rcu_is_watching(void)
 {
 {
 	return rcu_dynticks_nesting;
 	return rcu_dynticks_nesting;
 }
 }

+ 2 - 2
kernel/rcutree.c

@@ -662,7 +662,7 @@ void rcu_nmi_exit(void)
  * rcu_is_watching(), the caller of __rcu_is_watching() must have at
  * rcu_is_watching(), the caller of __rcu_is_watching() must have at
  * least disabled preemption.
  * least disabled preemption.
  */
  */
-bool __rcu_is_watching(void)
+bool notrace __rcu_is_watching(void)
 {
 {
 	return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1;
 	return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1;
 }
 }
@@ -673,7 +673,7 @@ bool __rcu_is_watching(void)
  * If the current CPU is in its idle loop and is neither in an interrupt
  * If the current CPU is in its idle loop and is neither in an interrupt
  * or NMI handler, return true.
  * or NMI handler, return true.
  */
  */
-bool rcu_is_watching(void)
+bool notrace rcu_is_watching(void)
 {
 {
 	int ret;
 	int ret;