linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Simon Kagstrom <simon.kagstrom@netinsight.net>
To: Ingo Molnar <mingo@elte.hu>, linux-mtd <linux-mtd@lists.infradead.org>
Cc: Artem Bityutskiy <dedekind1@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"Koskinen Aaro \(Nokia-D/Helsinki\)" <aaro.koskinen@nokia.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Woodhouse <dwmw2@infradead.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: [PATCH v9 4/5] core: Add kernel message dumper to call on oopses and panics
Date: Fri, 16 Oct 2009 09:46:01 +0200	[thread overview]
Message-ID: <20091016094601.4e2c2d3e@marrow.netinsight.se> (raw)
In-Reply-To: <20091015154640.GA11408@elte.hu>

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>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
---
ChangeLog:
	* (Arjan van de Ven): Use EXPORT_SYMBOL_GPL
	* (Ingo Molnar): Switch list/spinlock definition order
	* (Ingo Molnar): Set/check ->registered within spinlocked region
	* (Ingo Molnar): Return error from unregister and check that the
	  dumper really is registered
	* (Ingo Molnar): Maximise constness and correct array check
	* (Ingo Molnar): Use _irqsave/_irqrestore also in kmsg_dump
	* (Ingo Molnar): Style fixes
	* (Anders Grafström): Correct kerneldoc names

 include/linux/kmsg_dump.h |   36 ++++++++++++++
 kernel/panic.c            |    3 +
 kernel/printk.c           |  116 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/kmsg_dump.h

diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
new file mode 100644
index 0000000..64296f3
--- /dev/null
+++ b/include/linux/kmsg_dump.h
@@ -0,0 +1,36 @@
+/*
+ * linux/include/kmsg_dump.h
+ *
+ * Copyright (C) 2009 Net Insight AB
+ *
+ * Author: Simon Kagstrom <simon.kagstrom@netinsight.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+#ifndef _LINUX_KMSG_DUMP_H
+#define _LINUX_KMSG_DUMP_H
+
+#include <linux/list.h>
+
+enum kmsg_dump_reason {
+	KMSG_DUMP_OOPS,
+	KMSG_DUMP_PANIC,
+};
+
+struct kmsg_dumper {
+	void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason,
+			const char *s1, unsigned long l1,
+			const char *s2, unsigned long l2);
+	struct list_head list;
+	int registered;
+};
+
+void kmsg_dump(enum kmsg_dump_reason reason);
+
+int kmsg_dump_register(struct kmsg_dumper *dumper);
+
+int kmsg_dump_unregister(struct kmsg_dumper *dumper);
+
+#endif /* _LINUX_DUMP_DEVICE_H */
diff --git a/kernel/panic.c b/kernel/panic.c
index c0b33b8..763296d 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -10,6 +10,7 @@
  */
 #include <linux/debug_locks.h>
 #include <linux/interrupt.h>
+#include <linux/kmsg_dump.h>
 #include <linux/kallsyms.h>
 #include <linux/notifier.h>
 #include <linux/module.h>
@@ -76,6 +77,7 @@ NORET_TYPE void panic(const char * fmt, ...)
 	dump_stack();
 #endif
 
+	kmsg_dump(KMSG_DUMP_PANIC);
 	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
@@ -341,6 +343,7 @@ void oops_exit(void)
 {
 	do_oops_enter_exit();
 	print_oops_end_marker();
+	kmsg_dump(KMSG_DUMP_OOPS);
 }
 
 #ifdef WANT_WARN_ON_SLOWPATH
diff --git a/kernel/printk.c b/kernel/printk.c
index f38b07f..d363306 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -33,6 +33,7 @@
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
 #include <linux/kexec.h>
+#include <linux/kmsg_dump.h>
 
 #include <asm/uaccess.h>
 
@@ -1405,3 +1406,118 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 }
 EXPORT_SYMBOL(printk_timed_ratelimit);
 #endif
+
+static DEFINE_SPINLOCK(dump_list_lock);
+static LIST_HEAD(dump_list);
+
+/**
+ *	kmsg_dump_register - register a kernel log dumper.
+ *	@dump: pointer to the kmsg_dumper 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;
+
+	spin_lock_irqsave(&dump_list_lock, flags);
+
+	/* Don't allow registering multiple times */
+	if (dumper->registered) {
+		spin_unlock_irqrestore(&dump_list_lock, flags);
+
+		return -EBUSY;
+	}
+
+	dumper->registered = 1;
+	list_add(&dumper->list, &dump_list);
+	spin_unlock_irqrestore(&dump_list_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_register);
+
+/**
+ *	kmsg_dump_unregister - unregister a kmsg dumper.
+ *	@dump: pointer to the kmsg_dumper structure
+ *
+ *	Removes a dump device from the system.
+ */
+int kmsg_dump_unregister(struct kmsg_dumper *dumper)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dump_list_lock, flags);
+	if (!dumper->registered) {
+		spin_unlock_irqrestore(&dump_list_lock, flags);
+
+		return -EINVAL;
+	}
+
+	dumper->registered = 0;
+	list_del(&dumper->list);
+	spin_unlock_irqrestore(&dump_list_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
+
+static const char const *kmsg_reasons[] = {
+	[KMSG_DUMP_OOPS]	= "oops",
+	[KMSG_DUMP_PANIC]	= "panic",
+};
+
+static const char *kmsg_to_str(enum kmsg_dump_reason reason)
+{
+	if (reason >= ARRAY_SIZE(kmsg_reasons) || reason < 0)
+		return "unknown";
+
+	return kmsg_reasons[reason];
+}
+
+/**
+ *	kmsg_dump - 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;
+	unsigned long flags;
+
+	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_irqsave(&dump_list_lock, flags)) {
+		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_irqrestore(&dump_list_lock, flags);
+}
-- 
1.6.0.4

  reply	other threads:[~2009-10-16  7: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
2009-10-16  7:46         ` Simon Kagstrom [this message]
2009-10-16  8:09           ` [PATCH v9 " 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=20091016094601.4e2c2d3e@marrow.netinsight.se \
    --to=simon.kagstrom@netinsight.net \
    --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=mingo@elte.hu \
    --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).