From: Willy Tarreau Date: Sat, 21 Mar 2026 14:58:59 +0000 (+0000) Subject: MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY X-Git-Tag: v3.4-dev8~151 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=282b9b7d167cff0d89993a10aacd4f9f9149d9e6;p=thirdparty%2Fhaproxy.git MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY Self-waking tasklets are currently punished and go to the BULK list. However it's a problem with muxes or the stick-table purge that just yield and wake themselves up to limit the latency they cause to the rest of the process, because by doing so to help others, they punish themselves. Let's check if any TASK_WOKEN_ANY flag is present on the tasklet and stop sending tasks presenting such a flag to TL_BULK. Since tasklet_wakeup() by default passes TASK_WOKEN_OTHER, it means that such tasklets will no longer be punished. However, tasks which only want a best-effort wakeup can simply pass 0. It's worth noting that a comparison was made between going into TL_BULK at all and only setting the TASK_SELF_WAKING flag, and it shows that the average latencies are ~10% better when entirely avoiding TL_BULK in this case. --- diff --git a/src/task.c b/src/task.c index 4761e7b7a..7d0a1db9c 100644 --- a/src/task.c +++ b/src/task.c @@ -147,7 +147,7 @@ void __tasklet_wakeup_on(struct tasklet *tl, int thr) LIST_APPEND(&th_ctx->tasklets[TL_BULK], &tl->list); th_ctx->tl_class_mask |= 1 << TL_BULK; } - else if ((struct task *)tl == th_ctx->current) { + else if ((struct task *)tl == th_ctx->current && !(tl->state & TASK_WOKEN_ANY)) { LIST_APPEND(&th_ctx->tasklets[TL_BULK], &tl->list); th_ctx->tl_class_mask |= 1 << TL_BULK; } @@ -185,7 +185,7 @@ struct list *__tasklet_wakeup_after(struct list *head, struct tasklet *tl) LIST_INSERT(&th_ctx->tasklets[TL_BULK], &tl->list); th_ctx->tl_class_mask |= 1 << TL_BULK; } - else if ((struct task *)tl == th_ctx->current) { + else if ((struct task *)tl == th_ctx->current && !(tl->state & TASK_WOKEN_ANY)) { LIST_INSERT(&th_ctx->tasklets[TL_BULK], &tl->list); th_ctx->tl_class_mask |= 1 << TL_BULK; }