On Thu, Oct 05, 2023 at 10:37:00AM +0530, Mukesh Ojha wrote:
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 <quic_mojha@xxxxxxxxxxx>
---
Changes from v2: https://lore.kernel.org/lkml/1696431327-7369-1-git-send-email-quic_mojha@xxxxxxxxxxx/
- Renamed the flag to fw_abort_load.
Changes from v1: https://lore.kernel.org/lkml/1694773288-15755-1-git-send-email-quic_mojha@xxxxxxxxxxx/
- Renamed the flag to fw_load_abort.
- Kept the flag under fw_lock.
- Repharsed commit text.
drivers/base/firmware_loader/fallback.c | 6 +++++-
drivers/base/firmware_loader/firmware.h | 1 +
drivers/base/firmware_loader/main.c | 1 +
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index bf68e3947814..a162020e98f2 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -57,6 +57,10 @@ void kill_pending_fw_fallback_reqs(bool only_kill_custom)
This routine uses a bool for only_kill_custom for when the events we
should kill ar ecustom or not. Piggy backing on it to assume that the
negative of value represents a shutdown is abusing the semantics
and muddies the waters. So to avoid that, just extend the arguments
to kill_pending_fw_fallback_reqs() for a new bool shutdown, that allows
the code to be clearer and the intent is kept clear.
if (!fw_priv->need_uevent || !only_kill_custom)
__fw_load_abort(fw_priv);
}
+
+ if (!only_kill_custom)
+ fw_abort_load = true;
+
mutex_unlock(&fw_lock);
}
@@ -86,7 +90,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
}
mutex_lock(&fw_lock);
- if (fw_state_is_aborted(fw_priv)) {
+ if (fw_abort_load || fw_state_is_aborted(fw_priv)) {
However, do we really need this ? Could we just use:
if (system_state == SYSTEM_HALT ||
system_state == SYSTEM_POWER_OFF ||
system_state == SYSTEM_RESTART ||
fw_state_is_aborted(fw_priv))
?
Luis