From: Willy Tarreau Date: Fri, 31 Jan 2020 09:48:10 +0000 (+0100) Subject: MINOR: task: permanently flag tasklets waking themselves up X-Git-Tag: v2.2-dev2~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb238834da6bfe0d70a47d2d8fb0ecfe161b58a9;p=thirdparty%2Fhaproxy.git MINOR: task: permanently flag tasklets waking themselves up Commit a17664d829 ("MEDIUM: tasks: automatically requeue into the bulk queue an already running tasklet") tried to inflict a penalty to self-requeuing tasks/tasklets which correspond to those involved in large, high-latency data transfers, for the benefit of all other processing which requires a low latency. However, it turns out that while it ought to do this on a case-by-case basis, basing itself on the RUNNING flag isn't accurate because this flag doesn't leave for tasklets, so we'd rather need a distinct flag to tag such tasklets. This commit introduces TASK_SELF_WAKING to mark tasklets acting like this. For now it's still set when TASK_RUNNING is present but this will have to change. The flag is kept across wakeups. --- diff --git a/include/proto/task.h b/include/proto/task.h index ca963a1d36..53119b9d0d 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -245,10 +245,16 @@ static inline void tasklet_wakeup(struct tasklet *tl) if (likely(tl->tid < 0)) { /* this tasklet runs on the caller thread */ if (LIST_ISEMPTY(&tl->list)) { - if (tl->state & TASK_RUNNING) + if (tl->state & TASK_SELF_WAKING) { LIST_ADDQ(&task_per_thread[tid].tasklets[TL_BULK], &tl->list); - else + } + else if (tl->state & TASK_RUNNING) { + _HA_ATOMIC_OR(&tl->state, TASK_SELF_WAKING); + LIST_ADDQ(&task_per_thread[tid].tasklets[TL_BULK], &tl->list); + } + else { LIST_ADDQ(&task_per_thread[tid].tasklets[TL_URGENT], &tl->list); + } _HA_ATOMIC_ADD(&tasks_run_queue, 1); } } else { diff --git a/include/types/task.h b/include/types/task.h index 5f7ae61e86..6ca97671f0 100644 --- a/include/types/task.h +++ b/include/types/task.h @@ -36,6 +36,7 @@ #define TASK_QUEUED 0x0004 /* The task has been (re-)added to the run queue */ #define TASK_SHARED_WQ 0x0008 /* The task's expiration may be updated by other * threads, must be set before first queue/wakeup */ +#define TASK_SELF_WAKING 0x0010 /* task/tasklet found waking itself */ #define TASK_WOKEN_INIT 0x0100 /* woken up for initialisation purposes */ #define TASK_WOKEN_TIMER 0x0200 /* woken up because of expired timer */ diff --git a/src/task.c b/src/task.c index 3eaa9b4f6a..f1f36a914f 100644 --- a/src/task.c +++ b/src/task.c @@ -329,7 +329,7 @@ static int run_tasks_from_list(struct list *list, int max) while (done < max && !LIST_ISEMPTY(list)) { t = (struct task *)LIST_ELEM(list->n, struct tasklet *, list); - state = (t->state & TASK_SHARED_WQ) | TASK_RUNNING; + state = (t->state & (TASK_SHARED_WQ|TASK_SELF_WAKING)) | TASK_RUNNING; state = _HA_ATOMIC_XCHG(&t->state, state); __ha_barrier_atomic_store(); __tasklet_remove_from_tasklet_list((struct tasklet *)t);