From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
To: Petr Mladek <pmladek@suse.com>, Jan Kara <jack@suse.cz>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Tejun Heo <tj@kernel.org>, Calvin Owens <calvinowens@fb.com>,
Thomas Gleixner <tglx@linutronix.de>,
Mel Gorman <mgorman@techsingularity.net>,
Steven Rostedt <rostedt@goodmis.org>,
linux-kernel@vger.kernel.org,
Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Subject: Re: [RFC][PATCHv2 3/7] printk: introduce per-cpu alt_print seq buffer
Date: Sat, 1 Oct 2016 11:24:15 +0900 [thread overview]
Message-ID: <20161001022415.GA527@swordfish> (raw)
In-Reply-To: <20160930151758.8965-4-sergey.senozhatsky@gmail.com>
On (10/01/16 00:17), Sergey Senozhatsky wrote:
[..]
> +void alt_printk_enter(void)
> +{
> + unsigned long flags;
-
> + local_irq_save(flags);
> + if (!(this_cpu_read(alt_printk_ctx) & ALT_PRINTK_CONTEXT_MASK))
> + this_cpu_write(alt_printk_irq_flags, flags);
> + this_cpu_inc(alt_printk_ctx);
> +}
[..]
> +void alt_printk_exit(void)
> +{
> + this_cpu_dec(alt_printk_ctx);
> + if (!(this_cpu_read(alt_printk_ctx) & ALT_PRINTK_CONTEXT_MASK))
> + local_irq_restore(this_cpu_read(alt_printk_irq_flags));
> +}
a few words why did I make it so complex here. it may look that nested
alt_printk_enter()-s are not really possible; but it's not exactly the
case. and the reasons being is that printk exports too many symbols.
basically, the only 'safe' printk variant at the moment is
printk()
vprintk_func()
because it 'respects' current printk context... and that's it.
the reset of them will call vprintk_emit() regardless the context.
this patch set fixes (in 0001) vprintk()
vprintk()
vprintk_func()
but we still have
EXPORT_SYMBOL(vprintk_emit)
EXPORT_SYMBOL(printk_emit)
EXPORT_SYMBOL_GPL(vprintk_default)
any of those called from alt_printk_log_store() will deadlock us.
printk()
vprintk_emit()
alt_printk_enter()
raw_spin_lock(&logbuf_lock)
...
printk() << first recursion
vprintk_alt()
alt_printk_log_store()
vprintk_default()
---> vprintk_emit() << second recursion
raw_spin_lock(&logbuf_lock) << deadlock
...
alt_printk_exit()
our vprintk_alt()->alt_printk_log_store() seems to be *more or less*
safe, for the time being. there are many WARN_ON_* on
vprintk_alt()->alt_printk_log_store()->vsnprintf() path but they all
seem to be calling printk():
- WARN_ON_ONCE() from vsnprintf()
- WARN_ONCE() from vsnprintf()->format_decode()
- WARN_ON vsnprintf()->set_field_width()
- WARN_ON from vsnprintf()->set_precision()
- WARN_ON from vsnprintf()->pointer()->flags_string()
a side note, some of these WARNs are... 'funny'. e.g., to deadlock a
system it's enough to just pass an unsupported flag in format string.
vsnprintf() will
WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt)
but the problem is that we are already in printk():
printk()
raw_spin_lock(&logbuf_lock)
text_len = vscnprintf(text, sizeof(textbuf), fmt, args)
WARN_ONCE(1, "Please remove unsupported ...)
printk()
raw_spin_lock(&logbuf_lock) << deadlock
with alt_printk enabled we are cool now.
[ 175.226161] BUG: recent printk recursion!
[ 175.226170] ------------[ cut here ]------------
[ 175.226173] WARNING: CPU: 3 PID: 361 at lib/vsprintf.c:1900 format_decode+0x22c/0x308
[ 175.226175] Please remove unsupported %{ in format string
[ 175.226182] CPU: 3 PID: 361 Comm: bash
[ 175.226194] Call Trace:
[ 175.226197] [<ffffffff811efbaf>] dump_stack+0x68/0x92
[ 175.226199] [<ffffffff8103d5e7>] __warn+0xb8/0xd3
[ 175.226202] [<ffffffff8103d648>] warn_slowpath_fmt+0x46/0x4e
[ 175.226204] [<ffffffff811f648d>] format_decode+0x22c/0x308
[ 175.226207] [<ffffffff811f7715>] vsnprintf+0x89/0x481
[ 175.226209] [<ffffffff811f7e92>] vscnprintf+0xd/0x26
[ 175.226212] [<ffffffff81080701>] vprintk_emit+0xcc/0x271
[ 175.226214] [<ffffffff81080a08>] vprintk_default+0x18/0x1a
[ 175.226217] [<ffffffff810819b1>] vprintk_func+0x82/0x89
[ 175.226219] [<ffffffff810c82d0>] printk+0x3e/0x46
[..]
[ 175.226244] [<ffffffff814c1d6a>] entry_SYSCALL_64_fastpath+0x18/0xad
[ 175.226249] ---[ end trace ]---
speaking of %p. FORMAT_TYPE_PTR is big and sometimes seem to be platform
dependent. there are tons of things that can go wrong there. for instance:
- vsnprintf()
pointer()
symbol_string()
sprint_backtrace()
__sprint_symbol()
kallsyms_lookup()
get_symbol_pos()
BUG_ON
- vsnprintf()
pointer()
symbol_string()
sprint_backtrace()
__sprint_symbol()
kallsyms_lookup()
module_address_lookup()
__module_address()
BUG_ON
- vsnprintf()
pointer()
symbol_string()
sprint_backtrace()
__sprint_symbol()
kallsyms_lookup()
module_address_lookup()
module_assert_mutex_or_preempt()
WARN_ON_ONCE()
and probably even more.
for example, drivers/base/core.c has its own printk() implementation
and calls vprintk_emit() directly
return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args)
so as a precautions measure I've decided to enable alt_printk_enter()
nesting. but can drop it.
-ss
next prev parent reply other threads:[~2016-10-01 2:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-30 15:17 [RFC][PATCHv2 0/7] printk: use alt_printk to handle printk() recursive calls Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 1/7] printk: use vprintk_func in vprintk() Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 2/7] printk: rename nmi.c and exported api Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 3/7] printk: introduce per-cpu alt_print seq buffer Sergey Senozhatsky
2016-10-01 2:24 ` Sergey Senozhatsky [this message]
2016-10-06 14:56 ` Petr Mladek
2016-10-07 19:40 ` Sergey Senozhatsky
2016-10-10 11:03 ` Petr Mladek
2016-10-06 13:08 ` Petr Mladek
2016-10-07 19:33 ` Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 4/7] printk: make alt_printk available when config printk set Sergey Senozhatsky
2016-10-06 15:23 ` Petr Mladek
2016-10-07 19:08 ` Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 5/7] printk: use alternative printk buffers Sergey Senozhatsky
2016-09-30 15:17 ` [RFC][PATCHv2 6/7] printk: report printk recursion from alt_printk flush Sergey Senozhatsky
2016-10-06 15:41 ` Petr Mladek
2016-10-07 18:59 ` Sergey Senozhatsky
2016-10-10 11:02 ` Petr Mladek
2016-09-30 15:17 ` [RFC][PATCHv2 7/7] printk: remove zap_locks() function Sergey Senozhatsky
2016-10-06 15:55 ` [RFC][PATCHv2 0/7] printk: use alt_printk to handle printk() recursive calls Petr Mladek
2016-10-07 18:56 ` Sergey Senozhatsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161001022415.GA527@swordfish \
--to=sergey.senozhatsky.work@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=calvinowens@fb.com \
--cc=jack@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@techsingularity.net \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky@gmail.com \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox