From e5d79bccc0641ba26bb78ae029cafb4e17e6b13f Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 22 Jul 2020 14:29:42 +0200
Subject: [PATCH] MINOR: tasks/debug: add a few BUG_ON() to detect use of wrong
 timer queue

This aims at catching calls to task_unlink_wq() performed by the wrong
thread based on the shared status for the task, as well as calls to
__task_queue() with the wrong timer queue being used based on the task's
capabilities. This will at least help eliminate some hypothesis during
debugging sessions when suspecting that a wrong thread has attempted to
queue a task at the wrong place.
---
 include/haproxy/task.h | 1 +
 src/task.c             | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/include/haproxy/task.h b/include/haproxy/task.h
index 56fd50de6..820c2f1dd 100644
--- a/include/haproxy/task.h
+++ b/include/haproxy/task.h
@@ -221,6 +221,7 @@ static inline struct task *task_unlink_wq(struct task *t)
 
 	if (likely(task_in_wq(t))) {
 		locked = t->state & TASK_SHARED_WQ;
+		BUG_ON(!locked && t->thread_mask != tid_bit);
 		if (locked)
 			HA_RWLOCK_WRLOCK(TASK_WQ_LOCK, &wq_lock);
 		__task_unlink_wq(t);
diff --git a/src/task.c b/src/task.c
index 449857806..c91316cbb 100644
--- a/src/task.c
+++ b/src/task.c
@@ -192,6 +192,12 @@ void __task_wakeup(struct task *t, struct eb_root *root)
  */
 void __task_queue(struct task *task, struct eb_root *wq)
 {
+#ifdef USE_THREAD
+	BUG_ON((wq == &timers && !(task->state & TASK_SHARED_WQ)) ||
+	       (wq == &sched->timers && (task->state & TASK_SHARED_WQ)) ||
+	       (wq != &timers && wq != &sched->timers));
+#endif
+
 	if (likely(task_in_wq(task)))
 		__task_unlink_wq(task);