]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: tasklet: properly compute the sleeping threads mask in tasklet_wakeup()
authorWilly Tarreau <w@1wt.eu>
Fri, 18 Oct 2019 06:45:41 +0000 (08:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 18 Oct 2019 07:00:26 +0000 (09:00 +0200)
The use of ~(1 << tid) to compute the sleeping_mask in tasklet_wakeup()
will result in breakage above 32 threads, because (1<<31) = 0xFFFFFFFF8000000,
and upper values will lead to theorically undefined results, but practically
will wrap over 0x1 to 0x80000000 again and indicate wrong sleeping masks. It
seems that the main visible effect maybe extra latency on some threads or
short CPU loops on others.

No backport is needed.

include/proto/task.h

index 2258448103d960c219961da907f1e03570ba07a4..6ec2846cdf00b2eb42d5c9bf3919087ca285c5e4 100644 (file)
@@ -236,8 +236,8 @@ static inline void tasklet_wakeup(struct tasklet *tl)
        } else {
                if (MT_LIST_ADDQ(&task_per_thread[tl->tid].shared_tasklet_list, (struct mt_list *)&tl->list) == 1) {
                        _HA_ATOMIC_ADD(&tasks_run_queue, 1);
-                       if (sleeping_thread_mask & (1 << tl->tid)) {
-                               _HA_ATOMIC_AND(&sleeping_thread_mask, ~(1 << tl->tid));
+                       if (sleeping_thread_mask & (1UL << tl->tid)) {
+                               _HA_ATOMIC_AND(&sleeping_thread_mask, ~(1UL << tl->tid));
                                wake_thread(tl->tid);
                        }
                }