]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ring/applet: turn the wait_entry list to an mt_list instead
authorWilly Tarreau <w@1wt.eu>
Wed, 28 Feb 2024 16:04:40 +0000 (17:04 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 25 Mar 2024 17:34:19 +0000 (17:34 +0000)
Rings are keeping a lock only for the list, which apparently doesn't
need anything more than an mt_list, so let's first turn it into that
before dropping the lock. There should be no visible effect.

include/haproxy/applet-t.h
include/haproxy/dns_ring-t.h
include/haproxy/ring-t.h
src/applet.c
src/dns.c
src/dns_ring.c
src/ring.c
src/sink.c

index b730233b0a7b2caf6e6a9cc5572b642542a786c0..ab8746e28acc02cd3220fbb5ba4a14bbef22e35a 100644 (file)
@@ -97,7 +97,7 @@ struct appctx {
        struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */
        struct task *t;                  /* task associated to the applet */
        struct freq_ctr call_rate;       /* appctx call rate */
-       struct list wait_entry;          /* entry in a list of waiters for an event (e.g. ring events) */
+       struct mt_list wait_entry;       /* entry in a list of waiters for an event (e.g. ring events) */
 
        /* The pointer seen by application code is appctx->svcctx. In 2.7 the
         * anonymous union and the "ctx" struct disappeared, and the struct
index 765231b2678661273e872284e666848294c1c716..2c15784bfa2983f5d3abbf2f6987e2e32414affb 100644 (file)
@@ -95,7 +95,7 @@
 
 struct dns_ring {
        struct buffer buf;   // storage area
-       struct list waiters; // list of waiters, for now, CLI "show event"
+       struct mt_list waiters; // list of waiters, for now, CLI "show event"
        __decl_thread(HA_RWLOCK_T lock);
        int readers_count;
 };
index b719c9cad6b8886b5dffb80a00f66a765baa0b12..3624a003d508c716c560e743c04a50edce7907f8 100644 (file)
@@ -121,7 +121,7 @@ struct ring_storage {
 /* this is the ring definition, config, waiters etc */
 struct ring {
        struct ring_storage *storage; // the mapped part
-       struct list waiters;          // list of waiters, for now, CLI "show event"
+       struct mt_list waiters;       // list of waiters, for now, CLI "show event"
        __decl_thread(HA_RWLOCK_T lock);
        int readers_count;
        uint flags;          // RING_FL_*
index 59838648f0705d30c1ad1055247c99cdb6a38ead..6774e1a884211cd39d4c703554748927c340a038 100644 (file)
@@ -239,7 +239,7 @@ struct appctx *appctx_new_on(struct applet *applet, struct sedesc *sedesc, int t
                goto fail_appctx;
        }
 
-       LIST_INIT(&appctx->wait_entry);
+       MT_LIST_INIT(&appctx->wait_entry);
        appctx->obj_type = OBJ_TYPE_APPCTX;
        appctx->applet = applet;
        appctx->sess = NULL;
index fddc88bb33417ecd7bf76a929bea21f66664c785..2a4c4650fd58f0be63e54bfc0de5c28736f9ef5f 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -471,7 +471,7 @@ static void dns_session_io_handler(struct appctx *appctx)
        }
 
        HA_RWLOCK_WRLOCK(DNS_LOCK, &ring->lock);
-       LIST_DEL_INIT(&appctx->wait_entry);
+       MT_LIST_DELETE(&appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(DNS_LOCK, &ring->lock);
 
        HA_RWLOCK_RDLOCK(DNS_LOCK, &ring->lock);
@@ -633,8 +633,8 @@ static void dns_session_io_handler(struct appctx *appctx)
        if (ret) {
                /* let's be woken up once new request to write arrived */
                HA_RWLOCK_WRLOCK(DNS_LOCK, &ring->lock);
-               BUG_ON(LIST_INLIST(&appctx->wait_entry));
-               LIST_APPEND(&ring->waiters, &appctx->wait_entry);
+               BUG_ON(MT_LIST_INLIST(&appctx->wait_entry));
+               MT_LIST_APPEND(&ring->waiters, &appctx->wait_entry);
                HA_RWLOCK_WRUNLOCK(DNS_LOCK, &ring->lock);
                applet_have_no_more_data(appctx);
        }
@@ -797,7 +797,7 @@ void dns_session_free(struct dns_session *ds)
        BUG_ON(!LIST_ISEMPTY(&ds->list));
        BUG_ON(!LIST_ISEMPTY(&ds->waiter));
        BUG_ON(!LIST_ISEMPTY(&ds->queries));
-       BUG_ON(!LIST_ISEMPTY(&ds->ring.waiters));
+       BUG_ON(!MT_LIST_ISEMPTY(&ds->ring.waiters));
        BUG_ON(!eb_is_empty(&ds->query_ids));
        pool_free(dns_session_pool, ds);
 }
@@ -849,7 +849,7 @@ static void dns_session_release(struct appctx *appctx)
         * to retry a conn with a different appctx.
         */
        HA_RWLOCK_WRLOCK(DNS_LOCK, &ds->ring.lock);
-       LIST_DEL_INIT(&appctx->wait_entry);
+       MT_LIST_DELETE(&appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(DNS_LOCK, &ds->ring.lock);
 
        dss = ds->dss;
index 04a29faf14c6a2ff7d97bbf027c6a69b72f2c987..01ce59331ce4bfe1f2741d98a16d925a6e3f7e90 100644 (file)
@@ -34,7 +34,7 @@
 void dns_ring_init(struct dns_ring *ring, void *area, size_t size)
 {
        HA_RWLOCK_INIT(&ring->lock);
-       LIST_INIT(&ring->waiters);
+       MT_LIST_INIT(&ring->waiters);
        ring->readers_count = 0;
        ring->buf = b_make(area, size, 0, 0);
        /* write the initial RC byte */
@@ -94,6 +94,7 @@ ssize_t dns_ring_write(struct dns_ring *ring, size_t maxlen, const struct ist pf
        size_t lenlen;
        uint64_t dellen;
        int dellenlen;
+       struct mt_list *elt1, elt2;
        ssize_t sent = 0;
        int i;
 
@@ -165,7 +166,7 @@ ssize_t dns_ring_write(struct dns_ring *ring, size_t maxlen, const struct ist pf
        sent = lenlen + totlen + 1;
 
        /* notify potential readers */
-       list_for_each_entry(appctx, &ring->waiters, wait_entry)
+       mt_list_for_each_entry_safe(appctx, &ring->waiters, wait_entry, elt1, elt2)
                appctx_wakeup(appctx);
 
  done_buf:
@@ -209,7 +210,7 @@ void dns_ring_detach_appctx(struct dns_ring *ring, struct appctx *appctx, size_t
                        ofs -= b_head_ofs(&ring->buf);
 
                BUG_ON(ofs >= b_size(&ring->buf));
-               LIST_DEL_INIT(&appctx->wait_entry);
+               MT_LIST_DELETE(&appctx->wait_entry);
                HA_ATOMIC_DEC(b_peek(&ring->buf, ofs));
        }
        HA_ATOMIC_DEC(&ring->readers_count);
index 62dfa8cdd30abf513d21203b51329ef79a2298b3..613c8c6b918b084fff0666d8745e39ea49d9f420 100644 (file)
@@ -46,7 +46,7 @@ struct show_ring_ctx {
 void ring_init(struct ring *ring, void *area, size_t size, int reset)
 {
        HA_RWLOCK_INIT(&ring->lock);
-       LIST_INIT(&ring->waiters);
+       MT_LIST_INIT(&ring->waiters);
        ring->readers_count = 0;
        ring->flags = 0;
        ring->storage = area;
@@ -176,7 +176,6 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz
        size_t ring_size;
        char *ring_area;
        struct ist v1, v2;
-       struct appctx *appctx;
        size_t msglen = 0;
        size_t lenlen;
        size_t needed;
@@ -340,8 +339,11 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz
 
        /* notify potential readers */
        if (sent && HA_ATOMIC_LOAD(&ring->readers_count)) {
+               struct mt_list *elt1, elt2;
+               struct appctx *appctx;
+
                HA_RWLOCK_RDLOCK(RING_LOCK, &ring->lock);
-               list_for_each_entry(appctx, &ring->waiters, wait_entry)
+               mt_list_for_each_entry_safe(appctx, &ring->waiters, wait_entry, elt1, elt2)
                        appctx_wakeup(appctx);
                HA_RWLOCK_RDUNLOCK(RING_LOCK, &ring->lock);
        }
@@ -378,13 +380,15 @@ void ring_detach_appctx(struct ring *ring, struct appctx *appctx, size_t ofs)
                return;
 
        HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
+       HA_ATOMIC_DEC(&ring->readers_count);
+
        if (ofs != ~0) {
                /* reader was still attached */
                uint8_t *area = (uint8_t *)ring_area(ring);
                uint8_t readers;
 
                BUG_ON(ofs >= ring_size(ring));
-               LIST_DEL_INIT(&appctx->wait_entry);
+               MT_LIST_DELETE(&appctx->wait_entry);
 
                /* dec readers count */
                do {
@@ -392,7 +396,6 @@ void ring_detach_appctx(struct ring *ring, struct appctx *appctx, size_t ofs)
                } while ((readers > RING_MAX_READERS ||
                          !_HA_ATOMIC_CAS(area + ofs, &readers, readers - 1)) && __ha_cpu_relax());
        }
-       HA_ATOMIC_DEC(&ring->readers_count);
        HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
 }
 
@@ -564,7 +567,7 @@ int cli_io_handler_show_ring(struct appctx *appctx)
                return 1;
 
        HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-       LIST_DEL_INIT(&appctx->wait_entry);
+       MT_LIST_DELETE(&appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
 
        ret = ring_dispatch_messages(ring, appctx, &ctx->ofs, &last_ofs, ctx->flags, applet_append_line);
@@ -576,7 +579,7 @@ int cli_io_handler_show_ring(struct appctx *appctx)
                if (!sc_oc(sc)->output && !(sc->flags & SC_FL_SHUT_DONE)) {
                        /* let's be woken up once new data arrive */
                        HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-                       LIST_APPEND(&ring->waiters, &appctx->wait_entry);
+                       MT_LIST_APPEND(&ring->waiters, &appctx->wait_entry);
                        ofs = ring_tail(ring);
                        HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
                        if (ofs != last_ofs) {
index b5c681ad72939585193d62d1f74d4bece2e47326..52b9d2a1e2a60d0a7417f33f2b4462305af4fa84 100644 (file)
@@ -383,7 +383,7 @@ static void sink_forward_io_handler(struct appctx *appctx)
        }
 
        HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-       LIST_DEL_INIT(&appctx->wait_entry);
+       MT_LIST_DELETE(&appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
 
        ret = ring_dispatch_messages(ring, appctx, &sft->ofs, &last_ofs, 0, applet_append_line);
@@ -391,7 +391,7 @@ static void sink_forward_io_handler(struct appctx *appctx)
        if (ret) {
                /* let's be woken up once new data arrive */
                HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-               LIST_APPEND(&ring->waiters, &appctx->wait_entry);
+               MT_LIST_APPEND(&ring->waiters, &appctx->wait_entry);
                ofs = ring_tail(ring);
                HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
                if (ofs != last_ofs) {
@@ -452,14 +452,14 @@ static void sink_forward_oc_io_handler(struct appctx *appctx)
        }
 
        HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-       LIST_DEL_INIT(&appctx->wait_entry);
+       MT_LIST_DELETE(&appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
 
        ret = ring_dispatch_messages(ring, appctx, &sft->ofs, &last_ofs, 0, syslog_applet_append_event);
        if (ret) {
                /* let's be woken up once new data arrive */
                HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
-               LIST_APPEND(&ring->waiters, &appctx->wait_entry);
+               MT_LIST_APPEND(&ring->waiters, &appctx->wait_entry);
                ofs = ring_tail(ring);
                HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
                if (ofs != last_ofs) {
@@ -492,7 +492,7 @@ void __sink_forward_session_deinit(struct sink_forward_target *sft)
                return;
 
        HA_RWLOCK_WRLOCK(RING_LOCK, &sink->ctx.ring->lock);
-       LIST_DEL_INIT(&sft->appctx->wait_entry);
+       MT_LIST_DELETE(&sft->appctx->wait_entry);
        HA_RWLOCK_WRUNLOCK(RING_LOCK, &sink->ctx.ring->lock);
 
        sft->appctx = NULL;