From: Greg Kroah-Hartman Date: Mon, 11 Sep 2017 11:27:04 +0000 (-0700) Subject: 4.13-stable patches X-Git-Tag: v3.18.71~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d16e0aa25794ca6bcabad8231f1a0d67a7772082;p=thirdparty%2Fkernel%2Fstable-queue.git 4.13-stable patches added patches: revert-firmware-add-sanity-check-on-shutdown-suspend.patch --- diff --git a/queue-4.13/revert-firmware-add-sanity-check-on-shutdown-suspend.patch b/queue-4.13/revert-firmware-add-sanity-check-on-shutdown-suspend.patch new file mode 100644 index 00000000000..223491740e6 --- /dev/null +++ b/queue-4.13/revert-firmware-add-sanity-check-on-shutdown-suspend.patch @@ -0,0 +1,214 @@ +From f007cad159e99fa2acd3b2e9364fbb32ad28b971 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Sun, 10 Sep 2017 21:19:06 -0700 +Subject: Revert "firmware: add sanity check on shutdown/suspend" + +From: Linus Torvalds + +commit f007cad159e99fa2acd3b2e9364fbb32ad28b971 upstream. + +This reverts commit 81f95076281fdd3bc382e004ba1bce8e82fccbce. + +It causes random failures of firmware loading at resume time (well, +random for me, it seems to be more reliable for others) because the +firmware disabling is not actually synchronous with any particular +resume event, and at least the btusb driver that uses a workqueue to +load the firmware at resume seems to occasionally hit the "firmware +loading is disabled" logic because the firmware loader hasn't gotten the +resume event yet. + +Some kind of sanity check for not trying to load firmware when it's not +possible might be a good thing, but this commit was not it. + +Greg seems to have silently suffered the same issue, and pointed to the +likely culprit, and Gabriel C verified the revert fixed it for him too. + +Reported-by: Linus Torvalds +Pointed-at-by: Greg Kroah-Hartman +Tested-by: Gabriel C +Cc: Luis R. Rodriguez +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/driver-api/firmware/request_firmware.rst | 11 - + drivers/base/firmware_class.c | 99 ----------------- + 2 files changed, 110 deletions(-) + +--- a/Documentation/driver-api/firmware/request_firmware.rst ++++ b/Documentation/driver-api/firmware/request_firmware.rst +@@ -44,17 +44,6 @@ request_firmware_nowait + .. kernel-doc:: drivers/base/firmware_class.c + :functions: request_firmware_nowait + +-Considerations for suspend and resume +-===================================== +- +-During suspend and resume only the built-in firmware and the firmware cache +-elements of the firmware API can be used. This is managed by fw_pm_notify(). +- +-fw_pm_notify +------------- +-.. kernel-doc:: drivers/base/firmware_class.c +- :functions: fw_pm_notify +- + request firmware API expected driver use + ======================================== + +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -256,38 +256,6 @@ static int fw_cache_piggyback_on_request + * guarding for corner cases a global lock should be OK */ + static DEFINE_MUTEX(fw_lock); + +-static bool __enable_firmware = false; +- +-static void enable_firmware(void) +-{ +- mutex_lock(&fw_lock); +- __enable_firmware = true; +- mutex_unlock(&fw_lock); +-} +- +-static void disable_firmware(void) +-{ +- mutex_lock(&fw_lock); +- __enable_firmware = false; +- mutex_unlock(&fw_lock); +-} +- +-/* +- * When disabled only the built-in firmware and the firmware cache will be +- * used to look for firmware. +- */ +-static bool firmware_enabled(void) +-{ +- bool enabled = false; +- +- mutex_lock(&fw_lock); +- if (__enable_firmware) +- enabled = true; +- mutex_unlock(&fw_lock); +- +- return enabled; +-} +- + static struct firmware_cache fw_cache; + + static struct firmware_buf *__allocate_fw_buf(const char *fw_name, +@@ -1239,12 +1207,6 @@ _request_firmware(const struct firmware + if (ret <= 0) /* error or already assigned */ + goto out; + +- if (!firmware_enabled()) { +- WARN(1, "firmware request while host is not available\n"); +- ret = -EHOSTDOWN; +- goto out; +- } +- + ret = fw_get_filesystem_firmware(device, fw->priv); + if (ret) { + if (!(opt_flags & FW_OPT_NO_WARN)) +@@ -1755,62 +1717,6 @@ static void device_uncache_fw_images_del + msecs_to_jiffies(delay)); + } + +-/** +- * fw_pm_notify - notifier for suspend/resume +- * @notify_block: unused +- * @mode: mode we are switching to +- * @unused: unused +- * +- * Used to modify the firmware_class state as we move in between states. +- * The firmware_class implements a firmware cache to enable device driver +- * to fetch firmware upon resume before the root filesystem is ready. We +- * disable API calls which do not use the built-in firmware or the firmware +- * cache when we know these calls will not work. +- * +- * The inner logic behind all this is a bit complex so it is worth summarizing +- * the kernel's own suspend/resume process with context and focus on how this +- * can impact the firmware API. +- * +- * First a review on how we go to suspend:: +- * +- * pm_suspend() --> enter_state() --> +- * sys_sync() +- * suspend_prepare() --> +- * __pm_notifier_call_chain(PM_SUSPEND_PREPARE, ...); +- * suspend_freeze_processes() --> +- * freeze_processes() --> +- * __usermodehelper_set_disable_depth(UMH_DISABLED); +- * freeze all tasks ... +- * freeze_kernel_threads() +- * suspend_devices_and_enter() --> +- * dpm_suspend_start() --> +- * dpm_prepare() +- * dpm_suspend() +- * suspend_enter() --> +- * platform_suspend_prepare() +- * dpm_suspend_late() +- * freeze_enter() +- * syscore_suspend() +- * +- * When we resume we bail out of a loop from suspend_devices_and_enter() and +- * unwind back out to the caller enter_state() where we were before as follows:: +- * +- * enter_state() --> +- * suspend_devices_and_enter() --> (bail from loop) +- * dpm_resume_end() --> +- * dpm_resume() +- * dpm_complete() +- * suspend_finish() --> +- * suspend_thaw_processes() --> +- * thaw_processes() --> +- * __usermodehelper_set_disable_depth(UMH_FREEZING); +- * thaw_workqueues(); +- * thaw all processes ... +- * usermodehelper_enable(); +- * pm_notifier_call_chain(PM_POST_SUSPEND); +- * +- * fw_pm_notify() works through pm_notifier_call_chain(). +- */ + static int fw_pm_notify(struct notifier_block *notify_block, + unsigned long mode, void *unused) + { +@@ -1824,7 +1730,6 @@ static int fw_pm_notify(struct notifier_ + */ + kill_pending_fw_fallback_reqs(true); + device_cache_fw_images(); +- disable_firmware(); + break; + + case PM_POST_SUSPEND: +@@ -1837,7 +1742,6 @@ static int fw_pm_notify(struct notifier_ + mutex_lock(&fw_lock); + fw_cache.state = FW_LOADER_NO_CACHE; + mutex_unlock(&fw_lock); +- enable_firmware(); + + device_uncache_fw_images_delay(10 * MSEC_PER_SEC); + break; +@@ -1886,7 +1790,6 @@ static void __init fw_cache_init(void) + static int fw_shutdown_notify(struct notifier_block *unused1, + unsigned long unused2, void *unused3) + { +- disable_firmware(); + /* + * Kill all pending fallback requests to avoid both stalling shutdown, + * and avoid a deadlock with the usermode_lock. +@@ -1902,7 +1805,6 @@ static struct notifier_block fw_shutdown + + static int __init firmware_class_init(void) + { +- enable_firmware(); + fw_cache_init(); + register_reboot_notifier(&fw_shutdown_nb); + #ifdef CONFIG_FW_LOADER_USER_HELPER +@@ -1914,7 +1816,6 @@ static int __init firmware_class_init(vo + + static void __exit firmware_class_exit(void) + { +- disable_firmware(); + #ifdef CONFIG_PM_SLEEP + unregister_syscore_ops(&fw_syscore_ops); + unregister_pm_notifier(&fw_cache.pm_notify); diff --git a/queue-4.13/series b/queue-4.13/series index c3019d0b89d..ee4f8fd9b53 100644 --- a/queue-4.13/series +++ b/queue-4.13/series @@ -17,3 +17,4 @@ mm-swapfile.c-fix-swapon-frontswap_map-memory-leak-on-error.patch mm-sparse.c-fix-typo-in-online_mem_sections.patch mm-memory.c-fix-mem_cgroup_oom_disable-call-missing.patch kvm-svm-limit-pferr_nested_guest_page-error_code-check-to-l1-guest.patch +revert-firmware-add-sanity-check-on-shutdown-suspend.patch