diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2018-03-20 09:48:42 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2024-01-08 14:01:21 +0100 |
commit | 41928bc2e84bddbe45aaf689eadc67ca804bb218 (patch) | |
tree | 0aeb87b5fb66057658221ce71cd67fa7c2361524 | |
parent | d79c35a6a4e026ed1ca6a445ade63f193e28b512 (diff) |
input/psmouse: Don't hold the mutex while calling ->disconnect
At least trackpoint_disconnect wants to remove some sysfs files, and
we can't remove sysfs files while holding psmouse_mutex:
======================================================
WARNING: possible circular locking dependency detected
4.16.0-rc5-g613eb885b69e-drmtip_1+ #1 Tainted: G U
------------------------------------------------------
kworker/0:3/102 is trying to acquire lock:
(kn->count#130){++++}, at: [<000000009679748b>] kernfs_remove_by_name_ns+0x3b/0x80
but task is already holding lock:
(psmouse_mutex){+.+.}, at: [<0000000014f44bcc>] psmouse_disconnect+0x62/0x160
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (psmouse_mutex){+.+.}:
psmouse_attr_set_helper+0x28/0x140
kernfs_fop_write+0xfe/0x180
__vfs_write+0x1e/0x130
vfs_write+0xbd/0x1b0
SyS_write+0x40/0xa0
do_syscall_64+0x65/0x1a0
entry_SYSCALL_64_after_hwframe+0x42/0xb7
-> #0 (kn->count#130){++++}:
__kernfs_remove+0x243/0x2b0
kernfs_remove_by_name_ns+0x3b/0x80
remove_files.isra.0+0x2b/0x60
sysfs_remove_group+0x38/0x80
sysfs_remove_groups+0x24/0x40
trackpoint_disconnect+0x2c/0x50
psmouse_disconnect+0x8f/0x160
serio_disconnect_driver+0x28/0x40
serio_driver_remove+0xc/0x10
device_release_driver_internal+0x15b/0x230
serio_handle_event+0x1c8/0x260
process_one_work+0x215/0x620
worker_thread+0x48/0x3a0
kthread+0xfb/0x130
ret_from_fork+0x3a/0x50
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(psmouse_mutex);
lock(kn->count#130);
lock(psmouse_mutex);
lock(kn->count#130);
*** DEADLOCK ***
6 locks held by kworker/0:3/102:
#0: ((wq_completion)"events_long"){+.+.}, at: [<000000002e408bfa>] process_one_work+0x191/0x620
#1: (serio_event_work){+.+.}, at: [<000000002e408bfa>] process_one_work+0x191/0x620
#2: (serio_mutex){+.+.}, at: [<00000000c8a49847>] serio_handle_event+0x23/0x260
#3: (&dev->mutex){....}, at: [<00000000b55eee75>] device_release_driver_internal+0x2f/0x230
#4: (&serio->drv_mutex){+.+.}, at: [<000000009719f997>] serio_disconnect_driver+0x16/0x40
#5: (psmouse_mutex){+.+.}, at: [<0000000014f44bcc>] psmouse_disconnect+0x62/0x160
stack backtrace:
CPU: 0 PID: 102 Comm: kworker/0:3 Tainted: G U 4.16.0-rc5-g613eb885b69e-drmtip_1+ #1
Hardware name: LENOVO 74591P0/74591P0, BIOS 6DET28WW (1.05 ) 07/30/2008
Workqueue: events_long serio_handle_event
Call Trace:
dump_stack+0x5f/0x86
print_circular_bug.isra.18+0x1d0/0x2c0
__lock_acquire+0x14ae/0x1b60
? kernfs_remove_by_name_ns+0x20/0x80
? lock_acquire+0xaf/0x200
lock_acquire+0xaf/0x200
? kernfs_remove_by_name_ns+0x3b/0x80
__kernfs_remove+0x243/0x2b0
? kernfs_remove_by_name_ns+0x3b/0x80
? kernfs_name_hash+0xd/0x70
? kernfs_find_ns+0x7e/0x100
kernfs_remove_by_name_ns+0x3b/0x80
remove_files.isra.0+0x2b/0x60
sysfs_remove_group+0x38/0x80
sysfs_remove_groups+0x24/0x40
trackpoint_disconnect+0x2c/0x50
psmouse_disconnect+0x8f/0x160
serio_disconnect_driver+0x28/0x40
serio_driver_remove+0xc/0x10
device_release_driver_internal+0x15b/0x230
serio_handle_event+0x1c8/0x260
process_one_work+0x215/0x620
worker_thread+0x48/0x3a0
? _raw_spin_unlock_irqrestore+0x4c/0x60
kthread+0xfb/0x130
? process_one_work+0x620/0x620
? _kthread_create_on_node+0x30/0x30
ret_from_fork+0x3a/0x50
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index a0aac76b1e41..f925051f6444 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1492,8 +1492,10 @@ static void psmouse_disconnect(struct serio *serio) psmouse_deactivate(parent); } + mutex_unlock(&psmouse_mutex); if (psmouse->disconnect) psmouse->disconnect(psmouse); + mutex_lock(&psmouse_mutex); if (parent && parent->pt_deactivate) parent->pt_deactivate(parent); |