[lttng-dev] [PATCH lttng-tools] Fix: handle sys_futex() FUTEX_WAIT interrupted by signal

Jérémie Galarneau jeremie.galarneau at efficios.com
Fri Jul 10 15:54:29 EDT 2015


Merged in master, stable-2.6 and stable-2.5. Thanks!

Jérémie

On Mon, Jul 6, 2015 at 5:28 PM, Mathieu Desnoyers <
mathieu.desnoyers at efficios.com> wrote:

> We need to handle EINTR returned by sys_futex() FUTEX_WAIT, otherwise a
> signal interrupting this system call could make sys_futex return too
> early, and therefore cause a synchronization issue.
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> ---
>  src/common/futex.c | 37 ++++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/src/common/futex.c b/src/common/futex.c
> index 7f07b11..0781867 100644
> --- a/src/common/futex.c
> +++ b/src/common/futex.c
> @@ -55,8 +55,11 @@ void futex_wait_update(int32_t *futex, int active)
>  {
>         if (active) {
>                 uatomic_set(futex, 1);
> -               futex_async(futex, FUTEX_WAKE,
> -                               INT_MAX, NULL, NULL, 0);
> +               if (futex_async(futex, FUTEX_WAKE,
> +                               INT_MAX, NULL, NULL, 0) < 0) {
> +                       PERROR("futex_async");
> +                       abort();
> +               }
>         } else {
>                 uatomic_set(futex, 0);
>         }
> @@ -84,10 +87,23 @@ void futex_nto1_wait(int32_t *futex)
>  {
>         cmm_smp_mb();
>
> -       if (uatomic_read(futex) == -1) {
> -               futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0);
> +       if (uatomic_read(futex) != -1)
> +               goto end;
> +       while (futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0)) {
> +               switch (errno) {
> +               case EWOULDBLOCK:
> +                       /* Value already changed. */
> +                       goto end;
> +               case EINTR:
> +                       /* Retry if interrupted by signal. */
> +                       break;  /* Get out of switch. */
> +               default:
> +                       /* Unexpected error. */
> +                       PERROR("futex_async");
> +                       abort();
> +               }
>         }
> -
> +end:
>         DBG("Futex n to 1 wait done");
>  }
>
> @@ -97,10 +113,13 @@ void futex_nto1_wait(int32_t *futex)
>  LTTNG_HIDDEN
>  void futex_nto1_wake(int32_t *futex)
>  {
> -       if (caa_unlikely(uatomic_read(futex) == -1)) {
> -               uatomic_set(futex, 0);
> -               futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0);
> +       if (caa_unlikely(uatomic_read(futex) != -1))
> +               goto end;
> +       uatomic_set(futex, 0);
> +       if (futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0) < 0) {
> +               PERROR("futex_async");
> +               abort();
>         }
> -
> +end:
>         DBG("Futex n to 1 wake done");
>  }
> --
> 2.1.4
>
>


-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20150710/4a522f65/attachment.html>


More information about the lttng-dev mailing list