]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: dynbuf: make the buffer wait queue per thread
authorWilly Tarreau <w@1wt.eu>
Sat, 20 Feb 2021 10:38:56 +0000 (11:38 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 20 Feb 2021 11:38:18 +0000 (12:38 +0100)
The buffer wait queue used to be global historically but this doest not
make any sense anymore given that the most common use case is to have
thread-local pools. Thus there's no point waking up waiters of other
threads after releasing an entry, as they won't benefit from it.

Let's move the queue head to the thread_info structure and use
ti->buffer_wq from now on.

include/haproxy/channel.h
include/haproxy/dynbuf.h
include/haproxy/tinfo-t.h
src/check.c
src/dynbuf.c
src/flt_spoe.c
src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c
src/stream.c

index de51d046789e2e24d5923d606799d056588ef0ba..812808c0e744f5eb257a4201ee9fe6d449568577 100644 (file)
@@ -852,7 +852,7 @@ static inline int channel_alloc_buffer(struct channel *chn, struct buffer_wait *
                return 1;
 
        if (!MT_LIST_ADDED(&wait->list))
-               MT_LIST_ADDQ(&buffer_wq, &wait->list);
+               MT_LIST_ADDQ(&ti->buffer_wq, &wait->list);
 
        return 0;
 }
index 2a7aa476817feb26b1c4fc64c045c943c899c67f..c26ad21f6343bce271e3cb56197a6b32192e3c3f 100644 (file)
@@ -35,7 +35,6 @@
 #include <haproxy/pool.h>
 
 extern struct pool_head *pool_head_buffer;
-extern struct mt_list buffer_wq;
 
 int init_buffer();
 void buffer_dump(FILE *o, struct buffer *b, int from, int to);
@@ -192,13 +191,13 @@ static inline struct buffer *b_alloc_margin(struct buffer *buf, int margin)
  * passing a buffer to oneself in case of failed allocations (e.g. need two
  * buffers, get one, fail, release it and wake up self again). In case of
  * normal buffer release where it is expected that the caller is not waiting
- * for a buffer, NULL is fine.
+ * for a buffer, NULL is fine. It will wake waiters on the current thread only.
  */
 void __offer_buffer(void *from, unsigned int threshold);
 
 static inline void offer_buffers(void *from, unsigned int threshold)
 {
-       if (!MT_LIST_ISEMPTY(&buffer_wq))
+       if (!MT_LIST_ISEMPTY(&ti->buffer_wq))
                __offer_buffer(from, threshold);
 }
 
index f3badbd88ef97fdd3649ee395f49d35ad24c7bd1..6dc0458519d4e78f00e7f412af8aaaecfca3ebac 100644 (file)
@@ -45,6 +45,8 @@ struct thread_info {
 #ifdef CONFIG_HAP_LOCAL_POOLS
        struct list pool_lru_head;                         /* oldest objects   */
 #endif
+       struct mt_list buffer_wq;  /* buffer waiters */
+
        /* pad to cache line (64B) */
        char __pad[0];            /* unused except to check remaining room */
        char __end[0] __attribute__((aligned(64)));
index a09c67a7deede25f387dd6a31c80348749decccc..ff4effa179edad229e22a2109eba7cab5d0afd51 100644 (file)
@@ -1019,7 +1019,7 @@ struct buffer *check_get_buf(struct check *check, struct buffer *bptr)
            unlikely((buf = b_alloc_margin(bptr, 0)) == NULL)) {
                check->buf_wait.target = check;
                check->buf_wait.wakeup_cb = check_buf_available;
-               MT_LIST_ADDQ(&buffer_wq, &check->buf_wait.list);
+               MT_LIST_ADDQ(&ti->buffer_wq, &check->buf_wait.list);
        }
        return buf;
 }
index ad2cde926533faaaa5276422040d09410895f44e..395fa8a97875b45c71968af3cd93e4ac161426fb 100644 (file)
 
 struct pool_head *pool_head_buffer;
 
-/* list of objects waiting for at least one buffer */
-struct mt_list buffer_wq = LIST_HEAD_INIT(buffer_wq);
-
 /* perform minimal intializations, report 0 in case of error, 1 if OK. */
 int init_buffer()
 {
        void *buffer;
+       int thr;
 
        pool_head_buffer = create_pool("buffer", global.tune.bufsize, MEM_F_SHARED|MEM_F_EXACT);
        if (!pool_head_buffer)
                return 0;
 
+       for (thr = 0; thr < MAX_THREADS; thr++)
+               MT_LIST_INIT(&ha_thread_info[thr].buffer_wq);
+
+
        /* The reserved buffer is what we leave behind us. Thus we always need
         * at least one extra buffer in minavail otherwise we'll end up waking
         * up tasks with no memory available, causing a lot of useless wakeups.
@@ -112,7 +114,7 @@ void __offer_buffer(void *from, unsigned int threshold)
         */
        avail = pool_head_buffer->allocated - pool_head_buffer->used - global.tune.reserved_bufs / 2;
 
-       mt_list_for_each_entry_safe(wait, &buffer_wq, list, elt1, elt2) {
+       mt_list_for_each_entry_safe(wait, &ti->buffer_wq, list, elt1, elt2) {
                if (avail <= threshold)
                        break;
 
index b9471d9170775abf10858d712a5ea87af5c81954..27a15b6c1685168d7b89371249a5f4785d22c2d2 100644 (file)
@@ -2828,7 +2828,7 @@ spoe_acquire_buffer(struct buffer *buf, struct buffer_wait *buffer_wait)
        if (b_alloc_margin(buf, global.tune.reserved_bufs))
                return 1;
 
-       MT_LIST_ADDQ(&buffer_wq, &buffer_wait->list);
+       MT_LIST_ADDQ(&ti->buffer_wq, &buffer_wait->list);
        return 0;
 }
 
index a2c1c86c6a3a2b25ecaa60007b4ddd588db3edad..2ff7aa9098965042a819d94b6664a6f1486cf1ed 100644 (file)
@@ -608,7 +608,7 @@ static inline struct buffer *fcgi_get_buf(struct fcgi_conn *fconn, struct buffer
            unlikely((buf = b_alloc_margin(bptr, 0)) == NULL)) {
                fconn->buf_wait.target = fconn;
                fconn->buf_wait.wakeup_cb = fcgi_buf_available;
-               MT_LIST_ADDQ(&buffer_wq, &fconn->buf_wait.list);
+               MT_LIST_ADDQ(&ti->buffer_wq, &fconn->buf_wait.list);
        }
        return buf;
 }
index 63339351f2088f89b1fcbf54b4694fae17fac25c..077f4ea2dce5fbfadb8393c360bcd636e0f3a675 100644 (file)
@@ -452,7 +452,7 @@ static inline struct buffer *h1_get_buf(struct h1c *h1c, struct buffer *bptr)
            unlikely((buf = b_alloc_margin(bptr, 0)) == NULL)) {
                h1c->buf_wait.target = h1c;
                h1c->buf_wait.wakeup_cb = h1_buf_available;
-               MT_LIST_ADDQ(&buffer_wq, &h1c->buf_wait.list);
+               MT_LIST_ADDQ(&ti->buffer_wq, &h1c->buf_wait.list);
        }
        return buf;
 }
index 21c14b8737270cec4afb65ff3f352103458b5821..cfa5f8c4d447607c2dd8b477627dc4edf40dd2db 100644 (file)
@@ -810,7 +810,7 @@ static inline struct buffer *h2_get_buf(struct h2c *h2c, struct buffer *bptr)
            unlikely((buf = b_alloc_margin(bptr, 0)) == NULL)) {
                h2c->buf_wait.target = h2c;
                h2c->buf_wait.wakeup_cb = h2_buf_available;
-               MT_LIST_ADDQ(&buffer_wq, &h2c->buf_wait.list);
+               MT_LIST_ADDQ(&ti->buffer_wq, &h2c->buf_wait.list);
        }
        return buf;
 }
index 9394ac0a74ef91eb06d390acf8ba93d576d35d85..d7472116232d6605ce7f2171ed9b50a590877495 100644 (file)
@@ -773,7 +773,7 @@ static int stream_alloc_work_buffer(struct stream *s)
        if (b_alloc_margin(&s->res.buf, 0))
                return 1;
 
-       MT_LIST_ADDQ(&buffer_wq, &s->buffer_wait.list);
+       MT_LIST_ADDQ(&ti->buffer_wq, &s->buffer_wait.list);
        return 0;
 }