aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-05-26 09:20:19 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-13 19:59:27 -0400
commitf29e5956aebafe63f81e80f972c44c4a666e5c7f (patch)
tree16b1c8c095f8a1d0d12bd2e6cb66e29ab4c1e516 /fs/pstore
parent89a86a2da30a6a90dda719874092905cd762b7ef (diff)
pstore: Add console log messages support
Pstore doesn't support logging kernel messages in run-time, it only dumps dmesg when kernel oopses/panics. This makes pstore useless for debugging hangs caused by HW issues or improper use of HW (e.g. weird device inserted -> driver tried to write a reserved bits -> SoC hanged. In that case we don't get any messages in the pstore. Therefore, let's add a runtime logging support: PSTORE_TYPE_CONSOLE. Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org> Acked-by: Kees Cook <keescook@chromium.org> Acked-by: Colin Cross <ccross@android.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore')
-rw-r--r--fs/pstore/Kconfig7
-rw-r--r--fs/pstore/inode.c3
-rw-r--r--fs/pstore/platform.c37
3 files changed, 47 insertions, 0 deletions
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 23ade2680a4a..d044de6ee308 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -12,6 +12,13 @@ config PSTORE
12 If you don't have a platform persistent store driver, 12 If you don't have a platform persistent store driver,
13 say N. 13 say N.
14 14
15config PSTORE_CONSOLE
16 bool "Log kernel console messages"
17 depends on PSTORE
18 help
19 When the option is enabled, pstore will log all kernel
20 messages, even if no oops or panic happened.
21
15config PSTORE_RAM 22config PSTORE_RAM
16 tristate "Log panic/oops to a RAM buffer" 23 tristate "Log panic/oops to a RAM buffer"
17 depends on PSTORE 24 depends on PSTORE
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 11a2aa2a56c4..45bff5441b04 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -212,6 +212,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
212 case PSTORE_TYPE_DMESG: 212 case PSTORE_TYPE_DMESG:
213 sprintf(name, "dmesg-%s-%lld", psname, id); 213 sprintf(name, "dmesg-%s-%lld", psname, id);
214 break; 214 break;
215 case PSTORE_TYPE_CONSOLE:
216 sprintf(name, "console-%s", psname);
217 break;
215 case PSTORE_TYPE_MCE: 218 case PSTORE_TYPE_MCE:
216 sprintf(name, "mce-%s-%lld", psname, id); 219 sprintf(name, "mce-%s-%lld", psname, id);
217 break; 220 break;
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 82c585f715e3..61461ed9b6c8 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Persistent Storage - platform driver interface parts. 2 * Persistent Storage - platform driver interface parts.
3 * 3 *
4 * Copyright (C) 2007-2008 Google, Inc.
4 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com> 5 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -22,6 +23,7 @@
22#include <linux/errno.h> 23#include <linux/errno.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/kmsg_dump.h> 25#include <linux/kmsg_dump.h>
26#include <linux/console.h>
25#include <linux/module.h> 27#include <linux/module.h>
26#include <linux/pstore.h> 28#include <linux/pstore.h>
27#include <linux/string.h> 29#include <linux/string.h>
@@ -156,6 +158,40 @@ static struct kmsg_dumper pstore_dumper = {
156 .dump = pstore_dump, 158 .dump = pstore_dump,
157}; 159};
158 160
161#ifdef CONFIG_PSTORE_CONSOLE
162static void pstore_console_write(struct console *con, const char *s, unsigned c)
163{
164 const char *e = s + c;
165
166 while (s < e) {
167 unsigned long flags;
168
169 if (c > psinfo->bufsize)
170 c = psinfo->bufsize;
171 spin_lock_irqsave(&psinfo->buf_lock, flags);
172 memcpy(psinfo->buf, s, c);
173 psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
174 spin_unlock_irqrestore(&psinfo->buf_lock, flags);
175 s += c;
176 c = e - s;
177 }
178}
179
180static struct console pstore_console = {
181 .name = "pstore",
182 .write = pstore_console_write,
183 .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
184 .index = -1,
185};
186
187static void pstore_register_console(void)
188{
189 register_console(&pstore_console);
190}
191#else
192static void pstore_register_console(void) {}
193#endif
194
159/* 195/*
160 * platform specific persistent storage driver registers with 196 * platform specific persistent storage driver registers with
161 * us here. If pstore is already mounted, call the platform 197 * us here. If pstore is already mounted, call the platform
@@ -193,6 +229,7 @@ int pstore_register(struct pstore_info *psi)
193 pstore_get_records(0); 229 pstore_get_records(0);
194 230
195 kmsg_dump_register(&pstore_dumper); 231 kmsg_dump_register(&pstore_dumper);
232 pstore_register_console();
196 233
197 pstore_timer.expires = jiffies + PSTORE_INTERVAL; 234 pstore_timer.expires = jiffies + PSTORE_INTERVAL;
198 add_timer(&pstore_timer); 235 add_timer(&pstore_timer);