From: Willy Tarreau Date: Tue, 14 May 2024 17:19:23 +0000 (+0200) Subject: MINOR: dynbuf: provide a b_dequeue() variant for multi-thread X-Git-Tag: v3.0-dev12~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b0349cf2deea0594f73035ecf18b7054cb7a52d7;p=thirdparty%2Fhaproxy.git MINOR: dynbuf: provide a b_dequeue() variant for multi-thread 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. --- diff --git a/include/haproxy/dynbuf.h b/include/haproxy/dynbuf.h index 8a72b76be8..4a6595d3cc 100644 --- a/include/haproxy/dynbuf.h +++ b/include/haproxy/dynbuf.h @@ -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 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 from its list at for thread 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 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 */ /*