BACKPORT: 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()

Bug: 309378049
Change-Id: I61eb91f21a01460f340f890b25c60de7597a87ff
Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
Acked-by: Luis Chamberlain <mcgrof@kernel.org>
Link: https://lore.kernel.org/r/1698330459-31776-2-git-send-email-quic_mojha@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit effd7c70eaa0440688b60b9d419243695ede3c45)
Signed-off-by: Srinivasarao Pathipati <quic_c_spathi@quicinc.com>
This commit is contained in:
Mukesh Ojha 2023-10-26 19:57:39 +05:30 committed by Srinivasarao Pathipati
parent 93e172c43e
commit d43ac48de2
3 changed files with 7 additions and 1 deletions

View File

@ -114,6 +114,10 @@ void kill_pending_fw_fallback_reqs(bool kill_all)
if (kill_all || !fw_priv->need_uevent)
__fw_load_abort(fw_priv);
}
if (kill_all)
fw_load_abort_all = true;
mutex_unlock(&fw_lock);
}
@ -510,7 +514,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
}
mutex_lock(&fw_lock);
if (fw_state_is_aborted(fw_priv)) {
if (fw_load_abort_all || fw_state_is_aborted(fw_priv)) {
mutex_unlock(&fw_lock);
retval = -EINTR;
goto out;

View File

@ -78,6 +78,7 @@ struct fw_priv {
};
extern struct mutex fw_lock;
extern bool fw_load_abort_all;
static inline bool __fw_state_check(struct fw_priv *fw_priv,
enum fw_status status)

View File

@ -90,6 +90,7 @@ static inline struct fw_priv *to_fw_priv(struct kref *ref)
DEFINE_MUTEX(fw_lock);
static struct firmware_cache fw_cache;
bool fw_load_abort_all;
/* Builtin firmware support */