platform/x86: thinkpad_acpi: Use input_device_enabled()
Subsystems (3)
PATCH 1/1 platform/x86: thinkpad_acpi: Use input_device_enabled()
From: Andrzej Pietrasiewicz <[email protected]>
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
---
Not sure how this got stuck in my patch queue but it is still valid...
drivers/platform/x86/lenovo/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/platform/x86/lenovo/thinkpad_acpi.c +3 -1
@@ -2547,9 +2547,10 @@ static void hotkey_poll_setup(const bool may_warn)lockdep_assert_held (&hotkey_mutex); +mutex_lock (&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && (poll_driver_mask || - (poll_user_mask && tpacpi_inputdev->users >0 ))) { + (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task =kthread_run (hotkey_kthread,NULL ,TPACPI_NVRAM_KTHREAD_NAME );
@@ -2566,6 +2567,7 @@ static void hotkey_poll_setup(const bool may_warn) poll_user_mask, poll_driver_mask); } } +mutex_unlock (&tpacpi_inputdev->mutex); }static void hotkey_poll_setup_safe (const bool may_warn)
Signature · 5 lines
2.55.0.571.g244d577d93-goog -- Dmitry
Quoted 36 lines · Dmitry Torokhov
From: Andrzej Pietrasiewicz <[email protected]>
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
Signed-off-by Andrzej Pietrasiewicz <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>---
Not sure how this got stuck in my patch queue but it is still valid...
drivers/platform/x86/lenovo/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/platform/x86/lenovo/thinkpad_acpi.c +2
-1@@ -2547,9 +2547,10 @@ static void hotkey_poll_setup(const bool may_warn) lockdep_assert_held(&hotkey_mutex); +mutex_lock (&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && (poll_driver_mask || - (poll_user_mask && tpacpi_inputdev->users >0 ))) { + (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task = kthread_run(hotkey_kthread,drivers/platform/x86/lenovo/thinkpad_acpi.c +0
-0NULL, TPACPI_NVRAM_KTHREAD_NAME);
drivers/platform/x86/lenovo/thinkpad_acpi.c static void hotkey_poll_setup(const bool may_warn) · line 2573
Quoted 7 lines
drivers/platform/x86/lenovo/thinkpad_acpi.c +1
-0@@ -2566,6 +2567,7 @@ static void hotkey_poll_setup(const bool may_warn) poll_user_mask, poll_driver_mask); } } +mutex_unlock (&tpacpi_inputdev->mutex); }static void hotkey_poll_setup_safe (const bool may_warn)
Looks good to me.
Only note is that can you use guard(mutex)(&tpacpi_inputdev->mutex) instead of the lock/unlock? I think that's preferred these days.
Hi Mark,
Quoted 44 lines · Mark Pearson
Quoted 41 lines · Dmitry Torokhov
From: Andrzej Pietrasiewicz <[email protected]>
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
Signed-off-by Andrzej Pietrasiewicz <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>---
Not sure how this got stuck in my patch queue but it is still valid...
drivers/platform/x86/lenovo/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/platform/x86/lenovo/thinkpad_acpi.c +2
-1@@ -2547,9 +2547,10 @@ static void hotkey_poll_setup(const bool may_warn) lockdep_assert_held(&hotkey_mutex); +mutex_lock (&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && (poll_driver_mask || - (poll_user_mask && tpacpi_inputdev->users >0 ))) { + (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task = kthread_run(hotkey_kthread,drivers/platform/x86/lenovo/thinkpad_acpi.c +1
-0NULL, TPACPI_NVRAM_KTHREAD_NAME);@@ -2566,6 +2567,7 @@ static void hotkey_poll_setup(const bool may_warn) poll_user_mask, poll_driver_mask); } } +mutex_unlock (&tpacpi_inputdev->mutex); }
Quoted 6 lines
drivers/platform/x86/lenovo/thinkpad_acpi.c static void hotkey_poll_setup(const bool may_warn) · line 2573
Quoted 2 lines
drivers/platform/x86/lenovo/thinkpad_acpi.c +0
-0static void hotkey_poll_setup_safe (const bool may_warn)Looks good to me.
Only note is that can you use guard(mutex)(&tpacpi_inputdev->mutex) instead of the lock/unlock? I think that's preferred these days.
If that is desired the whole driver needs converting. I can do it in a separate patch(es) if you want.
Quoted 2 lines
Reviewed-by Mark Pearson <[email protected]>
Thanks.
Signature · 1 line
Dmitry
Mark Pearson
maintainerQuoted 52 lines · Dmitry Torokhov
Hi Mark,
Quoted 49 lines · Mark Pearson
Quoted 36 lines · Dmitry Torokhov
From: Andrzej Pietrasiewicz <[email protected]>
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
Signed-off-by Andrzej Pietrasiewicz <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>---
Not sure how this got stuck in my patch queue but it is still valid...
drivers/platform/x86/lenovo/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/platform/x86/lenovo/thinkpad_acpi.c +2
-1@@ -2547,9 +2547,10 @@ static void hotkey_poll_setup(const bool may_warn) lockdep_assert_held(&hotkey_mutex); +mutex_lock (&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && (poll_driver_mask || - (poll_user_mask && tpacpi_inputdev->users >0 ))) { + (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task = kthread_run(hotkey_kthread,drivers/platform/x86/lenovo/thinkpad_acpi.c +0
-0NULL, TPACPI_NVRAM_KTHREAD_NAME);drivers/platform/x86/lenovo/thinkpad_acpi.c static void hotkey_poll_setup(const bool may_warn) · line 2573
Quoted 7 lines
drivers/platform/x86/lenovo/thinkpad_acpi.c +1
-0@@ -2566,6 +2567,7 @@ static void hotkey_poll_setup(const bool may_warn) poll_user_mask, poll_driver_mask); } } +mutex_unlock (&tpacpi_inputdev->mutex); }static void hotkey_poll_setup_safe (const bool may_warn)Looks good to me.
Quoted 5 lines
Quoted 1 line
Only note is that can you use guard(mutex)(&tpacpi_inputdev->mutex) instead of the lock/unlock? I think that's preferred these days.
If that is desired the whole driver needs converting. I can do it in a separate patch(es) if you want.
Ah - good point. Not worth it for this IMO, unless the more experienced maintainers have a strong opinion :)
Mark
Quoted 55 lines · Mark Pearson
Quoted 52 lines · Dmitry Torokhov
Hi Mark,
Quoted 49 lines · Mark Pearson
Quoted 36 lines · Dmitry Torokhov
From: Andrzej Pietrasiewicz <[email protected]>
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
Signed-off-by Andrzej Pietrasiewicz <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>---
Not sure how this got stuck in my patch queue but it is still valid...
drivers/platform/x86/lenovo/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/platform/x86/lenovo/thinkpad_acpi.c +2
-1@@ -2547,9 +2547,10 @@ static void hotkey_poll_setup(const bool may_warn) lockdep_assert_held(&hotkey_mutex); +mutex_lock (&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && (poll_driver_mask || - (poll_user_mask && tpacpi_inputdev->users >0 ))) { + (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task = kthread_run(hotkey_kthread,drivers/platform/x86/lenovo/thinkpad_acpi.c +0
-0NULL, TPACPI_NVRAM_KTHREAD_NAME);drivers/platform/x86/lenovo/thinkpad_acpi.c static void hotkey_poll_setup(const bool may_warn) · line 2573
Quoted 7 lines
drivers/platform/x86/lenovo/thinkpad_acpi.c +1
-0@@ -2566,6 +2567,7 @@ static void hotkey_poll_setup(const bool may_warn) poll_user_mask, poll_driver_mask); } } +mutex_unlock (&tpacpi_inputdev->mutex); }static void hotkey_poll_setup_safe (const bool may_warn)Looks good to me.
Quoted 6 lines
Quoted 5 lines
Quoted 1 line
Only note is that can you use guard(mutex)(&tpacpi_inputdev->mutex) instead of the lock/unlock? I think that's preferred these days.
If that is desired the whole driver needs converting. I can do it in a separate patch(es) if you want.
Ah - good point. Not worth it for this IMO, unless the more experienced maintainers have a strong opinion :)
Well, I went and did it anyways in case you want to apply it.
Thanks.
Signature · 1 line
Dmitry
Ilpo Järvinen
maintainerQuoted 2 lines · Dmitry Torokhov
Use the new helper. Inspecting input device's 'users' member needs to be done under device's mutex, so add appropriate invocations.
Thank you for your contribution, it has been applied to my local review-ilpo-next branch. Note it will show up in the public platform-drivers-x86/review-ilpo-next branch only once I've pushed my local branch there, which might take a while.
FYI [if applicable to your patch], as per Linus' policy change, also fixes are mostly routed through for-next unless the fix is for a commit introduced in the most recent cycle or is clearly a regression fix.
The list of commits applied:
[1/1] platform/x86: thinkpad_acpi: Use input_device_enabled()
commit: be0048786d53375fa4eace15cfdf65593956a1a2
--
i.
Quoted 2 lines · Ilpo Järvinen
[1/1] platform/x86:
thinkpad_acpi: Useinput_device_enabled()commit: be0048786d53375fa4eace15cfdf65593956a1a2
This hangs on module load for me. hotkey_inputdev_open() gets called from input_open_device() with dev->mutex already held, so the new lock in hotkey_poll_setup() deadlocks:
INFO: task insmod:28182 is blocked on a mutex likely owned by task insmod:28182. hotkey_poll_setup+0x50/0x140 [thinkpad_acpi] hotkey_inputdev_open+0x36/0x50 [thinkpad_acpi] input_open_device+0x9d/0x130 kbd_connect+0x8f/0xb0
I guess hotkey_inputdev_close() has the same issue. This was next-20260929's thinkpad_acpi.c built against 7.1.11.
Quoted 8 lines · Ali Ahmet Memiş
Quoted 2 lines · Ilpo Järvinen
[1/1] platform/x86:
thinkpad_acpi: Useinput_device_enabled()commit: be0048786d53375fa4eace15cfdf65593956a1a2This hangs on module load for me.
hotkey_inputdev_open()gets called frominput_open_device()withdev->mutexalready held, so the new lock inhotkey_poll_setup()deadlocks:
Quoted 8 lines
INFO: task insmod:28182 is blocked on a mutex likely owned by task insmod:28182. hotkey_poll_setup+0x50/0x140 [thinkpad_acpi] hotkey_inputdev_open+0x36/0x50 [thinkpad_acpi] input_open_device+0x9d/0x130 kbd_connect+0x8f/0xb0I guess
hotkey_inputdev_close()has the same issue. This was next-20260929'sthinkpad_acpi.cbuilt against 7.1.11.
Hmm, indeed. I wonder if below will fox this for you.
Signature · 32 lines
Dmitry
platform/x86: thinkpad_acpi: fix deadlock in hotkey input open/close
Commit d6479c25ecef ("platform/x86: thinkpad_acpi: Use
input_device_enabled()") changed hotkey_poll_setup() to acquire
tpacpi_inputdev->mutex and call input_device_enabled(tpacpi_inputdev).
However, the input core already holds dev->mutex when invoking a
device's open() and close() callbacks. Because hotkey_inputdev_open()
and hotkey_inputdev_close() call into hotkey_poll_setup(), attempting to
acquire tpacpi_inputdev->mutex again results in an immediate
self-deadlock.
Additionally, locking tpacpi_inputdev->mutex inside hotkey_poll_setup()
while holding hotkey_mutex introduces an ABBA lock ordering inversion
with hotkey_inputdev_open() and hotkey_inputdev_close(), which acquire
hotkey_mutex while holding tpacpi_inputdev->mutex. Finally,
input_inhibit_device() calls dev->close() before setting dev->inhibited,
so input_device_enabled() still returns true inside
hotkey_inputdev_close().
Track whether the input device is active in a driver-local boolean
protected by hotkey_mutex instead of locking tpacpi_inputdev->mutex and
querying input_device_enabled().
Fixes: d6479c25ecef ("platform/x86: thinkpad_acpi: Use input_device_enabled()")
Assisted-by: LLM
Signed-off-by: Dmitry Torokhov <[email protected]>
---
drivers/platform/x86/lenovo/thinkpad_acpi.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)drivers/platform/x86/lenovo/thinkpad_acpi.c +11 -5
@@ -1887,6 +1887,7 @@ static u32 hotkey_reserved_mask; /* events better left disabled */static u32 hotkey_driver_mask;/* events needed by the driver */ static u32 hotkey_user_mask;/* events visible to userspace */ static u32 hotkey_acpi_mask;/* events enabled in firmware */ +static bool hotkey_input_enabled;static bool tpacpi_driver_event (const unsigned int hkey_event);static void hotkey_poll_setup (const bool may_warn);
@@ -2544,10 +2545,8 @@ static void hotkey_poll_setup(const bool may_warn)lockdep_assert_held (&hotkey_mutex); -guard (mutex)(&tpacpi_inputdev->mutex);if (hotkey_poll_freq >0 && - (poll_driver_mask || - (poll_user_mask &&input_device_enabled (tpacpi_inputdev)))) { + (poll_driver_mask || (poll_user_mask && hotkey_input_enabled))) {if (!tpacpi_hotkey_task) { tpacpi_hotkey_task =kthread_run (hotkey_kthread,NULL ,TPACPI_NVRAM_KTHREAD_NAME );
@@ -2602,7 +2601,10 @@ static int hotkey_inputdev_open(struct input_dev *dev)switch (tpacpi_lifecycle) {case TPACPI_LIFE_INIT :case TPACPI_LIFE_RUNNING : -hotkey_poll_setup_safe (false); + scoped_guard(mutex, &hotkey_mutex) { + hotkey_input_enabled = true; +hotkey_poll_setup (false); + }return 0 ;case TPACPI_LIFE_EXITING :return -EBUSY ;
@@ -2615,10 +2617,14 @@ static int hotkey_inputdev_open(struct input_dev *dev)static void hotkey_inputdev_close (struct input_dev *dev) { +guard (mutex)(&hotkey_mutex); + + hotkey_input_enabled = false; +/* disable hotkey polling when possible */ if (tpacpi_lifecycle !=TPACPI_LIFE_EXITING && !(hotkey_source_mask & hotkey_driver_mask)) -hotkey_poll_setup_safe (false); +hotkey_poll_setup (false); }/* sysfs hotkey enable ------------------------------------------------- */
Signature · 1 line
2.56.0.rc1.315.gc6ed9934b7-goog
Ali Ahmet Memiş
Tested-byQuoted 1 line · Dmitry Torokhov
Hmm, indeed. I wonder if below will fox this for you.
Yes, it loads fine now. I also toggled inhibited on the input device with polling enabled, and the nvram thread stops and starts again as expected.