Commit a144c6a6c924aa1da04dd77fb84b89927354fdff
1 parent
e1866b33b1
Exists in
master
and in
7 other branches
PM: Print a warning if firmware is requested when tasks are frozen
Some drivers erroneously use request_firmware() from their ->resume() (or ->thaw(), or ->restore()) callbacks, which is not going to work unless the firmware has been built in. This causes system resume to stall until the firmware-loading timeout expires, which makes users think that the resume has failed and reboot their machines unnecessarily. For this reason, make _request_firmware() print a warning and return immediately with error code if it has been called when tasks are frozen and it's impossible to start any new usermode helpers. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Reviewed-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
Showing 3 changed files with 19 additions and 0 deletions Side-by-side Diff
drivers/base/firmware_class.c
... | ... | @@ -521,6 +521,11 @@ |
521 | 521 | if (!firmware_p) |
522 | 522 | return -EINVAL; |
523 | 523 | |
524 | + if (WARN_ON(usermodehelper_is_disabled())) { | |
525 | + dev_err(device, "firmware: %s will not be loaded\n", name); | |
526 | + return -EBUSY; | |
527 | + } | |
528 | + | |
524 | 529 | *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); |
525 | 530 | if (!firmware) { |
526 | 531 | dev_err(device, "%s: kmalloc(struct firmware) failed\n", |
include/linux/kmod.h
... | ... | @@ -111,8 +111,13 @@ |
111 | 111 | |
112 | 112 | extern void usermodehelper_init(void); |
113 | 113 | |
114 | +#ifdef CONFIG_PM_SLEEP | |
114 | 115 | extern int usermodehelper_disable(void); |
115 | 116 | extern void usermodehelper_enable(void); |
117 | +extern bool usermodehelper_is_disabled(void); | |
118 | +#else | |
119 | +static inline bool usermodehelper_is_disabled(void) { return false; } | |
120 | +#endif | |
116 | 121 | |
117 | 122 | #endif /* __LINUX_KMOD_H__ */ |
kernel/kmod.c
... | ... | @@ -301,6 +301,15 @@ |
301 | 301 | usermodehelper_disabled = 0; |
302 | 302 | } |
303 | 303 | |
304 | +/** | |
305 | + * usermodehelper_is_disabled - check if new helpers are allowed to be started | |
306 | + */ | |
307 | +bool usermodehelper_is_disabled(void) | |
308 | +{ | |
309 | + return usermodehelper_disabled; | |
310 | +} | |
311 | +EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); | |
312 | + | |
304 | 313 | static void helper_lock(void) |
305 | 314 | { |
306 | 315 | atomic_inc(&running_helpers); |