BUG/MAJOR: tasks: Use the TASK_GLOBAL flag to know if we're in the global rq.

In task_unlink_rq, to decide if we should logk the global runqueue lock,
use the TASK_GLOBAL flag instead of relying on t->thread_mask being tid_bit,
as it could be so while still being in the global runqueue if another thread
woke that task for us.

This should be backported to 1.9.
This commit is contained in:
Olivier Houchard 2019-03-14 16:14:04 +01:00 committed by Olivier Houchard
parent 237985b228
commit 1d7f37a2cb

View File

@ -225,14 +225,16 @@ static inline struct task *__task_unlink_rq(struct task *t)
*/ */
static inline struct task *task_unlink_rq(struct task *t) static inline struct task *task_unlink_rq(struct task *t)
{ {
if (t->thread_mask != tid_bit) int is_global = t->state & TASK_GLOBAL;
if (is_global)
HA_SPIN_LOCK(TASK_RQ_LOCK, &rq_lock); HA_SPIN_LOCK(TASK_RQ_LOCK, &rq_lock);
if (likely(task_in_rq(t))) { if (likely(task_in_rq(t))) {
if (&t->rq == rq_next) if (&t->rq == rq_next)
rq_next = eb32sc_next(rq_next, tid_bit); rq_next = eb32sc_next(rq_next, tid_bit);
__task_unlink_rq(t); __task_unlink_rq(t);
} }
if (t->thread_mask != tid_bit) if (is_global)
HA_SPIN_UNLOCK(TASK_RQ_LOCK, &rq_lock); HA_SPIN_UNLOCK(TASK_RQ_LOCK, &rq_lock);
return t; return t;
} }