From b2ca7e52f657c0987706e3f4200cd882ae86c339 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 30 Nov 2020 14:52:11 +0100 Subject: [PATCH] MINOR: task: remove __tasklet_remove_from_tasklet_list() This function is only used at a single place directly within the scheduler in run_tasks_from_lists() and it really ought not be called by anything else, regardless of what its comment says. Let's delete it, move the two lines directly into the call place, and take this opportunity to factor the atomic decrement on tasks_run_queue. A comment was added on the remaining one tasklet_remove_from_tasklet_list() to mention the risks in using it. (cherry picked from commit 2da4c316c2cb7b01f54ed1959e91d1799d13959c) Signed-off-by: Christopher Faulet (cherry picked from commit 9a0374aaaafefa07b80e761f97f0fcd7688dabf4) Signed-off-by: Willy Tarreau (cherry picked from commit e4480476c172b13e0bb072ef1afd31b359cc3917) [wt: needed for next fix; context hanges in 2.1, no run_tasks_from_lists(), single LIST_DEL location] Signed-off-by: Willy Tarreau --- include/proto/task.h | 13 ++----------- src/task.c | 4 +++- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/proto/task.h b/include/proto/task.h index f237d0d..c4e9ea1 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -270,18 +270,9 @@ static inline void tasklet_insert_into_tasklet_list(struct tasklet *tl) LIST_ADDQ(&sched->task_list, &tl->list); } -/* Remove the tasklet from the tasklet list. The tasklet MUST already be there. - * If unsure, use tasklet_remove_from_tasklet_list() instead. If used with a - * plain task, the caller must update the task_list_size. - * This should only be used by the thread that owns the tasklet, any other - * thread should use tasklet_cancel(). +/* Try to remove a tasklet from the list. This call is inherently racy and may + * only be performed on the thread that was supposed to dequeue this tasklet. */ -static inline void __tasklet_remove_from_tasklet_list(struct tasklet *t) -{ - LIST_DEL_INIT(&t->list); - _HA_ATOMIC_SUB(&tasks_run_queue, 1); -} - static inline void tasklet_remove_from_tasklet_list(struct tasklet *t) { if (MT_LIST_DEL((struct mt_list *)&t->list)) diff --git a/src/task.c b/src/task.c index 240c55b..a7bbb32 100644 --- a/src/task.c +++ b/src/task.c @@ -400,11 +400,13 @@ void process_runnable_tasks() void *ctx; struct task *(*process)(struct task *t, void *ctx, unsigned short state); + _HA_ATOMIC_SUB(&tasks_run_queue, 1); + t = (struct task *)LIST_ELEM(task_per_thread[tid].task_list.n, struct tasklet *, list); state = (t->state & TASK_SHARED_WQ) | TASK_RUNNING; state = _HA_ATOMIC_XCHG(&t->state, state); __ha_barrier_atomic_store(); - __tasklet_remove_from_tasklet_list((struct tasklet *)t); + LIST_DEL_INIT(&((struct tasklet *)t)->list); ti->flags &= ~TI_FL_STUCK; // this thread is still running activity[tid].ctxsw++; -- 1.7.10.4