diff options
author | Paul Parsons <lost.distance@yahoo.com> | 2011-05-12 21:46:03 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-05-23 06:50:43 -0400 |
commit | fda5fe19725edd6805f2fd742235d1a0d0ba93f5 (patch) | |
tree | 86c5e5e7fe1b41ecf18233149f6a1f7a60b4cd45 /drivers/char | |
parent | 81024fc41a9353160bc445fda4f96d1aa5e82791 (diff) |
apm-emulation: apm_mutex breaks ACK; remove it
apm_mutex is locked by a process (e.g. apm -s) at the start of apm_ioctl() and
remains locked while pm_suspend() is called. Any subsequent process trying to
ACK the suspend (e.g. apmd) is then blocked at the start of apm_ioctl(),
causing the suspend to be delayed for 5 seconds in apm_suspend_notifier()
while the ACK times out. In short, ACKs don't work.
The driver's data structures are sufficiently protected by assorted locks. And
pm_suspend() has its own mutex to prevent reentrancy. Consequently there is no
obvious requirement for apm_mutex, which evolved from earlier BKL calls. So
let's remove it.
Signed-off-by: Paul Parsons <lost.distance@yahoo.com>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/apm-emulation.c | 5 |
1 files changed, 0 insertions, 5 deletions
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 45b987c9889e..548708c4b2b8 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -126,7 +126,6 @@ struct apm_user { | |||
126 | /* | 126 | /* |
127 | * Local variables | 127 | * Local variables |
128 | */ | 128 | */ |
129 | static DEFINE_MUTEX(apm_mutex); | ||
130 | static atomic_t suspend_acks_pending = ATOMIC_INIT(0); | 129 | static atomic_t suspend_acks_pending = ATOMIC_INIT(0); |
131 | static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); | 130 | static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); |
132 | static int apm_disabled; | 131 | static int apm_disabled; |
@@ -275,7 +274,6 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg) | |||
275 | if (!as->suser || !as->writer) | 274 | if (!as->suser || !as->writer) |
276 | return -EPERM; | 275 | return -EPERM; |
277 | 276 | ||
278 | mutex_lock(&apm_mutex); | ||
279 | switch (cmd) { | 277 | switch (cmd) { |
280 | case APM_IOC_SUSPEND: | 278 | case APM_IOC_SUSPEND: |
281 | mutex_lock(&state_lock); | 279 | mutex_lock(&state_lock); |
@@ -336,7 +334,6 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg) | |||
336 | mutex_unlock(&state_lock); | 334 | mutex_unlock(&state_lock); |
337 | break; | 335 | break; |
338 | } | 336 | } |
339 | mutex_unlock(&apm_mutex); | ||
340 | 337 | ||
341 | return err; | 338 | return err; |
342 | } | 339 | } |
@@ -371,7 +368,6 @@ static int apm_open(struct inode * inode, struct file * filp) | |||
371 | { | 368 | { |
372 | struct apm_user *as; | 369 | struct apm_user *as; |
373 | 370 | ||
374 | mutex_lock(&apm_mutex); | ||
375 | as = kzalloc(sizeof(*as), GFP_KERNEL); | 371 | as = kzalloc(sizeof(*as), GFP_KERNEL); |
376 | if (as) { | 372 | if (as) { |
377 | /* | 373 | /* |
@@ -391,7 +387,6 @@ static int apm_open(struct inode * inode, struct file * filp) | |||
391 | 387 | ||
392 | filp->private_data = as; | 388 | filp->private_data = as; |
393 | } | 389 | } |
394 | mutex_unlock(&apm_mutex); | ||
395 | 390 | ||
396 | return as ? 0 : -ENOMEM; | 391 | return as ? 0 : -ENOMEM; |
397 | } | 392 | } |