[PATCH 2/5] platform/x86: hp-wmi: avoid cancel_delayed_work_sync from work handler

From: Emre Cecanpunar

Date: Fri Mar 20 2026 - 19:58:29 EST


hp_wmi_apply_fan_settings() calls cancel_delayed_work_sync() in the
PWM_MODE_AUTO case to stop the keep-alive timer. This function is also
called from hp_wmi_hwmon_keep_alive_handler(), which is itself a
delayed work handler.

If the keep-alive work is executing and the fan mode happens to be
AUTO (e.g. a concurrent sysfs write changed it just before the handler
read priv->mode), cancel_delayed_work_sync() tries to flush the work
item it is already running inside, causing a deadlock.

The workqueue documentation explicitly requires callers to ensure this
self-flush situation does not arise.

Replace cancel_delayed_work_sync() with cancel_delayed_work() in
hp_wmi_apply_fan_settings(). The non-synchronous variant cancels
pending work without waiting for a running instance to complete,
avoiding the deadlock. The synchronous cancel in hp_wmi_bios_remove()
is unaffected and still provides the final cleanup guarantee at driver
removal time.

Signed-off-by: Emre Cecanpunar <emreleno@xxxxxxxxx>
---
drivers/platform/x86/hp/hp-wmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index 0cb2a2b31998..41769c0861e5 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -2365,7 +2365,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
}
if (ret < 0)
return ret;
- cancel_delayed_work_sync(&priv->keep_alive_dwork);
+ cancel_delayed_work(&priv->keep_alive_dwork);
return 0;
default:
/* shouldn't happen */
--
2.53.0