]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: dynbuf: provide a b_dequeue() variant for multi-thread
authorWilly Tarreau <w@1wt.eu>
Tue, 14 May 2024 17:19:23 +0000 (19:19 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 15 May 2024 17:37:12 +0000 (19:37 +0200)
In order to forcefully unregister a buffer waiter during an inter-thread
takeover under isolation, we'll need to that the function works without
th_ctx but the target thread's ctx instead. Let's implement this by
passing the target thread as an argument. Now b_dequeue() simply calls
this one with tid. It's OK it's not on that critical a path, especially
since the list has been checked for existence before performing the call.

include/haproxy/dynbuf.h

index 8a72b76be8c0c09d72faa03643047ff096a890c4..4a6595d3cc2201914d4d5639dfe30a715986d992 100644 (file)
@@ -217,30 +217,40 @@ static inline int b_queue(enum dynbuf_crit crit, struct buffer_wait *bw, void *c
        return b_requeue(crit, bw);
 }
 
-/* Dequeues bw element <bw> from its list and updates the bufq_map if if was
- * the last element. All users of buffer_wait should use this to dequeue (e.g.
- * when killing a pending request on timeout) so as to make sure that we keep
- * consistency between the list heads and the bitmap.
+/* Dequeues bw element <bw> from its list at for thread <thr> and updates the
+ * thread's bufq_map if it was the last element. The element is assumed to be
+ * in a list (it's the caller's job to test it). This is only meant to really
+ * be used either by the owner thread or under thread isolation. You should
+ * use b_dequeue() instead.
  */
-static inline void b_dequeue(struct buffer_wait *bw)
+static inline void _b_dequeue(struct buffer_wait *bw, int thr)
 {
+       struct thread_ctx *ctx = &ha_thread_ctx[thr];
        uint q;
 
-       if (likely(!LIST_INLIST(&bw->list)))
-               return;
-
        /* trick: detect if we're the last one and pointing to a root, so we
         * can figure the queue number since the root belongs to an array.
         */
        if (LIST_ATMOST1(&bw->list)) {
                /* OK then which root? */
-               q = bw->list.n - &th_ctx->buffer_wq[0];
+               q = bw->list.n - &ctx->buffer_wq[0];
                BUG_ON_HOT(q >= DYNBUF_NBQ);
-               th_ctx->bufq_map &= ~(1 << q);
+               ctx->bufq_map &= ~(1 << q);
        }
        LIST_DEL_INIT(&bw->list);
 }
 
+/* Dequeues bw element <bw> from its list and updates the bufq_map if if was
+ * the last element. All users of buffer_wait should use this to dequeue (e.g.
+ * when killing a pending request on timeout) so as to make sure that we keep
+ * consistency between the list heads and the bitmap.
+ */
+static inline void b_dequeue(struct buffer_wait *bw)
+{
+       if (unlikely(LIST_INLIST(&bw->list)))
+               _b_dequeue(bw, tid);
+}
+
 #endif /* _HAPROXY_DYNBUF_H */
 
 /*