]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: tasks: Keep the TASK_RUNNING flag until queued
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 7 May 2026 11:14:16 +0000 (13:14 +0200)
committerOlivier Houchard <cognet@ci0.org>
Mon, 11 May 2026 14:17:40 +0000 (16:17 +0200)
In task_schedule(), it is not enough to get the TASK_RUNNING flag before
setting the expire field, we also have to keep it while queueing the
taks, otherwise the task may run in the meanwhile and set expire to 0,
triggering the BUG_ON() in __task_queue() again. So now, only drop the
running flag once it's done.

This should be backported up to 2.8.

include/haproxy/task.h

index 02d98156bd2c4ba7252f2264b727a520ab041d03..419d7749f947e1a9c168f9935b4eb7f35b9e0e66 100644 (file)
@@ -736,7 +736,6 @@ static inline void _task_schedule(struct task *task, int when, const struct ha_c
                        when = tick_first(when, task->expire);
 
                task->expire = when;
-               task_drop_running(task, 0);
                if (!task_in_wq(task) || tick_is_lt(task->expire, task->wq.key)) {
                        if (likely(caller)) {
                                caller = HA_ATOMIC_XCHG(&task->caller, caller);
@@ -747,6 +746,7 @@ static inline void _task_schedule(struct task *task, int when, const struct ha_c
                        }
                        __task_queue(task, &tg_ctx->timers);
                }
+               task_drop_running(task, 0);
                HA_RWLOCK_WRUNLOCK(TASK_WQ_LOCK, &wq_lock);
        } else
 #endif