Commit 024e4ec1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux

Pull pstore patches from Tony Luck:
 "A few fixes to reduce places where pstore might hang a system in the
  crash path.  Plus a new mountpoint (/sys/fs/pstore ...  makes more
  sense then /dev/pstore)."

Fix up trivial conflict in drivers/firmware/efivars.c

* tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
  pstore: Create a convenient mount point for pstore
  efi_pstore: Introducing workqueue updating sysfs
  efivars: Disable external interrupt while holding efivars->lock
  efi_pstore: Avoid deadlock in non-blocking paths
  pstore: Avoid deadlock in panic and emergency-restart path
parents 850cb82b fb0af3f2
Where: /dev/pstore/... Where: /sys/fs/pstore/... (or /dev/pstore/...)
Date: March 2011 Date: March 2011
Kernel Version: 2.6.39 Kernel Version: 2.6.39
Contact: tony.luck@intel.com Contact: tony.luck@intel.com
...@@ -11,9 +11,9 @@ Description: Generic interface to platform dependent persistent storage. ...@@ -11,9 +11,9 @@ Description: Generic interface to platform dependent persistent storage.
of the console log is captured, but other interesting of the console log is captured, but other interesting
data can also be saved. data can also be saved.
# mount -t pstore -o kmsg_bytes=8000 - /dev/pstore # mount -t pstore -o kmsg_bytes=8000 - /sys/fs/pstore
$ ls -l /dev/pstore $ ls -l /sys/fs/pstore/
total 0 total 0
-r--r--r-- 1 root root 7896 Nov 30 15:38 dmesg-erst-1 -r--r--r-- 1 root root 7896 Nov 30 15:38 dmesg-erst-1
...@@ -27,9 +27,9 @@ Description: Generic interface to platform dependent persistent storage. ...@@ -27,9 +27,9 @@ Description: Generic interface to platform dependent persistent storage.
the file will signal to the underlying persistent storage the file will signal to the underlying persistent storage
device that it can reclaim the space for later re-use. device that it can reclaim the space for later re-use.
$ rm /dev/pstore/dmesg-erst-1 $ rm /sys/fs/pstore/dmesg-erst-1
The expectation is that all files in /dev/pstore The expectation is that all files in /sys/fs/pstore/
will be saved elsewhere and erased from persistent store will be saved elsewhere and erased from persistent store
soon after boot to free up space ready for the next soon after boot to free up space ready for the next
catastrophe. catastrophe.
......
This diff is collapsed.
...@@ -418,9 +418,25 @@ static struct file_system_type pstore_fs_type = { ...@@ -418,9 +418,25 @@ static struct file_system_type pstore_fs_type = {
.kill_sb = pstore_kill_sb, .kill_sb = pstore_kill_sb,
}; };
static struct kobject *pstore_kobj;
static int __init init_pstore_fs(void) static int __init init_pstore_fs(void)
{ {
return register_filesystem(&pstore_fs_type); int err = 0;
/* Create a convenient mount point for people to access pstore */
pstore_kobj = kobject_create_and_add("pstore", fs_kobj);
if (!pstore_kobj) {
err = -ENOMEM;
goto out;
}
err = register_filesystem(&pstore_fs_type);
if (err < 0)
kobject_put(pstore_kobj);
out:
return err;
} }
module_init(init_pstore_fs) module_init(init_pstore_fs)
......
...@@ -96,6 +96,27 @@ static const char *get_reason_str(enum kmsg_dump_reason reason) ...@@ -96,6 +96,27 @@ static const char *get_reason_str(enum kmsg_dump_reason reason)
} }
} }
bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
{
/*
* In case of NMI path, pstore shouldn't be blocked
* regardless of reason.
*/
if (in_nmi())
return true;
switch (reason) {
/* In panic case, other cpus are stopped by smp_send_stop(). */
case KMSG_DUMP_PANIC:
/* Emergency restart shouldn't be blocked by spin lock. */
case KMSG_DUMP_EMERG:
return true;
default:
return false;
}
}
EXPORT_SYMBOL_GPL(pstore_cannot_block_path);
/* /*
* callback from kmsg_dump. (s2,l2) has the most recently * callback from kmsg_dump. (s2,l2) has the most recently
* written bytes, older bytes are in (s1,l1). Save as much * written bytes, older bytes are in (s1,l1). Save as much
...@@ -114,10 +135,12 @@ static void pstore_dump(struct kmsg_dumper *dumper, ...@@ -114,10 +135,12 @@ static void pstore_dump(struct kmsg_dumper *dumper,
why = get_reason_str(reason); why = get_reason_str(reason);
if (in_nmi()) { if (pstore_cannot_block_path(reason)) {
is_locked = spin_trylock(&psinfo->buf_lock); is_locked = spin_trylock_irqsave(&psinfo->buf_lock, flags);
if (!is_locked) if (!is_locked) {
pr_err("pstore dump routine blocked in NMI, may corrupt error record\n"); pr_err("pstore dump routine blocked in %s path, may corrupt error record\n"
, in_nmi() ? "NMI" : why);
}
} else } else
spin_lock_irqsave(&psinfo->buf_lock, flags); spin_lock_irqsave(&psinfo->buf_lock, flags);
oopscount++; oopscount++;
...@@ -143,9 +166,9 @@ static void pstore_dump(struct kmsg_dumper *dumper, ...@@ -143,9 +166,9 @@ static void pstore_dump(struct kmsg_dumper *dumper,
total += hsize + len; total += hsize + len;
part++; part++;
} }
if (in_nmi()) { if (pstore_cannot_block_path(reason)) {
if (is_locked) if (is_locked)
spin_unlock(&psinfo->buf_lock); spin_unlock_irqrestore(&psinfo->buf_lock, flags);
} else } else
spin_unlock_irqrestore(&psinfo->buf_lock, flags); spin_unlock_irqrestore(&psinfo->buf_lock, flags);
} }
......
...@@ -740,7 +740,8 @@ struct efivars { ...@@ -740,7 +740,8 @@ struct efivars {
* 1) ->list - adds, removals, reads, writes * 1) ->list - adds, removals, reads, writes
* 2) ops.[gs]et_variable() calls. * 2) ops.[gs]et_variable() calls.
* It must not be held when creating sysfs entries or calling kmalloc. * It must not be held when creating sysfs entries or calling kmalloc.
* ops.get_next_variable() is only called from register_efivars(), * ops.get_next_variable() is only called from register_efivars()
* or efivar_update_sysfs_entries(),
* which is protected by the BKL, so that path is safe. * which is protected by the BKL, so that path is safe.
*/ */
spinlock_t lock; spinlock_t lock;
......
...@@ -68,12 +68,18 @@ struct pstore_info { ...@@ -68,12 +68,18 @@ struct pstore_info {
#ifdef CONFIG_PSTORE #ifdef CONFIG_PSTORE
extern int pstore_register(struct pstore_info *); extern int pstore_register(struct pstore_info *);
extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
#else #else
static inline int static inline int
pstore_register(struct pstore_info *psi) pstore_register(struct pstore_info *psi)
{ {
return -ENODEV; return -ENODEV;
} }
static inline bool
pstore_cannot_block_path(enum kmsg_dump_reason reason)
{
return false;
}
#endif #endif
#endif /*_LINUX_PSTORE_H*/ #endif /*_LINUX_PSTORE_H*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment