From: Ingo Molnar <mingo@elte.hu>
To: Simon Kagstrom <simon.kagstrom@netinsight.net>
Cc: Artem Bityutskiy <dedekind1@gmail.com>,
David Woodhouse <dwmw2@infradead.org>,
LKML <linux-kernel@vger.kernel.org>,
"Koskinen Aaro \(Nokia-D/Helsinki\)" <aaro.koskinen@nokia.com>,
linux-mtd <linux-mtd@lists.infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Re: [PATCH v8 4/5] core: Add kernel message dumper to call on oopses and panics
Date: Thu, 15 Oct 2009 17:46:40 +0200 [thread overview]
Message-ID: <20091015154640.GA11408@elte.hu> (raw)
In-Reply-To: <20091015161052.0752208e@marrow.netinsight.se>
* Simon Kagstrom <simon.kagstrom@netinsight.net> wrote:
> The core functionality is implemented as per Linus suggestion from
>
> http://lists.infradead.org/pipermail/linux-mtd/2009-October/027620.html
>
> (with the kmsg_dump implementation by Linus). A struct kmsg_dumper has
> been added which contains a callback to dump the kernel log buffers on
> crashes. The kmsg_dump function gets called from oops_exit() and panic()
> and invokes this callbacks with the crash reason.
>
> Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
> Reviewed-by: Anders Grafstrom <anders.grafstrom@netinsight.net>
The general structure looks very nice now! Assuming my review comments
below are addressed all patches are:
Reviewed-by: Ingo Molnar <mingo@elte.hu>
> diff --git a/kernel/printk.c b/kernel/printk.c
> index f38b07f..960406a 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -33,6 +33,8 @@
> #include <linux/bootmem.h>
> #include <linux/syscalls.h>
> #include <linux/kexec.h>
> +#include <linux/kmsg_dump.h>
> +#include <linux/spinlock.h>
( Small nit: in theory the spinlock.h include should not be needed as
printk.c already uses spinlocks and gets the types via mutex.h. )
>
> #include <asm/uaccess.h>
>
> @@ -1405,3 +1407,105 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
> }
> EXPORT_SYMBOL(printk_timed_ratelimit);
> #endif
> +
> +static LIST_HEAD(dump_list);
> +static DEFINE_SPINLOCK(dump_list_lock);
Please switch it around to be:
static DEFINE_SPINLOCK(dump_list_lock);
static LIST_HEAD(dump_list);
as the lock will be cacheline aligned on SMP, so the list head can come
after it 'for free'.
If it's the other way around we'll use 8/16 more .data bytes on average.
> +
> +/**
> + * kmsg_dump_register - register a kernel log dumper.
> + * @dump: pointer to the kmsg_dumper structure
> + * @priv: private data for the structure
> + *
> + * Adds a kernel log dumper to the system. The dump callback in the
> + * structure will be called when the kernel oopses or panics and must be
> + * set. Returns zero on success and -EINVAL or -EBUSY otherwise.
> + */
> +int kmsg_dump_register(struct kmsg_dumper *dumper)
> +{
> + unsigned long flags;
> +
> + /* The dump callback needs to be set */
> + if (!dumper->dump)
> + return -EINVAL;
> +
> + /* Don't allow registering multiple times */
> + if (dumper->registered)
> + return -EBUSY;
> +
> + dumper->registered = 1;
> +
> + spin_lock_irqsave(&dump_list_lock, flags);
> + list_add(&dumper->list, &dump_list);
> + spin_unlock_irqrestore(&dump_list_lock, flags);
> + return 0;
> +}
> +EXPORT_SYMBOL(kmsg_dump_register);
There's a race here: dumper->registered should be set to 1 inside the
spinlock - to make the register/unregister API SMP safe.
It probably doesnt matter much in practice right now (as the dumper will
be registered during bootup and unregistered during shutdown), but still
- it could matter to modular loading of multiple dumpers at once, in the
future.
Also, the check for ->registered should be done inside too.
Plus a style nit: please put a newline before the 'return 0' - it looks
more symmetric and separates the return from other code flow.
> +
> +/**
> + * kmsg_dump_unregister - unregister a kmsg dumper.
> + * @dump: pointer to the kmsg_dumper structure
> + *
> + * Removes a dump device from the system.
> + */
> +void kmsg_dump_unregister(struct kmsg_dumper *dumper)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(&dump_list_lock, flags);
> + list_del(&dumper->list);
> + spin_unlock_irqrestore(&dump_list_lock, flags);
> +}
> +EXPORT_SYMBOL(kmsg_dump_unregister);
I'd suggest for this API to use an error return as well, and to do it
safely - i.e. any combination of these APIs should result in a safe
result.
Right now a call sequence kmsg_dump_register() + kmsg_dump_unregister()
+ kmsg_dump_register() will corrupt memory.
> +
> +static const char *kmsg_reasons[] = {
> + [KMSG_DUMP_OOPS] = "oops",
> + [KMSG_DUMP_PANIC] = "panic",
> +};
Should be 'const char const' for max constness.
> +static const char *kmsg_to_str(enum kmsg_dump_reason reason)
> +{
> + if (reason > ARRAY_SIZE(kmsg_reasons) || reason < 0)
> + return "unknown";
That should be ">=" i guess, for the check to be correct.
> +
> + return kmsg_reasons[reason];
> +}
> +
> +/**
> + * dump_kmsg - dump kernel log to kernel message dumpers.
> + * @reason: the reason (oops, panic etc) for dumping
> + *
> + * Iterate through each of the dump devices and call the oops/panic
> + * callbacks with the log buffer.
> + */
> +void kmsg_dump(enum kmsg_dump_reason reason)
> +{
> + unsigned long len = ACCESS_ONCE(log_end);
> + struct kmsg_dumper *dumper;
> + const char *s1, *s2;
> + unsigned long l1, l2;
> +
> + s1 = "";
> + l1 = 0;
> + s2 = log_buf;
> + l2 = len;
> +
> + /* Have we rotated around the circular buffer? */
> + if (len > log_buf_len) {
> + unsigned long pos = len & LOG_BUF_MASK;
> +
> + s1 = log_buf + pos;
> + l1 = log_buf_len - pos;
> +
> + s2 = log_buf;
> + l2 = pos;
> + }
> +
> + if (!spin_trylock(&dump_list_lock)) {
> + printk(KERN_ERR "dump_kmsg: dump list lock is held during %s, skipping dump\n",
> + kmsg_to_str(reason));
> + return;
> + }
> + list_for_each_entry(dumper, &dump_list, list)
> + dumper->dump(dumper, reason, s1, l1, s2, l2);
> + spin_unlock(&dump_list_lock);
> +}
( Might make sense to use _irqsave()/_irqrestore() variants here - so
that if an IRQ comes in and panics too we dont recurse. The trylock
protects us above, but we are already non-preempt here - going irqsafe
is even better i guess. )
Ingo
next prev parent reply other threads:[~2009-10-15 15:46 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-15 7:40 [PATCH v7 0/5]: mtdoops: fixes and improvements Simon Kagstrom
2009-10-15 7:47 ` [PATCH v7 1/5]: mtdoops: avoid erasing already empty areas Simon Kagstrom
2009-10-23 3:57 ` Artem Bityutskiy
2009-10-15 7:47 ` [PATCH v7 2/5]: mtdoops: Keep track of used/unused mtdoops pages in an array Simon Kagstrom
2009-10-23 4:08 ` Artem Bityutskiy
2009-10-15 7:47 ` [PATCH v7 3/5]: mtdoops: Make page (record) size configurable Simon Kagstrom
2009-10-23 4:13 ` Artem Bityutskiy
2009-10-23 6:58 ` Simon Kagstrom
2009-10-15 7:48 ` [PATCH v7 4/5]: core: Add kernel message dumper to call on oopses and panics Simon Kagstrom
2009-10-15 9:31 ` Ingo Molnar
2009-10-15 14:10 ` [PATCH v8 4/5] " Simon Kagstrom
2009-10-15 15:46 ` Ingo Molnar [this message]
2009-10-16 7:46 ` [PATCH v9 " Simon Kagstrom
2009-10-16 8:09 ` Ingo Molnar
2009-10-16 8:24 ` Artem Bityutskiy
2009-10-16 9:25 ` [PATCH v10 " Simon Kagstrom
2009-10-16 10:10 ` Ingo Molnar
2009-10-16 11:00 ` Artem Bityutskiy
2009-10-16 12:57 ` Ingo Molnar
2009-10-16 12:09 ` [PATCH v11 " Simon Kagstrom
2009-10-19 11:48 ` Artem Bityutskiy
2009-10-19 12:50 ` Ingo Molnar
2009-10-21 23:33 ` Linus Torvalds
2009-10-22 6:25 ` Simon Kagstrom
2009-10-22 6:36 ` Artem Bityutskiy
2009-10-22 6:42 ` Simon Kagstrom
2009-10-22 8:52 ` Artem Bityutskiy
2009-10-22 8:58 ` Simon Kagstrom
2009-10-23 7:22 ` Ingo Molnar
2009-10-23 15:53 ` Shargorodsky Atal (EXT-Teleca/Helsinki)
2009-10-24 17:05 ` Artem Bityutskiy
2009-10-26 10:40 ` Shargorodsky Atal (EXT-Teleca/Helsinki)
2009-10-26 7:41 ` Simon Kagstrom
2009-10-26 10:36 ` Shargorodsky Atal (EXT-Teleca/Helsinki)
2009-10-26 11:53 ` Simon Kagstrom
2009-10-26 15:13 ` Shargorodsky Atal (EXT-Teleca/Helsinki)
2009-10-26 15:37 ` Simon Kagstrom
2009-10-16 11:25 ` [PATCH v10 " Aaro Koskinen
2009-10-15 7:48 ` [PATCH v7 5/5]: mtdoops: refactor as a kmsg_dumper Simon Kagstrom
2009-10-15 14:10 ` [PATCH v8 " Simon Kagstrom
2009-10-16 7:46 ` [PATCH v9 " Simon Kagstrom
2009-10-23 4:32 ` [PATCH v7 " Artem Bityutskiy
2009-10-23 6:34 ` Simon Kagstrom
2010-01-06 14:33 ` David Woodhouse
2010-01-07 6:47 ` Simon Kagstrom
2009-10-29 12:35 ` [PATCH v12 0/4]: mtdoops: fixes and improvements Simon Kagstrom
2009-10-29 12:41 ` [PATCH v12 1/4]: mtdoops: Keep track of used/unused mtdoops pages in an array Simon Kagstrom
2009-10-29 15:24 ` Artem Bityutskiy
2009-10-29 12:41 ` [PATCH v12 2/4]: mtdoops: Add a maximum MTD partition size Simon Kagstrom
2009-10-29 15:27 ` Artem Bityutskiy
2009-11-03 6:23 ` Artem Bityutskiy
2009-10-29 12:41 ` [PATCH v12 3/4]: mtdoops: Make page (record) size configurable Simon Kagstrom
2009-11-03 6:23 ` Artem Bityutskiy
2009-11-03 7:27 ` Simon Kagstrom
2009-11-03 7:45 ` Artem Bityutskiy
2009-10-29 12:41 ` [PATCH v12 4/4]: mtdoops: refactor as a kmsg_dumper Simon Kagstrom
2009-11-03 7:29 ` Artem Bityutskiy
2009-11-03 13:19 ` [PATCH v13 " Simon Kagstrom
2009-11-10 9:55 ` Simon Kagstrom
2009-11-10 11:53 ` Artem Bityutskiy
2009-11-10 11:58 ` Simon Kagstrom
2009-11-10 16:04 ` Artem Bityutskiy
2009-11-10 16:11 ` Artem Bityutskiy
2009-11-11 9:46 ` Simon Kagstrom
2009-11-11 10:29 ` Artem Bityutskiy
2009-11-11 11:27 ` Simon Kagstrom
2009-11-11 11:34 ` Artem Bityutskiy
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=20091015154640.GA11408@elte.hu \
--to=mingo@elte.hu \
--cc=aaro.koskinen@nokia.com \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=dedekind1@gmail.com \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=simon.kagstrom@netinsight.net \
--cc=torvalds@linux-foundation.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;
as well as URLs for NNTP newsgroup(s).