[PATCH][BZ #14652] Fix deadlock on PI mutex in pthread_cond_wait cleanup handler
Jeff Law
law@redhat.com
Thu Oct 4 21:50:00 GMT 2012
On 10/03/2012 04:44 AM, Siddhesh Poyarekar wrote:
> Hi,
>
> This bug is related in principle to pr#14417. If a thread is
> cancelled just after it returns successfully from a futex wait for a PI
> mutex and before async cancellation is disabled, it already holds the
> mutex and hence, the cleanup handler gets deadlocked trying to lock a
> mutex it already owns. The bug report has a reproducer that
> demonstrates the problem.
>
> The attached patch fixes this by checking if the mutex is owned by the
> current thread and if it is, then resume rewinding without attempting
> to lock the mutex. The patch has a test case that verifies that this
> is fixed. I have verified this on x86_64 and i686 (32-bit build on
> x86_64). I have also verified that the test case fails without this
> patch.
>
> The patch applies on top of the patch for pr #14417 that I just
> submitted. OK to commit once the pr #14417 patch is approved?
>
> Regards,
> Siddhesh
>
> Regards,
> Siddhesh
>
> nptl/ChangeLog:
>
> [BZ #14652]
> * Makefile (tests): New test case tst-cond25.
> (LDFLAGS-tst-cond25): Link tst-cond25 against librt.
> * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
> (__condvar_tw_cleanup): Lock mutex only if we don't already
> own it.
> * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
> (__condvar_w_cleanup): Likewise.
> * sysdeps/unix/sysv/linux/pthread-pi-defines.sym: Add TID_MASK.
> * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
> (__condvar_cleanup2): Lock mutex only if we don't already
> own it.
> * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
> (__condvar_cleanup1): Likewise.
> * tst-cond25.c: New test case.
This looks good to me. Please install it -- it is almost totally
independent of the issues Rich has raised as far as I can tell.
Siddhesh is actually fixing the cleanup handlers in code which
implements cancellation handling by way of exception tables.
+ andl $(ROBUST_BIT|PI_BIT), %ebx
+ cmpl $PI_BIT, %ebx
What's the point behind including ROBUST_BIT in the mask here?
+ movl (%eax), %ebx
+ andl $TID_MASK, %ebx
+ cmpl %ebx, %gs:TID
+ je 9f
So when the TID doesn't match don't lock and just bail out? Is that
really the right thing to do?
Those two questions span each of the 4 implementations...
More information about the Libc-alpha
mailing list