Re: [PATCHES] Fix a few shortcomings in the tasklet code

2018-06-14 Thread Willy Tarreau
On Thu, Jun 14, 2018 at 04:27:04PM +0200, Olivier Houchard wrote:
> Attached are 2 patches that fix a few bugs in the tasklet code.
> It should have little incidence right now because tasklets are unused, but
> will be useful for later work.

Applied, thank you!

Willy



[PATCHES] Fix a few shortcomings in the tasklet code

2018-06-14 Thread Olivier Houchard
Hi,

Attached are 2 patches that fix a few bugs in the tasklet code.
It should have little incidence right now because tasklets are unused, but
will be useful for later work.

Regards,

Olivier
>From fd2838a8b4eae2d9801592889285ae221fc3a7cb Mon Sep 17 00:00:00 2001
From: Olivier Houchard 
Date: Fri, 8 Jun 2018 17:08:19 +0200
Subject: [PATCH 1/2] MINOR: tasks: Make sure we correctly init and deinit a
 tasklet.

Up until now, a tasklet couldn't be free'd while it was in the list, it is
no longer the case, so make sure we remove it from the list before freeing it.
To do so, we have to make sure we correctly initialize it, so use LIST_INIT,
instead of setting the pointers to NULL.
---
 include/proto/task.h | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/proto/task.h b/include/proto/task.h
index 760b368b..47f74d4e 100644
--- a/include/proto/task.h
+++ b/include/proto/task.h
@@ -229,6 +229,7 @@ static inline void task_insert_into_tasklet_list(struct 
task *t)
 static inline void task_remove_from_task_list(struct task *t)
 {
LIST_DEL(&((struct tasklet *)t)->list);
+   LIST_INIT(&((struct tasklet *)t)->list);
task_list_size[tid]--;
HA_ATOMIC_SUB(_run_queue, 1);
if (!TASK_IS_TASKLET(t)) {
@@ -270,7 +271,7 @@ static inline void tasklet_init(struct tasklet *t)
t->nice = -32768;
t->calls = 0;
t->state = 0;
-   t->list.p = t->list.n = NULL;
+   LIST_INIT(>list);
 }
 
 static inline struct tasklet *tasklet_new(void)
@@ -321,9 +322,10 @@ static inline void task_free(struct task *t)
t->process = NULL;
 }
 
-
 static inline void tasklet_free(struct tasklet *tl)
 {
+   LIST_DEL(>list);
+
pool_free(pool_head_tasklet, tl);
if (unlikely(stopping))
pool_flush(pool_head_tasklet);
-- 
2.14.3

>From e09a118d1a7b120e4529f56c2ba4458f5059f5ec Mon Sep 17 00:00:00 2001
From: Olivier Houchard 
Date: Thu, 14 Jun 2018 15:40:47 +0200
Subject: [PATCH 2/2] BUG/MINOR: tasklets: Just make sure we don't pass a
 tasklet to the handler.

We can't just set t to NULL if it's a tasklet, or we'd have a hard time
accessing to t->process, so just make sure we pass NULL as the first parameter
of t->process if it's a tasklet.
This should be a non-issue at this point, as tasklets aren't used yet.
---
 src/task.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/task.c b/src/task.c
index fb484073..815df24c 100644
--- a/src/task.c
+++ b/src/task.c
@@ -342,13 +342,11 @@ void process_runnable_tasks()
rqueue_size[tid]--;
t->calls++;
curr_task = (struct task *)t;
-   if (TASK_IS_TASKLET(t))
-   t = NULL;
if (likely(process == process_stream))
t = process_stream(t, ctx, state);
else {
if (t->process != NULL)
-   t = process(t, ctx, state);
+   t = process(TASK_IS_TASKLET(t) ? NULL : t, ctx, 
state);
else {
__task_free(t);
t = NULL;
-- 
2.14.3