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@xxxxxxxxx> --- This patch supersedes my previous "apm-emulation: Fix mutex race condition" patch; this patch fixes that earlier bug too. --- clean-2.6.39-rc7/drivers/char/apm-emulation.c 2011-03-15 01:20:32.000000000 +0000 +++ linux-2.6.39-rc7/drivers/char/apm-emulation.c 2011-05-13 01:40:02.068822695 +0100 @@ -126,7 +126,6 @@ struct apm_user { /* * Local variables */ -static DEFINE_MUTEX(apm_mutex); static atomic_t suspend_acks_pending = ATOMIC_INIT(0); static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); static int apm_disabled; @@ -275,7 +274,6 @@ apm_ioctl(struct file *filp, u_int cmd, if (!as->suser || !as->writer) return -EPERM; - mutex_lock(&apm_mutex); switch (cmd) { case APM_IOC_SUSPEND: mutex_lock(&state_lock); @@ -336,7 +334,6 @@ apm_ioctl(struct file *filp, u_int cmd, mutex_unlock(&state_lock); break; } - mutex_unlock(&apm_mutex); return err; } @@ -371,7 +368,6 @@ static int apm_open(struct inode * inode { struct apm_user *as; - mutex_lock(&apm_mutex); as = kzalloc(sizeof(*as), GFP_KERNEL); if (as) { /* @@ -391,7 +387,6 @@ static int apm_open(struct inode * inode filp->private_data = as; } - mutex_unlock(&apm_mutex); return as ? 0 : -ENOMEM; } _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm