]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy; replace the spinlock with an rwlock
authorWilly Tarreau <w@1wt.eu>
Tue, 20 Oct 2020 15:24:27 +0000 (17:24 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 22 Oct 2020 15:32:28 +0000 (17:32 +0200)
This is an anticipation of finer grained locking for the queues. For now
all lock places take a write lock so that there is no difference at all
with previous code.

include/haproxy/proxy-t.h
src/haproxy.c
src/listener.c
src/proxy.c
src/queue.c
src/server.c

index 1e59373c9389395c1ce3159d806570dac7ebfccc..41aca9d39286cf8dc1fc05499361d4194dad70b0 100644 (file)
@@ -321,7 +321,7 @@ struct proxy {
                int clientfin;                  /* timeout to apply to client half-closed connections */
                int serverfin;                  /* timeout to apply to server half-closed connections */
        } timeout;
-       __decl_thread(HA_SPINLOCK_T lock);      /* may be taken under the server's lock */
+       __decl_thread(HA_RWLOCK_T lock);        /* may be taken under the server's lock */
 
        char *id, *desc;                        /* proxy id (name) and description */
        struct eb_root pendconns;               /* pending connections with no server assigned yet */
index cc5cc1aeac4dab846c25a9e4ee048b0198908123..3e6fd18f72992eeca1b25c91e044f931021b959f 100644 (file)
@@ -2697,7 +2697,7 @@ void deinit(void)
                p0 = p;
                p = p->next;
                HA_RWLOCK_DESTROY(&p0->lbprm.lock);
-               HA_SPIN_DESTROY(&p0->lock);
+               HA_RWLOCK_DESTROY(&p0->lock);
                free(p0);
        }/* end while(p) */
 
index 7061f9a9daa3c0f752d74d8edc944da36fbf44cc..1947fdb5383345bc8735118ff9fcaa92f40e9dcb 100644 (file)
@@ -295,7 +295,7 @@ void stop_listener(struct listener *l, int lpx, int lpr, int lli)
        }
 
        if (!lpx)
-               HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+               HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 
        if (!lpr)
                HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
@@ -319,7 +319,7 @@ void stop_listener(struct listener *l, int lpx, int lpr, int lli)
                HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
 
        if (!lpx)
-               HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+               HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 }
 
 /* default function called to suspend a listener: it simply passes the call to
index 790d4d08025ec1898046b7581fc4b9d01f590a3e..fa17eebb6ce9a1cf1922ea62af56e6e66de8fba1 100644 (file)
@@ -1041,7 +1041,7 @@ void init_new_proxy(struct proxy *p)
        /* Default to only allow L4 retries */
        p->retry_type = PR_RE_CONN_FAILED;
 
-       HA_SPIN_INIT(&p->lock);
+       HA_RWLOCK_INIT(&p->lock);
 }
 
 /* to be called under the proxy lock after stopping some listeners. This will
@@ -1310,7 +1310,7 @@ void stop_proxy(struct proxy *p)
 {
        struct listener *l;
 
-       HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
 
        list_for_each_entry(l, &p->conf.listeners, by_fe)
                stop_listener(l, 1, 0, 0);
@@ -1320,7 +1320,7 @@ void stop_proxy(struct proxy *p)
                p->disabled = 1;
        }
 
-       HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
 }
 
 /* This function resumes listening on the specified proxy. It scans all of its
@@ -1559,14 +1559,14 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
        /* note: we still lock since we have to be certain that nobody is
         * dumping the output while we free.
         */
-       HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &proxy->lock);
        if (is_back) {
                es = HA_ATOMIC_XCHG(&proxy->invalid_rep, es);
        } else {
                es = HA_ATOMIC_XCHG(&proxy->invalid_req, es);
        }
        free(es);
-       HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &proxy->lock);
 }
 
 /* Configure all proxies which lack a maxconn setting to use the global one by
@@ -1936,9 +1936,9 @@ static int cli_parse_enable_dyncookie_backend(char **args, char *payload, struct
        /* Note: this lock is to make sure this doesn't change while another
         * thread is in srv_set_dyncookie().
         */
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
        px->ck_opts |= PR_CK_DYNAMIC;
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        for (s = px->srv; s != NULL; s = s->next) {
                HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -1968,9 +1968,9 @@ static int cli_parse_disable_dyncookie_backend(char **args, char *payload, struc
        /* Note: this lock is to make sure this doesn't change while another
         * thread is in srv_set_dyncookie().
         */
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
        px->ck_opts &= ~PR_CK_DYNAMIC;
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        for (s = px->srv; s != NULL; s = s->next) {
                HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -2011,10 +2011,10 @@ static int cli_parse_set_dyncookie_key_backend(char **args, char *payload, struc
        /* Note: this lock is to make sure this doesn't change while another
         * thread is in srv_set_dyncookie().
         */
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
        free(px->dyncookie_key);
        px->dyncookie_key = newkey;
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        for (s = px->srv; s != NULL; s = s->next) {
                HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -2052,7 +2052,7 @@ static int cli_parse_set_maxconn_frontend(char **args, char *payload, struct app
        /* OK, the value is fine, so we assign it to the proxy and to all of
         * its listeners. The blocked ones will be dequeued.
         */
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 
        px->maxconn = v;
        list_for_each_entry(l, &px->conf.listeners, by_fe) {
@@ -2063,7 +2063,7 @@ static int cli_parse_set_maxconn_frontend(char **args, char *payload, struct app
        if (px->maxconn > px->feconn)
                dequeue_proxy_listeners(px);
 
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        return 1;
 }
@@ -2112,9 +2112,9 @@ static int cli_parse_disable_frontend(char **args, char *payload, struct appctx
        if (!px->li_ready)
                return cli_msg(appctx, LOG_NOTICE, "All sockets are already disabled.\n");
 
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
        ret = pause_proxy(px);
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        if (!ret)
                return cli_err(appctx, "Failed to pause frontend, check logs for precise cause.\n");
@@ -2144,9 +2144,9 @@ static int cli_parse_enable_frontend(char **args, char *payload, struct appctx *
        if (px->li_ready == px->li_all)
                return cli_msg(appctx, LOG_NOTICE, "All sockets are already enabled.\n");
 
-       HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
        ret = resume_proxy(px);
-       HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
        if (!ret)
                return cli_err(appctx, "Failed to resume frontend, check logs for precise cause (port conflict?).\n");
@@ -2225,7 +2225,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
        while (appctx->ctx.errors.px) {
                struct error_snapshot *es;
 
-               HA_SPIN_LOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+               HA_RWLOCK_WRLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
 
                if ((appctx->ctx.errors.flag & 1) == 0) {
                        es = appctx->ctx.errors.px->invalid_req;
@@ -2335,7 +2335,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                        appctx->ctx.errors.bol = newline;
                };
        next:
-               HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+               HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
                appctx->ctx.errors.bol = 0;
                appctx->ctx.errors.ptr = -1;
                appctx->ctx.errors.flag ^= 1;
@@ -2347,7 +2347,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
        return 1;
 
  cant_send_unlock:
-       HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
  cant_send:
        si_rx_room_blk(si);
        return 0;
index 312c91fca535d34f648018032444a8bf21105583..f571878de49a04b0e2c575afffcf66cffce5bc8a 100644 (file)
@@ -152,7 +152,7 @@ static inline void pendconn_queue_lock(struct pendconn *p)
        if (p->srv)
                HA_SPIN_LOCK(SERVER_LOCK, &p->srv->lock);
        else
-               HA_SPIN_LOCK(PROXY_LOCK, &p->px->lock);
+               HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->px->lock);
 }
 
 /* Unlocks the queue the pendconn element belongs to. This relies on both p->px
@@ -164,7 +164,7 @@ static inline void pendconn_queue_unlock(struct pendconn *p)
        if (p->srv)
                HA_SPIN_UNLOCK(SERVER_LOCK, &p->srv->lock);
        else
-               HA_SPIN_UNLOCK(PROXY_LOCK, &p->px->lock);
+               HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->px->lock);
 }
 
 /* Removes the pendconn from the server/proxy queue. At this stage, the
@@ -312,14 +312,14 @@ void process_srv_queue(struct server *s)
        int maxconn;
 
        HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
-       HA_SPIN_LOCK(PROXY_LOCK,  &p->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK,  &p->lock);
        maxconn = srv_dynamic_maxconn(s);
        while (s->served < maxconn) {
                int ret = pendconn_process_next_strm(s, p);
                if (!ret)
                        break;
        }
-       HA_SPIN_UNLOCK(PROXY_LOCK,  &p->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK,  &p->lock);
        HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 }
 
@@ -444,7 +444,7 @@ int pendconn_grab_from_px(struct server *s)
             ((s != s->proxy->lbprm.fbck) && !(s->proxy->options & PR_O_USE_ALL_BK))))
                return 0;
 
-       HA_SPIN_LOCK(PROXY_LOCK, &s->proxy->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &s->proxy->lock);
        maxconn = srv_dynamic_maxconn(s);
        while ((p = pendconn_first(&s->proxy->pendconns))) {
                if (s->maxconn && s->served + xferred >= maxconn)
@@ -456,7 +456,7 @@ int pendconn_grab_from_px(struct server *s)
                task_wakeup(p->strm->task, TASK_WOKEN_RES);
                xferred++;
        }
-       HA_SPIN_UNLOCK(PROXY_LOCK, &s->proxy->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &s->proxy->lock);
        return xferred;
 }
 
index 2271f9e9969e73abd20358a8316bd6d9cedcb5c9..cdb5bce6840d1591c44b4cd81890c49dcdb30f91 100644 (file)
@@ -139,7 +139,7 @@ void srv_set_dyncookie(struct server *s)
        int addr_len;
        int port;
 
-       HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
+       HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
 
        if ((s->flags & SRV_F_COOKIESET) ||
            !(s->proxy->ck_opts & PR_CK_DYNAMIC) ||
@@ -188,7 +188,7 @@ void srv_set_dyncookie(struct server *s)
        if (!(s->next_admin & SRV_ADMF_FMAINT))
                srv_check_for_dup_dyncookie(s);
  out:
-       HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
+       HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
 }
 
 /*