]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 16:43:24 +0000 (09:43 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 16:43:24 +0000 (09:43 -0700)
added patches:
tracing-use-current_uid-for-critical-time-tracing.patch

queue-3.4/series
queue-3.4/tracing-use-current_uid-for-critical-time-tracing.patch [new file with mode: 0644]

index 5ab56662ced824856726acd233b2670ec2ec3ecd..77da3ca3b11ed9d0650de551a4b44190c1a0d71f 100644 (file)
@@ -7,4 +7,5 @@ rt2x00-read-5ghz-tx-power-values-from-the-correct-offset.patch
 ath9k-do-not-assign-noise-for-null-caldata.patch
 scsi-zfcp-fix-adapter-re-open-recovery-while-link-to-san-is-down.patch
 scsi-mpt2sas-fix-firmware-failure-with-wrong-task-attribute.patch
+tracing-use-current_uid-for-critical-time-tracing.patch
 sunrpc-pipefs-mount-notification-optimization-for-dying-clients.patch
diff --git a/queue-3.4/tracing-use-current_uid-for-critical-time-tracing.patch b/queue-3.4/tracing-use-current_uid-for-critical-time-tracing.patch
new file mode 100644 (file)
index 0000000..8b32e57
--- /dev/null
@@ -0,0 +1,101 @@
+From f17a5194859a82afe4164e938b92035b86c55794 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+Date: Thu, 30 May 2013 21:10:37 -0400
+Subject: tracing: Use current_uid() for critical time tracing
+
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+
+commit f17a5194859a82afe4164e938b92035b86c55794 upstream.
+
+The irqsoff tracer records the max time that interrupts are disabled.
+There are hooks in the assembly code that calls back into the tracer when
+interrupts are disabled or enabled.
+
+When they are enabled, the tracer checks if the amount of time they
+were disabled is larger than the previous recorded max interrupts off
+time. If it is, it creates a snapshot of the currently running trace
+to store where the last largest interrupts off time was held and how
+it happened.
+
+During testing, this RCU lockdep dump appeared:
+
+[ 1257.829021] ===============================
+[ 1257.829021] [ INFO: suspicious RCU usage. ]
+[ 1257.829021] 3.10.0-rc1-test+ #171 Tainted: G        W
+[ 1257.829021] -------------------------------
+[ 1257.829021] /home/rostedt/work/git/linux-trace.git/include/linux/rcupdate.h:780 rcu_read_lock() used illegally while idle!
+[ 1257.829021]
+[ 1257.829021] other info that might help us debug this:
+[ 1257.829021]
+[ 1257.829021]
+[ 1257.829021] RCU used illegally from idle CPU!
+[ 1257.829021] rcu_scheduler_active = 1, debug_locks = 0
+[ 1257.829021] RCU used illegally from extended quiescent state!
+[ 1257.829021] 2 locks held by trace-cmd/4831:
+[ 1257.829021]  #0:  (max_trace_lock){......}, at: [<ffffffff810e2b77>] stop_critical_timing+0x1a3/0x209
+[ 1257.829021]  #1:  (rcu_read_lock){.+.+..}, at: [<ffffffff810dae5a>] __update_max_tr+0x88/0x1ee
+[ 1257.829021]
+[ 1257.829021] stack backtrace:
+[ 1257.829021] CPU: 3 PID: 4831 Comm: trace-cmd Tainted: G        W    3.10.0-rc1-test+ #171
+[ 1257.829021] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS SDBLI944.86P 05/08/2007
+[ 1257.829021]  0000000000000001 ffff880065f49da8 ffffffff8153dd2b ffff880065f49dd8
+[ 1257.829021]  ffffffff81092a00 ffff88006bd78680 ffff88007add7500 0000000000000003
+[ 1257.829021]  ffff88006bd78680 ffff880065f49e18 ffffffff810daebf ffffffff810dae5a
+[ 1257.829021] Call Trace:
+[ 1257.829021]  [<ffffffff8153dd2b>] dump_stack+0x19/0x1b
+[ 1257.829021]  [<ffffffff81092a00>] lockdep_rcu_suspicious+0x109/0x112
+[ 1257.829021]  [<ffffffff810daebf>] __update_max_tr+0xed/0x1ee
+[ 1257.829021]  [<ffffffff810dae5a>] ? __update_max_tr+0x88/0x1ee
+[ 1257.829021]  [<ffffffff811002b9>] ? user_enter+0xfd/0x107
+[ 1257.829021]  [<ffffffff810dbf85>] update_max_tr_single+0x11d/0x12d
+[ 1257.829021]  [<ffffffff811002b9>] ? user_enter+0xfd/0x107
+[ 1257.829021]  [<ffffffff810e2b15>] stop_critical_timing+0x141/0x209
+[ 1257.829021]  [<ffffffff8109569a>] ? trace_hardirqs_on+0xd/0xf
+[ 1257.829021]  [<ffffffff811002b9>] ? user_enter+0xfd/0x107
+[ 1257.829021]  [<ffffffff810e3057>] time_hardirqs_on+0x2a/0x2f
+[ 1257.829021]  [<ffffffff811002b9>] ? user_enter+0xfd/0x107
+[ 1257.829021]  [<ffffffff8109550c>] trace_hardirqs_on_caller+0x16/0x197
+[ 1257.829021]  [<ffffffff8109569a>] trace_hardirqs_on+0xd/0xf
+[ 1257.829021]  [<ffffffff811002b9>] user_enter+0xfd/0x107
+[ 1257.829021]  [<ffffffff810029b4>] do_notify_resume+0x92/0x97
+[ 1257.829021]  [<ffffffff8154bdca>] int_signal+0x12/0x17
+
+What happened was entering into the user code, the interrupts were enabled
+and a max interrupts off was recorded. The trace buffer was saved along with
+various information about the task: comm, pid, uid, priority, etc.
+
+The uid is recorded with task_uid(tsk). But this is a macro that uses rcu_read_lock()
+to retrieve the data, and this happened to happen where RCU is blind (user_enter).
+
+As only the preempt and irqs off tracers can have this happen, and they both
+only have the tsk == current, if tsk == current, use current_uid() instead of
+task_uid(), as current_uid() does not use RCU as only current can change its uid.
+
+This fixes the RCU suspicious splat.
+
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -687,7 +687,15 @@ __update_max_tr(struct trace_array *tr,
+       memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN);
+       max_data->pid = tsk->pid;
+-      max_data->uid = task_uid(tsk);
++      /*
++       * If tsk == current, then use current_uid(), as that does not use
++       * RCU. The irq tracer can be called out of RCU scope.
++       */
++      if (tsk == current)
++              max_data->uid = current_uid();
++      else
++              max_data->uid = task_uid(tsk);
++
+       max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
+       max_data->policy = tsk->policy;
+       max_data->rt_priority = tsk->rt_priority;