Greg, I know it's late in the -rc cycle but I'd like to get this fix into 3.13. Although it's only likely to happen at shutdown/reboot, the hang frequency could be as often as 1 in 10000.
The patch fixes the count value returned when the cmpxchg() has successfully changed the count. Only one code path checks the returned count when the cmpxchg() is successful; down_read_failed(). After failed down_read attempt is reversed but before the reader waits for the lock, the new count is checked to ensure _someone_ has the lock: /* if there are no active locks, wake the new lock owner(s) */ if ((count & LDSEM_ACTIVE_MASK) == 0) __ldsem_wake(sem); Because ldsem_cmpxchg() was returning the _old_ value on success, this was checking the wrong count value. No other code paths are impacted by the patch. The equivalent diff below also fixes the problem; however, I feel the intent is less clear. | diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c | index 22fad8a..29d9e7c 100644 | --- a/drivers/tty/tty_ldsem.c | +++ b/drivers/tty/tty_ldsem.c | @@ -222,7 +222,7 @@ down_read_failed(struct ld_semaphore *sem, long count, long timeout) | get_task_struct(tsk); | | /* if there are no active locks, wake the new lock owner(s) */ | - if ((count & LDSEM_ACTIVE_MASK) == 0) | + if ((count + adjust & LDSEM_ACTIVE_MASK) == 0) | __ldsem_wake(sem); | | raw_spin_unlock_irq(&sem->wait_lock); Regards, Peter Hurley (1): tty: Fix hang at ldsem_down_read() drivers/tty/tty_ldsem.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/