* [PATCH] tracing: fix circular dead lock
@ 2010-02-02 7:32 Lai Jiangshan
2010-02-02 13:25 ` Steven Rostedt
2010-02-03 5:18 ` [tip:tracing/urgent] tracing: Fix circular dead lock in stack trace tip-bot for Lai Jiangshan
0 siblings, 2 replies; 3+ messages in thread
From: Lai Jiangshan @ 2010-02-02 7:32 UTC (permalink / raw)
To: Li Zefan, Steven Rostedt, Frederic Weisbecker, Ingo Molnar, LKML
When we cat <debugfs>/tracing/stack_trace, we may cause circular lock:
sys_read()
t_start()
arch_spin_lock(&max_stack_lock);
t_show()
seq_printf(), vsnprintf() .... /* they are all trace-able,
when they are traced, max_stack_lock may be required again. */
The following script can trigger this circular dead lock very easy:
#!/bin/bash
echo 1 > /proc/sys/kernel/stack_tracer_enabled
mount -t debugfs xxx /mnt > /dev/null 2>&1
(
# make check_stack() zealous to require max_stack_lock
for ((; ;))
{
echo 1 > /mnt/tracing/stack_max_size
}
) &
for ((; ;))
{
cat /mnt/tracing/stack_trace > /dev/null
}
To fix this bug, we increase the percpu trace_active before
require the lock.
Reported-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 678a512..f4bc9b2 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -157,6 +157,7 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
unsigned long val, flags;
char buf[64];
int ret;
+ int cpu;
if (count >= sizeof(buf))
return -EINVAL;
@@ -171,9 +172,20 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
return ret;
local_irq_save(flags);
+
+ /*
+ * In case we trace inside arch_spin_lock() or after (NMI),
+ * we will cause circular lock, so we also need to increase
+ * the percpu trace_active here.
+ */
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)++;
+
arch_spin_lock(&max_stack_lock);
*ptr = val;
arch_spin_unlock(&max_stack_lock);
+
+ per_cpu(trace_active, cpu)--;
local_irq_restore(flags);
return count;
@@ -206,7 +218,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
static void *t_start(struct seq_file *m, loff_t *pos)
{
+ int cpu;
+
local_irq_disable();
+
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)++;
+
arch_spin_lock(&max_stack_lock);
if (*pos == 0)
@@ -217,7 +235,13 @@ static void *t_start(struct seq_file *m, loff_t *pos)
static void t_stop(struct seq_file *m, void *p)
{
+ int cpu;
+
arch_spin_unlock(&max_stack_lock);
+
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)--;
+
local_irq_enable();
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] tracing: fix circular dead lock
2010-02-02 7:32 [PATCH] tracing: fix circular dead lock Lai Jiangshan
@ 2010-02-02 13:25 ` Steven Rostedt
2010-02-03 5:18 ` [tip:tracing/urgent] tracing: Fix circular dead lock in stack trace tip-bot for Lai Jiangshan
1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2010-02-02 13:25 UTC (permalink / raw)
To: Lai Jiangshan; +Cc: Li Zefan, Frederic Weisbecker, Ingo Molnar, LKML
On Tue, 2010-02-02 at 15:32 +0800, Lai Jiangshan wrote:
> When we cat <debugfs>/tracing/stack_trace, we may cause circular lock:
> sys_read()
> t_start()
> arch_spin_lock(&max_stack_lock);
>
> t_show()
> seq_printf(), vsnprintf() .... /* they are all trace-able,
> when they are traced, max_stack_lock may be required again. */
>
>
> The following script can trigger this circular dead lock very easy:
> #!/bin/bash
>
> echo 1 > /proc/sys/kernel/stack_tracer_enabled
>
> mount -t debugfs xxx /mnt > /dev/null 2>&1
> (
> # make check_stack() zealous to require max_stack_lock
> for ((; ;))
> {
> echo 1 > /mnt/tracing/stack_max_size
> }
> ) &
>
> for ((; ;))
> {
> cat /mnt/tracing/stack_trace > /dev/null
> }
>
>
> To fix this bug, we increase the percpu trace_active before
> require the lock.
>
> Reported-by: Li Zefan <lizf@cn.fujitsu.com>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Thanks Lai! I'll try to get this into 33.
-- Steve
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip:tracing/urgent] tracing: Fix circular dead lock in stack trace
2010-02-02 7:32 [PATCH] tracing: fix circular dead lock Lai Jiangshan
2010-02-02 13:25 ` Steven Rostedt
@ 2010-02-03 5:18 ` tip-bot for Lai Jiangshan
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Lai Jiangshan @ 2010-02-03 5:18 UTC (permalink / raw)
To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, lizf, tglx, laijs
Commit-ID: 4f48f8b7fd18c44f8478174f9925cc3c059c6ce4
Gitweb: http://git.kernel.org/tip/4f48f8b7fd18c44f8478174f9925cc3c059c6ce4
Author: Lai Jiangshan <laijs@cn.fujitsu.com>
AuthorDate: Tue, 2 Feb 2010 15:32:09 +0800
Committer: Steven Rostedt <rostedt@goodmis.org>
CommitDate: Tue, 2 Feb 2010 10:20:18 -0500
tracing: Fix circular dead lock in stack trace
When we cat <debugfs>/tracing/stack_trace, we may cause circular lock:
sys_read()
t_start()
arch_spin_lock(&max_stack_lock);
t_show()
seq_printf(), vsnprintf() .... /* they are all trace-able,
when they are traced, max_stack_lock may be required again. */
The following script can trigger this circular dead lock very easy:
#!/bin/bash
echo 1 > /proc/sys/kernel/stack_tracer_enabled
mount -t debugfs xxx /mnt > /dev/null 2>&1
(
# make check_stack() zealous to require max_stack_lock
for ((; ;))
{
echo 1 > /mnt/tracing/stack_max_size
}
) &
for ((; ;))
{
cat /mnt/tracing/stack_trace > /dev/null
}
To fix this bug, we increase the percpu trace_active before
require the lock.
Reported-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
LKML-Reference: <4B67D4F9.9080905@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_stack.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 678a512..f4bc9b2 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -157,6 +157,7 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
unsigned long val, flags;
char buf[64];
int ret;
+ int cpu;
if (count >= sizeof(buf))
return -EINVAL;
@@ -171,9 +172,20 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
return ret;
local_irq_save(flags);
+
+ /*
+ * In case we trace inside arch_spin_lock() or after (NMI),
+ * we will cause circular lock, so we also need to increase
+ * the percpu trace_active here.
+ */
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)++;
+
arch_spin_lock(&max_stack_lock);
*ptr = val;
arch_spin_unlock(&max_stack_lock);
+
+ per_cpu(trace_active, cpu)--;
local_irq_restore(flags);
return count;
@@ -206,7 +218,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
static void *t_start(struct seq_file *m, loff_t *pos)
{
+ int cpu;
+
local_irq_disable();
+
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)++;
+
arch_spin_lock(&max_stack_lock);
if (*pos == 0)
@@ -217,7 +235,13 @@ static void *t_start(struct seq_file *m, loff_t *pos)
static void t_stop(struct seq_file *m, void *p)
{
+ int cpu;
+
arch_spin_unlock(&max_stack_lock);
+
+ cpu = smp_processor_id();
+ per_cpu(trace_active, cpu)--;
+
local_irq_enable();
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-02-03 5:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-02 7:32 [PATCH] tracing: fix circular dead lock Lai Jiangshan
2010-02-02 13:25 ` Steven Rostedt
2010-02-03 5:18 ` [tip:tracing/urgent] tracing: Fix circular dead lock in stack trace tip-bot for Lai Jiangshan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.