[v2,1/2] Fix robust mutex daedlock [BZ #20263]
Commit Message
In Linux/ARM environment, a robust mutex can't catch the timeout result
when it is already owned by other thread and requests to try lock with
a specific time value(pthread_mutex_timedlock). The futex already returns
the ETIMEDOUT result but there is no check the return value and it makes
a deadlock.
* nptl/lowlevelrobustlock.c: Implement ETIMEDOUT logic.
---
ChangeLog | 5 +++++
nptl/lowlevelrobustlock.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
Comments
Jiyoung Yun <t2wish@gmail.com> writes:
> diff --git a/nptl/lowlevelrobustlock.c b/nptl/lowlevelrobustlock.c
> index 3b988b2..e5d3758 100644
> --- a/nptl/lowlevelrobustlock.c
> +++ b/nptl/lowlevelrobustlock.c
> @@ -113,15 +113,20 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
> && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
> continue;
>
> + int err;
> /* If *futex == 2, wait until woken or timeout. */
> #if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
> || !defined lll_futex_timed_wait_bitset)
> - lll_futex_timed_wait (futex, newval, &rt, private);
> + err = lll_futex_timed_wait (futex, newval, &rt, private);
I don't think this call should be checked for timeout because we want to
check the absolute time, not the relative time we computed here.
Andreas.
Jiyoung Yun <t2wish@gmail.com> writes:
> And the same problem can be occured in case of the relative time too,
> doesn't it?
No, it doesn't, see the top of the loop.
Andreas.
@@ -1,3 +1,8 @@
+2016-06-28 Jiyoung Yun <t2wish@gmail.com>
+
+ [BZ #20263]
+ * nptl/lowlevelrobustlock.c: Implement ETIMEDOUT logic.
+
2016-06-28 Richard Henderson <rth@redhat.com>
* elf/elf.h (EM_BPF): New.
@@ -113,15 +113,20 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
&& atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
continue;
+ int err;
/* If *futex == 2, wait until woken or timeout. */
#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
|| !defined lll_futex_timed_wait_bitset)
- lll_futex_timed_wait (futex, newval, &rt, private);
+ err = lll_futex_timed_wait (futex, newval, &rt, private);
#else
- lll_futex_timed_wait_bitset (futex, newval, abstime,
+ err = lll_futex_timed_wait_bitset (futex, newval, abstime,
FUTEX_CLOCK_REALTIME, private);
#endif
+ /* the futex call time out */
+ if (err == -ETIMEDOUT)
+ return -err;
+
try:
;
}