platform.c 7.3 KB
Newer Older
1 2 3
/*
 * Persistent Storage - platform driver interface parts.
 *
4
 * Copyright (C) 2007-2008 Google, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kmsg_dump.h>
26
#include <linux/console.h>
27 28 29
#include <linux/module.h>
#include <linux/pstore.h>
#include <linux/string.h>
30
#include <linux/timer.h>
31 32
#include <linux/slab.h>
#include <linux/uaccess.h>
33
#include <linux/hardirq.h>
34
#include <linux/jiffies.h>
35
#include <linux/workqueue.h>
36 37 38

#include "internal.h"

39 40 41 42 43
/*
 * We defer making "oops" entries appear in pstore - see
 * whether the system is actually still running well enough
 * to let someone see the entry
 */
44 45 46 47
static int pstore_update_ms = 60000;
module_param_named(update_ms, pstore_update_ms, int, 0600);
MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content "
		 "(default is 60000; -1 means runtime updates are disabled)");
48 49 50 51 52 53 54 55 56

static int pstore_new_entry;

static void pstore_timefunc(unsigned long);
static DEFINE_TIMER(pstore_timer, pstore_timefunc, 0, 0);

static void pstore_dowork(struct work_struct *);
static DECLARE_WORK(pstore_work, pstore_dowork);

57 58 59 60 61 62 63
/*
 * pstore_lock just protects "psinfo" during
 * calls to pstore_register()
 */
static DEFINE_SPINLOCK(pstore_lock);
static struct pstore_info *psinfo;

64 65
static char *backend;

66
/* How much of the console log to snapshot */
67 68
static unsigned long kmsg_bytes = 10240;

69
void pstore_set_kmsg_bytes(int bytes)
70
{
71
	kmsg_bytes = bytes;
72 73 74 75 76
}

/* Tag each group of saved records with a sequence number */
static int	oopscount;

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
static const char *get_reason_str(enum kmsg_dump_reason reason)
{
	switch (reason) {
	case KMSG_DUMP_PANIC:
		return "Panic";
	case KMSG_DUMP_OOPS:
		return "Oops";
	case KMSG_DUMP_EMERG:
		return "Emergency";
	case KMSG_DUMP_RESTART:
		return "Restart";
	case KMSG_DUMP_HALT:
		return "Halt";
	case KMSG_DUMP_POWEROFF:
		return "Poweroff";
	default:
		return "Unknown";
	}
}
T
Tony Luck 已提交
96

97 98 99 100 101 102 103 104 105 106 107 108 109
/*
 * callback from kmsg_dump. (s2,l2) has the most recently
 * written bytes, older bytes are in (s1,l1). Save as much
 * as we can from the end of the buffer.
 */
static void pstore_dump(struct kmsg_dumper *dumper,
	    enum kmsg_dump_reason reason,
	    const char *s1, unsigned long l1,
	    const char *s2, unsigned long l2)
{
	unsigned long	s1_start, s2_start;
	unsigned long	l1_cpy, l2_cpy;
	unsigned long	size, total = 0;
110 111
	char		*dst;
	const char	*why;
112
	u64		id;
113
	int		hsize, ret;
M
Matthew Garrett 已提交
114
	unsigned int	part = 1;
115 116
	unsigned long	flags = 0;
	int		is_locked = 0;
117

118
	why = get_reason_str(reason);
T
Tony Luck 已提交
119

120 121 122 123 124 125
	if (in_nmi()) {
		is_locked = spin_trylock(&psinfo->buf_lock);
		if (!is_locked)
			pr_err("pstore dump routine blocked in NMI, may corrupt error record\n");
	} else
		spin_lock_irqsave(&psinfo->buf_lock, flags);
126 127 128
	oopscount++;
	while (total < kmsg_bytes) {
		dst = psinfo->buf;
129
		hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
		size = psinfo->bufsize - hsize;
		dst += hsize;

		l2_cpy = min(l2, size);
		l1_cpy = min(l1, size - l2_cpy);

		if (l1_cpy + l2_cpy == 0)
			break;

		s2_start = l2 - l2_cpy;
		s1_start = l1 - l1_cpy;

		memcpy(dst, s1 + s1_start, l1_cpy);
		memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);

145
		ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part,
146
				   hsize + l1_cpy + l2_cpy, psinfo);
147
		if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
148
			pstore_new_entry = 1;
149 150 151
		l1 -= l1_cpy;
		l2 -= l2_cpy;
		total += l1_cpy + l2_cpy;
152
		part++;
153
	}
154 155 156 157 158
	if (in_nmi()) {
		if (is_locked)
			spin_unlock(&psinfo->buf_lock);
	} else
		spin_unlock_irqrestore(&psinfo->buf_lock, flags);
159 160 161 162 163 164
}

static struct kmsg_dumper pstore_dumper = {
	.dump = pstore_dump,
};

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#ifdef CONFIG_PSTORE_CONSOLE
static void pstore_console_write(struct console *con, const char *s, unsigned c)
{
	const char *e = s + c;

	while (s < e) {
		unsigned long flags;

		if (c > psinfo->bufsize)
			c = psinfo->bufsize;
		spin_lock_irqsave(&psinfo->buf_lock, flags);
		memcpy(psinfo->buf, s, c);
		psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
		spin_unlock_irqrestore(&psinfo->buf_lock, flags);
		s += c;
		c = e - s;
	}
}

static struct console pstore_console = {
	.name	= "pstore",
	.write	= pstore_console_write,
	.flags	= CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
	.index	= -1,
};

static void pstore_register_console(void)
{
	register_console(&pstore_console);
}
#else
static void pstore_register_console(void) {}
#endif

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
/*
 * platform specific persistent storage driver registers with
 * us here. If pstore is already mounted, call the platform
 * read function right away to populate the file system. If not
 * then the pstore mount code will call us later to fill out
 * the file system.
 *
 * Register with kmsg_dump to save last part of console log on panic.
 */
int pstore_register(struct pstore_info *psi)
{
	struct module *owner = psi->owner;

	spin_lock(&pstore_lock);
	if (psinfo) {
		spin_unlock(&pstore_lock);
		return -EBUSY;
	}
217 218 219 220 221 222

	if (backend && strcmp(backend, psi->name)) {
		spin_unlock(&pstore_lock);
		return -EINVAL;
	}

223
	psinfo = psi;
224
	mutex_init(&psinfo->read_mutex);
225 226 227 228 229 230 231 232
	spin_unlock(&pstore_lock);

	if (owner && !try_module_get(owner)) {
		psinfo = NULL;
		return -EINVAL;
	}

	if (pstore_is_mounted())
233
		pstore_get_records(0);
234 235

	kmsg_dump_register(&pstore_dumper);
236
	pstore_register_console();
237

238 239 240 241 242
	if (pstore_update_ms >= 0) {
		pstore_timer.expires = jiffies +
			msecs_to_jiffies(pstore_update_ms);
		add_timer(&pstore_timer);
	}
243

244 245 246 247 248
	return 0;
}
EXPORT_SYMBOL_GPL(pstore_register);

/*
249 250 251 252
 * Read all the records from the persistent store. Create
 * files in our filesystem.  Don't warn about -EEXIST errors
 * when we are re-scanning the backing store looking to add new
 * error records.
253
 */
254
void pstore_get_records(int quiet)
255 256
{
	struct pstore_info *psi = psinfo;
257
	char			*buf = NULL;
258
	ssize_t			size;
259 260 261
	u64			id;
	enum pstore_type_id	type;
	struct timespec		time;
262
	int			failed = 0, rc;
263 264 265 266

	if (!psi)
		return;

267
	mutex_lock(&psi->read_mutex);
268
	if (psi->open && psi->open(psi))
269 270
		goto out;

271 272
	while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) {
		rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size,
273
				  time, psi);
274 275
		kfree(buf);
		buf = NULL;
276
		if (rc && (rc != -EEXIST || !quiet))
277 278
			failed++;
	}
279 280
	if (psi->close)
		psi->close(psi);
281
out:
282
	mutex_unlock(&psi->read_mutex);
283 284 285 286 287 288

	if (failed)
		printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
		       failed, psi->name);
}

289 290 291 292 293 294 295 296 297 298 299 300
static void pstore_dowork(struct work_struct *work)
{
	pstore_get_records(1);
}

static void pstore_timefunc(unsigned long dummy)
{
	if (pstore_new_entry) {
		pstore_new_entry = 0;
		schedule_work(&pstore_work);
	}

301
	mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms));
302 303
}

304 305
module_param(backend, charp, 0444);
MODULE_PARM_DESC(backend, "Pstore backend to use");