Commit d7961998 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

lock: Restore ability to abort on futex waiting

In commit 71cc2733
I occasionally dropped the ability to abort on waiting
(because we used signed -1 value to inform waiters that
something is wrong and waiting should be aborted, but
the type was changed to unsigned one and as result
this condition never triggers).

So to resolve it futex_abort_and_wake() is added and
should be used explicitly where appropriate instead
if signess hack.
Reported-by: 's avatarAndrew Vagin <avagin@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarAndrew Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 2a33c4d5
...@@ -1140,7 +1140,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) ...@@ -1140,7 +1140,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
pr_err("%d killed by signal %d\n", pr_err("%d killed by signal %d\n",
siginfo->si_pid, siginfo->si_status); siginfo->si_pid, siginfo->si_status);
futex_set_and_wake(&task_entries->nr_in_progress, -1); futex_abort_and_wake(&task_entries->nr_in_progress);
} }
static int restore_task_with_children(void *_arg) static int restore_task_with_children(void *_arg)
......
...@@ -15,6 +15,9 @@ typedef struct { ...@@ -15,6 +15,9 @@ typedef struct {
u32 raw; u32 raw;
} futex_t; } futex_t;
#define FUTEX_ABORT_FLAG (0x80000000)
#define FUTEX_ABORT_RAW (-1U)
/* Get current futex @f value */ /* Get current futex @f value */
static inline u32 futex_get(futex_t *f) static inline u32 futex_get(futex_t *f)
{ {
...@@ -37,7 +40,8 @@ static inline void futex_set(futex_t *f, u32 v) ...@@ -37,7 +40,8 @@ static inline void futex_set(futex_t *f, u32 v)
\ \
while (1) { \ while (1) { \
tmp = (__f)->raw; \ tmp = (__f)->raw; \
if (tmp __cond (__v)) \ if ((tmp & FUTEX_ABORT_FLAG) || \
(tmp __cond (__v))) \
break; \ break; \
ret = sys_futex(&(__f)->raw, FUTEX_WAIT,\ ret = sys_futex(&(__f)->raw, FUTEX_WAIT,\
tmp, NULL, NULL, 0); \ tmp, NULL, NULL, 0); \
...@@ -52,6 +56,13 @@ static inline void futex_set_and_wake(futex_t *f, u32 v) ...@@ -52,6 +56,13 @@ static inline void futex_set_and_wake(futex_t *f, u32 v)
BUG_ON(sys_futex(&f->raw, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0); BUG_ON(sys_futex(&f->raw, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0);
} }
/* Mark futex @f as wait abort needed and wake up all waiters */
static inline void futex_abort_and_wake(futex_t *f)
{
BUILD_BUG_ON(!(FUTEX_ABORT_RAW & FUTEX_ABORT_FLAG));
futex_set_and_wake(f, FUTEX_ABORT_RAW);
}
/* Decrement futex @f value and wake up all waiters */ /* Decrement futex @f value and wake up all waiters */
static inline void futex_dec_and_wake(futex_t *f) static inline void futex_dec_and_wake(futex_t *f)
{ {
......
...@@ -46,7 +46,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) ...@@ -46,7 +46,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
write_string(" killed by signal "); write_string(" killed by signal ");
write_num_n(siginfo->si_status); write_num_n(siginfo->si_status);
futex_set_and_wake(&task_entries->nr_in_progress, -1); futex_abort_and_wake(&task_entries->nr_in_progress);
/* sa_restorer may be unmaped, so we can't go back to userspace*/ /* sa_restorer may be unmaped, so we can't go back to userspace*/
sys_kill(sys_getpid(), SIGSTOP); sys_kill(sys_getpid(), SIGSTOP);
sys_exit(1); sys_exit(1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment