linux/fs/pstore/platform.c
<<
>>
Prefs
   1/*
   2 * Persistent Storage - platform driver interface parts.
   3 *
   4 * Copyright (C) 2007-2008 Google, Inc.
   5 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License version 2 as
   9 *  published by the Free Software Foundation.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20
  21#include <linux/atomic.h>
  22#include <linux/types.h>
  23#include <linux/errno.h>
  24#include <linux/init.h>
  25#include <linux/kmsg_dump.h>
  26#include <linux/console.h>
  27#include <linux/module.h>
  28#include <linux/pstore.h>
  29#include <linux/string.h>
  30#include <linux/timer.h>
  31#include <linux/slab.h>
  32#include <linux/uaccess.h>
  33#include <linux/hardirq.h>
  34#include <linux/jiffies.h>
  35#include <linux/workqueue.h>
  36
  37#include "internal.h"
  38
  39/*
  40 * We defer making "oops" entries appear in pstore - see
  41 * whether the system is actually still running well enough
  42 * to let someone see the entry
  43 */
  44static int pstore_update_ms = -1;
  45module_param_named(update_ms, pstore_update_ms, int, 0600);
  46MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content "
  47                 "(default is -1, which means runtime updates are disabled; "
  48                 "enabling this option is not safe, it may lead to further "
  49                 "corruption on Oopses)");
  50
  51static int pstore_new_entry;
  52
  53static void pstore_timefunc(unsigned long);
  54static DEFINE_TIMER(pstore_timer, pstore_timefunc, 0, 0);
  55
  56static void pstore_dowork(struct work_struct *);
  57static DECLARE_WORK(pstore_work, pstore_dowork);
  58
  59/*
  60 * pstore_lock just protects "psinfo" during
  61 * calls to pstore_register()
  62 */
  63static DEFINE_SPINLOCK(pstore_lock);
  64struct pstore_info *psinfo;
  65
  66static char *backend;
  67
  68/* How much of the console log to snapshot */
  69static unsigned long kmsg_bytes = 10240;
  70
  71void pstore_set_kmsg_bytes(int bytes)
  72{
  73        kmsg_bytes = bytes;
  74}
  75
  76/* Tag each group of saved records with a sequence number */
  77static int      oopscount;
  78
  79static const char *get_reason_str(enum kmsg_dump_reason reason)
  80{
  81        switch (reason) {
  82        case KMSG_DUMP_PANIC:
  83                return "Panic";
  84        case KMSG_DUMP_OOPS:
  85                return "Oops";
  86        case KMSG_DUMP_EMERG:
  87                return "Emergency";
  88        case KMSG_DUMP_RESTART:
  89                return "Restart";
  90        case KMSG_DUMP_HALT:
  91                return "Halt";
  92        case KMSG_DUMP_POWEROFF:
  93                return "Poweroff";
  94        default:
  95                return "Unknown";
  96        }
  97}
  98
  99bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
 100{
 101        /*
 102         * In case of NMI path, pstore shouldn't be blocked
 103         * regardless of reason.
 104         */
 105        if (in_nmi())
 106                return true;
 107
 108        switch (reason) {
 109        /* In panic case, other cpus are stopped by smp_send_stop(). */
 110        case KMSG_DUMP_PANIC:
 111        /* Emergency restart shouldn't be blocked by spin lock. */
 112        case KMSG_DUMP_EMERG:
 113                return true;
 114        default:
 115                return false;
 116        }
 117}
 118EXPORT_SYMBOL_GPL(pstore_cannot_block_path);
 119
 120/*
 121 * callback from kmsg_dump. (s2,l2) has the most recently
 122 * written bytes, older bytes are in (s1,l1). Save as much
 123 * as we can from the end of the buffer.
 124 */
 125static void pstore_dump(struct kmsg_dumper *dumper,
 126                        enum kmsg_dump_reason reason)
 127{
 128        unsigned long   total = 0;
 129        const char      *why;
 130        u64             id;
 131        unsigned int    part = 1;
 132        unsigned long   flags = 0;
 133        int             is_locked = 0;
 134        int             ret;
 135
 136        why = get_reason_str(reason);
 137
 138        if (pstore_cannot_block_path(reason)) {
 139                is_locked = spin_trylock_irqsave(&psinfo->buf_lock, flags);
 140                if (!is_locked) {
 141                        pr_err("pstore dump routine blocked in %s path, may corrupt error record\n"
 142                                       , in_nmi() ? "NMI" : why);
 143                }
 144        } else
 145                spin_lock_irqsave(&psinfo->buf_lock, flags);
 146        oopscount++;
 147        while (total < kmsg_bytes) {
 148                char *dst;
 149                unsigned long size;
 150                int hsize;
 151                size_t len;
 152                bool compressed = false;
 153
 154                dst = psinfo->buf;
 155                hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
 156                size = psinfo->bufsize - hsize;
 157                dst += hsize;
 158
 159                if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len))
 160                        break;
 161
 162                ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part,
 163                                    oopscount, compressed, hsize + len, psinfo);
 164                if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
 165                        pstore_new_entry = 1;
 166
 167                total += hsize + len;
 168                part++;
 169        }
 170        if (pstore_cannot_block_path(reason)) {
 171                if (is_locked)
 172                        spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 173        } else
 174                spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 175}
 176
 177static struct kmsg_dumper pstore_dumper = {
 178        .dump = pstore_dump,
 179};
 180
 181#ifdef CONFIG_PSTORE_CONSOLE
 182static void pstore_console_write(struct console *con, const char *s, unsigned c)
 183{
 184        const char *e = s + c;
 185
 186        while (s < e) {
 187                unsigned long flags;
 188                u64 id;
 189
 190                if (c > psinfo->bufsize)
 191                        c = psinfo->bufsize;
 192
 193                if (oops_in_progress) {
 194                        if (!spin_trylock_irqsave(&psinfo->buf_lock, flags))
 195                                break;
 196                } else {
 197                        spin_lock_irqsave(&psinfo->buf_lock, flags);
 198                }
 199                memcpy(psinfo->buf, s, c);
 200                psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, 0, c, psinfo);
 201                spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 202                s += c;
 203                c = e - s;
 204        }
 205}
 206
 207static struct console pstore_console = {
 208        .name   = "pstore",
 209        .write  = pstore_console_write,
 210        .flags  = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
 211        .index  = -1,
 212};
 213
 214static void pstore_register_console(void)
 215{
 216        register_console(&pstore_console);
 217}
 218#else
 219static void pstore_register_console(void) {}
 220#endif
 221
 222static int pstore_write_compat(enum pstore_type_id type,
 223                               enum kmsg_dump_reason reason,
 224                               u64 *id, unsigned int part, int count,
 225                               bool compressed, size_t size,
 226                               struct pstore_info *psi)
 227{
 228        return psi->write_buf(type, reason, id, part, psinfo->buf, compressed,
 229                             size, psi);
 230}
 231
 232/*
 233 * platform specific persistent storage driver registers with
 234 * us here. If pstore is already mounted, call the platform
 235 * read function right away to populate the file system. If not
 236 * then the pstore mount code will call us later to fill out
 237 * the file system.
 238 *
 239 * Register with kmsg_dump to save last part of console log on panic.
 240 */
 241int pstore_register(struct pstore_info *psi)
 242{
 243        struct module *owner = psi->owner;
 244
 245        if (backend && strcmp(backend, psi->name))
 246                return -EPERM;
 247
 248        spin_lock(&pstore_lock);
 249        if (psinfo) {
 250                spin_unlock(&pstore_lock);
 251                return -EBUSY;
 252        }
 253
 254        if (!psi->write)
 255                psi->write = pstore_write_compat;
 256        psinfo = psi;
 257        mutex_init(&psinfo->read_mutex);
 258        spin_unlock(&pstore_lock);
 259
 260        if (owner && !try_module_get(owner)) {
 261                psinfo = NULL;
 262                return -EINVAL;
 263        }
 264
 265        if (pstore_is_mounted())
 266                pstore_get_records(0);
 267
 268        kmsg_dump_register(&pstore_dumper);
 269        pstore_register_console();
 270        pstore_register_ftrace();
 271
 272        if (pstore_update_ms >= 0) {
 273                pstore_timer.expires = jiffies +
 274                        msecs_to_jiffies(pstore_update_ms);
 275                add_timer(&pstore_timer);
 276        }
 277
 278        pr_info("pstore: Registered %s as persistent store backend\n",
 279                psi->name);
 280
 281        return 0;
 282}
 283EXPORT_SYMBOL_GPL(pstore_register);
 284
 285/*
 286 * Read all the records from the persistent store. Create
 287 * files in our filesystem.  Don't warn about -EEXIST errors
 288 * when we are re-scanning the backing store looking to add new
 289 * error records.
 290 */
 291void pstore_get_records(int quiet)
 292{
 293        struct pstore_info *psi = psinfo;
 294        char                    *buf = NULL;
 295        ssize_t                 size;
 296        u64                     id;
 297        int                     count;
 298        enum pstore_type_id     type;
 299        struct timespec         time;
 300        int                     failed = 0, rc;
 301        bool                    compressed;
 302
 303        if (!psi)
 304                return;
 305
 306        mutex_lock(&psi->read_mutex);
 307        if (psi->open && psi->open(psi))
 308                goto out;
 309
 310        while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed,
 311                                psi)) > 0) {
 312                rc = pstore_mkfile(type, psi->name, id, count, buf,
 313                                  (size_t)size, time, psi);
 314                kfree(buf);
 315                buf = NULL;
 316                if (rc && (rc != -EEXIST || !quiet))
 317                        failed++;
 318        }
 319        if (psi->close)
 320                psi->close(psi);
 321out:
 322        mutex_unlock(&psi->read_mutex);
 323
 324        if (failed)
 325                printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
 326                       failed, psi->name);
 327}
 328
 329static void pstore_dowork(struct work_struct *work)
 330{
 331        pstore_get_records(1);
 332}
 333
 334static void pstore_timefunc(unsigned long dummy)
 335{
 336        if (pstore_new_entry) {
 337                pstore_new_entry = 0;
 338                schedule_work(&pstore_work);
 339        }
 340
 341        mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms));
 342}
 343
 344module_param(backend, charp, 0444);
 345MODULE_PARM_DESC(backend, "Pstore backend to use");
 346