* + lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch added to -mm tree
@ 2016-01-27 0:12 akpm
2016-01-27 1:14 ` Sergey Senozhatsky
0 siblings, 1 reply; 3+ messages in thread
From: akpm @ 2016-01-27 0:12 UTC (permalink / raw)
To: byungchul.park, akinobu.mita, jack, mingo, mm-commits
The patch titled
Subject: lib/spinlock_debug.c: prevent an infinite recursive cycle in spin_dump()
has been added to the -mm tree. Its filename is
lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch
This patch should soon appear at
http://ozlabs.org/~akpm/mmots/broken-out/lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch
and later at
http://ozlabs.org/~akpm/mmotm/broken-out/lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/SubmitChecklist when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: Byungchul Park <byungchul.park@lge.com>
Subject: lib/spinlock_debug.c: prevent an infinite recursive cycle in spin_dump()
There is an infinite recursive cycle when using CONFIG_DEBUG_SPINLOCK, in
spin_dump(). Backtrace prints printk() -> console_trylock() ->
do_raw_spin_lock() -> spin_bug() -> spin_dump() -> printk()...
infinitely.
If the spin_bug() is called from a function like printk() which is trying
to obtain the console lock, we should prevent the debug spinlock code from
calling printk() again in that context.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
kernel/locking/spinlock_debug.c | 11 +++++++++++
kernel/printk/printk.c | 5 +++++
2 files changed, 16 insertions(+)
diff -puN kernel/locking/spinlock_debug.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump kernel/locking/spinlock_debug.c
--- a/kernel/locking/spinlock_debug.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump
+++ a/kernel/locking/spinlock_debug.c
@@ -67,11 +67,22 @@ static void spin_dump(raw_spinlock_t *lo
dump_stack();
}
+extern int is_console_lock(raw_spinlock_t *lock);
+
static void spin_bug(raw_spinlock_t *lock, const char *msg)
{
if (!debug_locks_off())
return;
+ /*
+ * If this function is called from a function like printk()
+ * which is trying to obtain the console lock, then we should
+ * not call printk() any more. Or it will cause an infinite
+ * recursive cycle!
+ */
+ if (unlikely(is_console_lock(lock)))
+ return;
+
spin_dump(lock, msg);
}
diff -puN kernel/printk/printk.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump kernel/printk/printk.c
--- a/kernel/printk/printk.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump
+++ a/kernel/printk/printk.c
@@ -120,6 +120,11 @@ static int __down_trylock_console_sem(un
up(&console_sem);\
} while (0)
+int is_console_lock(raw_spinlock_t *lock)
+{
+ return &console_sem.lock == lock;
+}
+
/*
* This is used for debugging the mess that is the VT code by
* keeping track if we have the console semaphore held. It's
_
Patches currently in -mm which might be from byungchul.park@lge.com are
lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: + lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch added to -mm tree
2016-01-27 0:12 + lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch added to -mm tree akpm
@ 2016-01-27 1:14 ` Sergey Senozhatsky
2016-01-27 6:13 ` Byungchul Park
0 siblings, 1 reply; 3+ messages in thread
From: Sergey Senozhatsky @ 2016-01-27 1:14 UTC (permalink / raw)
To: byungchul.park; +Cc: akpm, akinobu.mita, jack, mingo, mm-commits, linux-kernel
On (01/26/16 16:12), akpm@linux-foundation.org wrote:
[..]
> There is an infinite recursive cycle when using CONFIG_DEBUG_SPINLOCK, in
> spin_dump(). Backtrace prints printk() -> console_trylock() ->
> do_raw_spin_lock() -> spin_bug() -> spin_dump() -> printk()...
> infinitely.
is it even possible to lockup on a semaphore's spin_lock?
int down_trylock(struct semaphore *sem)
{
unsigned long flags;
int count;
raw_spin_lock_irqsave(&sem->lock, flags);
^^^^ here?
count = sem->count - 1;
if (likely(count >= 0))
sem->count = count;
raw_spin_unlock_irqrestore(&sem->lock, flags);
return (count < 0);
}
under what circumstances and why it should be silenced? a memory corruption?
or is it the 'logbuf_lock' spin_lock that was meant to be in the report?
what if we lockup on `logbuf_lock`, it will generate the same call-chain...
> If the spin_bug() is called from a function like printk() which is trying
> to obtain the console lock, we should prevent the debug spinlock code from
> calling printk() again in that context.
even if it was the 'logbuf_lock' spin_lock then still, we take it for quite
short periods of time with IRQs disabled:
in vprintk_emit(), when sprintf text and store it
local_irq_save()
raw_spin_lock()
vscnprintf()
log_store()
raw_spin_unlock()
local_irq_restore()
and in console_unlock() when we read it back
for (;;) {
raw_spin_lock_irqsave(&logbuf_lock, flags);
msg_print_text
raw_spin_unlock(&logbuf_lock)
call_console_drivers()
local_irq_restore
}
so if the CPU that owns the spin_lock somehow managed to keep it forever
(due to a memory corruption... or something has powered off the cpu
core???) -- then _this is_ the problem, not the fact that other CPUs will
not lock the spin_lock anymore.
so I don't think this patch does the right thing, sorry.
-ss
> Signed-off-by: Byungchul Park <byungchul.park@lge.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Akinobu Mita <akinobu.mita@gmail.com>
> Cc: Jan Kara <jack@suse.cz>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
>
> kernel/locking/spinlock_debug.c | 11 +++++++++++
> kernel/printk/printk.c | 5 +++++
> 2 files changed, 16 insertions(+)
>
> diff -puN kernel/locking/spinlock_debug.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump kernel/locking/spinlock_debug.c
> --- a/kernel/locking/spinlock_debug.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump
> +++ a/kernel/locking/spinlock_debug.c
> @@ -67,11 +67,22 @@ static void spin_dump(raw_spinlock_t *lo
> dump_stack();
> }
>
> +extern int is_console_lock(raw_spinlock_t *lock);
> +
> static void spin_bug(raw_spinlock_t *lock, const char *msg)
> {
> if (!debug_locks_off())
> return;
>
> + /*
> + * If this function is called from a function like printk()
> + * which is trying to obtain the console lock, then we should
> + * not call printk() any more. Or it will cause an infinite
> + * recursive cycle!
> + */
> + if (unlikely(is_console_lock(lock)))
> + return;
> +
> spin_dump(lock, msg);
> }
>
> diff -puN kernel/printk/printk.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump kernel/printk/printk.c
> --- a/kernel/printk/printk.c~lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump
> +++ a/kernel/printk/printk.c
> @@ -120,6 +120,11 @@ static int __down_trylock_console_sem(un
> up(&console_sem);\
> } while (0)
>
> +int is_console_lock(raw_spinlock_t *lock)
> +{
> + return &console_sem.lock == lock;
> +}
> +
> /*
> * This is used for debugging the mess that is the VT code by
> * keeping track if we have the console semaphore held. It's
> _
>
> Patches currently in -mm which might be from byungchul.park@lge.com are
>
> lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch
>
> --
> To unsubscribe from this list: send the line "unsubscribe mm-commits" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: + lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch added to -mm tree
2016-01-27 1:14 ` Sergey Senozhatsky
@ 2016-01-27 6:13 ` Byungchul Park
0 siblings, 0 replies; 3+ messages in thread
From: Byungchul Park @ 2016-01-27 6:13 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: akpm, akinobu.mita, jack, mingo, mm-commits, linux-kernel
On Wed, Jan 27, 2016 at 10:14:54AM +0900, Sergey Senozhatsky wrote:
> On (01/26/16 16:12), akpm@linux-foundation.org wrote:
> [..]
> > There is an infinite recursive cycle when using CONFIG_DEBUG_SPINLOCK, in
> > spin_dump(). Backtrace prints printk() -> console_trylock() ->
> > do_raw_spin_lock() -> spin_bug() -> spin_dump() -> printk()...
> > infinitely.
>
> is it even possible to lockup on a semaphore's spin_lock?
>
> int down_trylock(struct semaphore *sem)
> {
> unsigned long flags;
> int count;
>
> raw_spin_lock_irqsave(&sem->lock, flags);
> ^^^^ here?
Yes.
> under what circumstances and why it should be silenced? a memory corruption?
> or is it the 'logbuf_lock' spin_lock that was meant to be in the report?
Backtracing said it's console_sem.lock. But as you said, logbuf_lock can
cause same lockup when trying printk() in printk().
> so if the CPU that owns the spin_lock somehow managed to keep it forever
> (due to a memory corruption... or something has powered off the cpu
> core???) -- then _this is_ the problem, not the fact that other CPUs will
> not lock the spin_lock anymore.
>
> so I don't think this patch does the right thing, sorry.
I agree with you.
thanks,
byungchul
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-01-27 6:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-27 0:12 + lib-spinlock_debugc-prevent-an-infinite-recursive-cycle-in-spin_dump.patch added to -mm tree akpm
2016-01-27 1:14 ` Sergey Senozhatsky
2016-01-27 6:13 ` Byungchul Park
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.