Skip to content

Commit effd7c7

Browse files
Mukesh Ojhagregkh
authored andcommitted
firmware_loader: Abort all upcoming firmware load request once reboot triggered
There could be following scenario where there is a ongoing reboot is going from processA which tries to call all the reboot notifier callback and one of them is firmware reboot call which tries to abort all the ongoing firmware userspace request under fw_lock but there could be another processB which tries to do request firmware, which came just after abort done from ProcessA and ask for userspace to load the firmware and this can stop the ongoing reboot ProcessA to stall for next 60s(default timeout) which may not be expected behaviour everyone like to see, instead we should abort any firmware load request which came once firmware knows about the reboot through notification. ProcessA ProcessB kernel_restart_prepare blocking_notifier_call_chain fw_shutdown_notify kill_pending_fw_fallback_reqs __fw_load_abort fw_state_aborted request_firmware __fw_state_set firmware_fallback_sysfs ... fw_load_from_user_helper .. ... . .. usermodehelper_read_trylock fw_load_sysfs_fallback fw_sysfs_wait_timeout usermodehelper_disable __usermodehelper_disable down_write() Signed-off-by: Mukesh Ojha <[email protected]> Acked-by: Luis Chamberlain <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 87ffa98 commit effd7c7

File tree

3 files changed

+7
-1
lines changed

3 files changed

+7
-1
lines changed

drivers/base/firmware_loader/fallback.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ void kill_pending_fw_fallback_reqs(bool kill_all)
5757
if (kill_all || !fw_priv->need_uevent)
5858
__fw_load_abort(fw_priv);
5959
}
60+
61+
if (kill_all)
62+
fw_load_abort_all = true;
63+
6064
mutex_unlock(&fw_lock);
6165
}
6266

@@ -86,7 +90,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
8690
}
8791

8892
mutex_lock(&fw_lock);
89-
if (fw_state_is_aborted(fw_priv)) {
93+
if (fw_load_abort_all || fw_state_is_aborted(fw_priv)) {
9094
mutex_unlock(&fw_lock);
9195
retval = -EINTR;
9296
goto out;

drivers/base/firmware_loader/firmware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct fw_priv {
8686

8787
extern struct mutex fw_lock;
8888
extern struct firmware_cache fw_cache;
89+
extern bool fw_load_abort_all;
8990

9091
static inline bool __fw_state_check(struct fw_priv *fw_priv,
9192
enum fw_status status)

drivers/base/firmware_loader/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static inline struct fw_priv *to_fw_priv(struct kref *ref)
9393
DEFINE_MUTEX(fw_lock);
9494

9595
struct firmware_cache fw_cache;
96+
bool fw_load_abort_all;
9697

9798
void fw_state_init(struct fw_priv *fw_priv)
9899
{

0 commit comments

Comments
 (0)