]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
powerpc: Work around tracing from dyntick-idle mode
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Sun, 4 Sep 2011 19:18:00 +0000 (12:18 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 13 Sep 2011 15:46:42 +0000 (08:46 -0700)
PowerPC LPAR's __trace_hcall_exit() can invoke event tracing at a
point where RCU has been told that the CPU is in dyntick-idle mode.
Because event tracing uses RCU, this can result in failures.

A correct fix would arrange for RCU to be told about dyntick-idle
mode after tracing had completed, however, this will require some care
because it appears that __trace_hcall_exit() can also be called from
non-dyntick-idle mode.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: anton@samba.org
Cc: benh@kernel.crashing.org
Cc: paulus@samba.org
arch/powerpc/platforms/pseries/lpar.c

index 39e6e0a7b2faf259db0f59e169f2fce9ab6fb1a0..668f30060b9fc3479ab3bb3efdd1bd9810f04503 100644 (file)
@@ -715,12 +715,14 @@ EXPORT_SYMBOL(arch_free_page);
 /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
 extern long hcall_tracepoint_refcount;
 
+#if 0 /* work around buggy use of RCU from dyntick-idle mode */
 /* 
  * Since the tracing code might execute hcalls we need to guard against
  * recursion. One example of this are spinlocks calling H_YIELD on
  * shared processor partitions.
  */
 static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
+#endif /* #if 0 work around buggy use of RCU from dyntick-idle mode */
 
 void hcall_tracepoint_regfunc(void)
 {
@@ -734,6 +736,7 @@ void hcall_tracepoint_unregfunc(void)
 
 void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
 {
+#if 0 /* work around buggy use of RCU from dyntick-idle mode */
        unsigned long flags;
        unsigned int *depth;
 
@@ -750,11 +753,13 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
 
 out:
        local_irq_restore(flags);
+#endif /* #if 0 work around buggy use of RCU from dyntick-idle mode */
 }
 
 void __trace_hcall_exit(long opcode, unsigned long retval,
                        unsigned long *retbuf)
 {
+#if 0 /* work around buggy use of RCU from dyntick-idle mode */
        unsigned long flags;
        unsigned int *depth;
 
@@ -771,6 +776,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval,
 
 out:
        local_irq_restore(flags);
+#endif /* #if 0 work around buggy use of RCU from dyntick-idle mode */
 }
 #endif