diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2010-01-05 20:56:02 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-01-06 03:14:32 -0500 |
| commit | 59b015133cd0034f5904a76969d73476380aac46 (patch) | |
| tree | 578643cc919b7e62b5086718d5c3f9b0fee836a9 /include/linux | |
| parent | abf2a117c67a67fbb611913a31109d0ff66ab073 (diff) | |
Input: serio - fix potential deadlock when unbinding drivers
sysfs_remove_group() waits for sysfs attributes to be removed, therefore
we do not need to worry about driver-specific attributes being accessed
after driver has been detached from the device. In fact, attempts to take
serio->drv_mutex in attribute methods may lead to the following deadlock:
sysfs_read_file()
fill_read_buffer()
sysfs_get_active_two()
psmouse_attr_show_helper()
serio_pin_driver()
serio_disconnect_driver()
mutex_lock(&serio->drv_mutex);
<--------> mutex_lock(&serio_drv_mutex);
psmouse_disconnect()
sysfs_remove_group(... psmouse_attr_group);
....
sysfs_deactivate();
wait_for_completion();
Fix this by removing calls to serio_[un]pin_driver() and functions themselves
and using driver-private mutexes to serialize access to attribute's set()
methods that may change device state.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/serio.h | 19 |
1 files changed, 0 insertions, 19 deletions
diff --git a/include/linux/serio.h b/include/linux/serio.h index e2f3044d4a4a..813d26c247ec 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
| @@ -136,25 +136,6 @@ static inline void serio_continue_rx(struct serio *serio) | |||
| 136 | spin_unlock_irq(&serio->lock); | 136 | spin_unlock_irq(&serio->lock); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | /* | ||
| 140 | * Use the following functions to pin serio's driver in process context | ||
| 141 | */ | ||
| 142 | static inline int serio_pin_driver(struct serio *serio) | ||
| 143 | { | ||
| 144 | return mutex_lock_interruptible(&serio->drv_mutex); | ||
| 145 | } | ||
| 146 | |||
| 147 | static inline void serio_pin_driver_uninterruptible(struct serio *serio) | ||
| 148 | { | ||
| 149 | mutex_lock(&serio->drv_mutex); | ||
| 150 | } | ||
| 151 | |||
| 152 | static inline void serio_unpin_driver(struct serio *serio) | ||
| 153 | { | ||
| 154 | mutex_unlock(&serio->drv_mutex); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | #endif | 139 | #endif |
| 159 | 140 | ||
| 160 | /* | 141 | /* |
