diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 12:38:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 12:38:18 -0500 |
commit | 024e4ec1856d57bb78c06ec903d29dcf716f5f47 (patch) | |
tree | 72c89ea735f2aad2f63f64444ec056d7da8e06ff /fs/pstore | |
parent | 850cb82b754c931c570c9cb7f10c9f2181bac617 (diff) | |
parent | fb0af3f2b1b613e5ea75426d454c7e5b1d1eef49 (diff) |
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
Diffstat (limited to 'fs/pstore')
-rw-r--r-- | fs/pstore/inode.c | 18 | ||||
-rw-r--r-- | fs/pstore/platform.c | 35 |
2 files changed, 46 insertions, 7 deletions
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 67de74ca85f4..e4bcb2cf055a 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
@@ -418,9 +418,25 @@ static struct file_system_type pstore_fs_type = { | |||
418 | .kill_sb = pstore_kill_sb, | 418 | .kill_sb = pstore_kill_sb, |
419 | }; | 419 | }; |
420 | 420 | ||
421 | static struct kobject *pstore_kobj; | ||
422 | |||
421 | static int __init init_pstore_fs(void) | 423 | static int __init init_pstore_fs(void) |
422 | { | 424 | { |
423 | return register_filesystem(&pstore_fs_type); | 425 | int err = 0; |
426 | |||
427 | /* Create a convenient mount point for people to access pstore */ | ||
428 | pstore_kobj = kobject_create_and_add("pstore", fs_kobj); | ||
429 | if (!pstore_kobj) { | ||
430 | err = -ENOMEM; | ||
431 | goto out; | ||
432 | } | ||
433 | |||
434 | err = register_filesystem(&pstore_fs_type); | ||
435 | if (err < 0) | ||
436 | kobject_put(pstore_kobj); | ||
437 | |||
438 | out: | ||
439 | return err; | ||
424 | } | 440 | } |
425 | module_init(init_pstore_fs) | 441 | module_init(init_pstore_fs) |
426 | 442 | ||
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 5ea2e77ff023..86d1038b5a12 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -96,6 +96,27 @@ static const char *get_reason_str(enum kmsg_dump_reason reason) | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | bool 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 | } | ||
118 | EXPORT_SYMBOL_GPL(pstore_cannot_block_path); | ||
119 | |||
99 | /* | 120 | /* |
100 | * callback from kmsg_dump. (s2,l2) has the most recently | 121 | * callback from kmsg_dump. (s2,l2) has the most recently |
101 | * written bytes, older bytes are in (s1,l1). Save as much | 122 | * written bytes, older bytes are in (s1,l1). Save as much |
@@ -114,10 +135,12 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
114 | 135 | ||
115 | why = get_reason_str(reason); | 136 | why = get_reason_str(reason); |
116 | 137 | ||
117 | if (in_nmi()) { | 138 | if (pstore_cannot_block_path(reason)) { |
118 | is_locked = spin_trylock(&psinfo->buf_lock); | 139 | is_locked = spin_trylock_irqsave(&psinfo->buf_lock, flags); |
119 | if (!is_locked) | 140 | if (!is_locked) { |
120 | pr_err("pstore dump routine blocked in NMI, may corrupt error record\n"); | 141 | pr_err("pstore dump routine blocked in %s path, may corrupt error record\n" |
142 | , in_nmi() ? "NMI" : why); | ||
143 | } | ||
121 | } else | 144 | } else |
122 | spin_lock_irqsave(&psinfo->buf_lock, flags); | 145 | spin_lock_irqsave(&psinfo->buf_lock, flags); |
123 | oopscount++; | 146 | oopscount++; |
@@ -143,9 +166,9 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
143 | total += hsize + len; | 166 | total += hsize + len; |
144 | part++; | 167 | part++; |
145 | } | 168 | } |
146 | if (in_nmi()) { | 169 | if (pstore_cannot_block_path(reason)) { |
147 | if (is_locked) | 170 | if (is_locked) |
148 | spin_unlock(&psinfo->buf_lock); | 171 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
149 | } else | 172 | } else |
150 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); | 173 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
151 | } | 174 | } |