]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: backend: replace the lbprm lock with an rwlock
authorWilly Tarreau <w@1wt.eu>
Sat, 17 Oct 2020 16:48:47 +0000 (18:48 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 17 Oct 2020 16:51:41 +0000 (18:51 +0200)
It was previously a spinlock, and it happens that a number of LB algos
only lock it for lookups, without performing any modification. Let's
first turn it to an rwlock and w-lock it everywhere. This is strictly
identical.

It was carefully checked that every HA_SPIN_LOCK() was turned to
HA_RWLOCK_WRLOCK() and that HA_SPIN_UNLOCK() was turned to
HA_RWLOCK_WRUNLOCK() on this lock. _INIT and _DESTROY were updated too.

include/haproxy/backend-t.h
src/cfgparse.c
src/haproxy.c
src/lb_chash.c
src/lb_fas.c
src/lb_fwlc.c
src/lb_fwrr.c
src/lb_map.c

index daaf386631751a671f03ab0d2f0a4c724235cc98..bb8ec6f5599ef9ff900f8bcedd5799879cac3d58 100644 (file)
@@ -157,7 +157,7 @@ struct lbprm {
        int   arg_opt2;                 /* extra option 2 for the LB algo (algo-specific) */
        int   arg_opt3;                 /* extra option 3 for the LB algo (algo-specific) */
        struct server *fbck;            /* first backup server when !PR_O_USE_ALL_BK, or NULL */
-       __decl_thread(HA_SPINLOCK_T lock);
+       __decl_thread(HA_RWLOCK_T lock);
 
        /* Call backs for some actions. Any of them may be NULL (thus should be ignored). */
        void (*update_server_eweight)(struct server *);  /* to be called after eweight change */
index cda259094dc274cf9c14c9f7bdceaa85167aa6c8..4d3c8ad554471163d1883c33b3904ad56970ed20 100644 (file)
@@ -3270,7 +3270,7 @@ out_uri_auth_compat:
                        }
                        break;
                }
-               HA_SPIN_INIT(&curproxy->lbprm.lock);
+               HA_RWLOCK_INIT(&curproxy->lbprm.lock);
 
                if (curproxy->options & PR_O_LOGASAP)
                        curproxy->to_log &= ~LW_BYTES;
index 83e57ce6e90b0913dedc33904cddbe71881e7e10..389abb84ea0fd128a171aab4bf4a8befd24b9ba5 100644 (file)
@@ -2685,7 +2685,7 @@ void deinit(void)
 
                p0 = p;
                p = p->next;
-               HA_SPIN_DESTROY(&p0->lbprm.lock);
+               HA_RWLOCK_DESTROY(&p0->lbprm.lock);
                HA_SPIN_DESTROY(&p0->lock);
                free(p0);
        }/* end while(p) */
index 55417b5e73e21d5dd66bddedfa57aee98218ccdd..a37a40ff2e09ad3796e315b2049235cab6b16a7c 100644 (file)
@@ -124,7 +124,7 @@ static void chash_set_server_status_down(struct server *srv)
        if (!srv_lb_status_changed(srv))
                return;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv_willbe_usable(srv))
                goto out_update_state;
@@ -162,7 +162,7 @@ out_update_backend:
  out_update_state:
        srv_lb_commit_status(srv);
 
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -181,7 +181,7 @@ static void chash_set_server_status_up(struct server *srv)
        if (!srv_lb_status_changed(srv))
                return;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (!srv_willbe_usable(srv))
                goto out_update_state;
@@ -224,7 +224,7 @@ static void chash_set_server_status_up(struct server *srv)
  out_update_state:
        srv_lb_commit_status(srv);
 
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /* This function must be called after an update to server <srv>'s effective
@@ -264,7 +264,7 @@ static void chash_update_server_weight(struct server *srv)
                return;
        }
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        /* only adjust the server's presence in the tree */
        chash_queue_dequeue_srv(srv);
@@ -277,7 +277,7 @@ static void chash_update_server_weight(struct server *srv)
        update_backend_weight(p);
        srv_lb_commit_status(srv);
 
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /*
@@ -324,7 +324,7 @@ struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const s
        unsigned int dn, dp;
        int loop;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (p->srv_act)
                root = &p->lbprm.chash.act;
@@ -379,7 +379,7 @@ struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const s
        }
 
  out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
        return nsrv;
 }
 
@@ -395,7 +395,7 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid)
        srv = avoided = NULL;
        avoided_node = NULL;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        if (p->srv_act)
                root = &p->lbprm.chash.act;
        else if (p->lbprm.fbck) {
@@ -454,7 +454,7 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid)
        }
 
  out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
        return srv;
 }
 
index 0fcd5e395f686119675a6743ecd128ec3adbf9c8..43ff6a582259f5e802b50dd2160b68d13afc16af 100644 (file)
@@ -65,12 +65,12 @@ static inline void fas_queue_srv(struct server *s)
  */
 static void fas_srv_reposition(struct server *s)
 {
-       HA_SPIN_LOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
        if (s->lb_tree) {
                fas_dequeue_srv(s);
                fas_queue_srv(s);
        }
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -91,7 +91,7 @@ static void fas_set_server_status_down(struct server *srv)
        if (srv_willbe_usable(srv))
                goto out_update_state;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (!srv_currently_usable(srv))
                /* server was already down */
@@ -124,7 +124,7 @@ static void fas_set_server_status_down(struct server *srv)
  out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -149,7 +149,7 @@ static void fas_set_server_status_up(struct server *srv)
        if (!srv_willbe_usable(srv))
                goto out_update_state;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv_currently_usable(srv))
                /* server was already up */
@@ -188,7 +188,7 @@ static void fas_set_server_status_up(struct server *srv)
  out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -231,7 +231,7 @@ static void fas_update_server_weight(struct server *srv)
                return;
        }
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv->lb_tree)
                fas_dequeue_srv(srv);
@@ -247,7 +247,7 @@ static void fas_update_server_weight(struct server *srv)
        fas_queue_srv(srv);
 
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        srv_lb_commit_status(srv);
 }
@@ -300,7 +300,7 @@ struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid)
 
        srv = avoided = NULL;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        if (p->srv_act)
                node = eb32_first(&p->lbprm.fas.act);
        else if (p->lbprm.fbck) {
@@ -336,7 +336,7 @@ struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid)
        if (!srv)
                srv = avoided;
   out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
        return srv;
 }
 
index 8eac2c9304f066295d6a61b5e6af232fbc39c52a..882dd7d430001788ac9c608ee0c401609022afe2 100644 (file)
@@ -63,12 +63,12 @@ static inline void fwlc_queue_srv(struct server *s)
  */
 static void fwlc_srv_reposition(struct server *s)
 {
-       HA_SPIN_LOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
        if (s->lb_tree) {
                fwlc_dequeue_srv(s);
                fwlc_queue_srv(s);
        }
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -88,7 +88,7 @@ static void fwlc_set_server_status_down(struct server *srv)
 
        if (srv_willbe_usable(srv))
                goto out_update_state;
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 
        if (!srv_currently_usable(srv))
@@ -122,7 +122,7 @@ static void fwlc_set_server_status_down(struct server *srv)
 out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -147,7 +147,7 @@ static void fwlc_set_server_status_up(struct server *srv)
        if (!srv_willbe_usable(srv))
                goto out_update_state;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv_currently_usable(srv))
                /* server was already up */
@@ -186,7 +186,7 @@ static void fwlc_set_server_status_up(struct server *srv)
  out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -229,7 +229,7 @@ static void fwlc_update_server_weight(struct server *srv)
                return;
        }
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv->lb_tree)
                fwlc_dequeue_srv(srv);
@@ -245,7 +245,7 @@ static void fwlc_update_server_weight(struct server *srv)
        fwlc_queue_srv(srv);
 
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        srv_lb_commit_status(srv);
 }
@@ -298,7 +298,7 @@ struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid)
 
        srv = avoided = NULL;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        if (p->srv_act)
                node = eb32_first(&p->lbprm.fwlc.act);
        else if (p->lbprm.fbck) {
@@ -334,7 +334,7 @@ struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid)
        if (!srv)
                srv = avoided;
  out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
        return srv;
 }
 
index 05ae5f6f466e4f600ae7c8950bd102d530587ab5..e2cdd9f0dadac7b83310fdb46e9fcbde5d52011c 100644 (file)
@@ -43,7 +43,7 @@ static void fwrr_set_server_status_down(struct server *srv)
        if (srv_willbe_usable(srv))
                goto out_update_state;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (!srv_currently_usable(srv))
                /* server was already down */
@@ -79,7 +79,7 @@ static void fwrr_set_server_status_down(struct server *srv)
 out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -105,7 +105,7 @@ static void fwrr_set_server_status_up(struct server *srv)
        if (!srv_willbe_usable(srv))
                goto out_update_state;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        if (srv_currently_usable(srv))
                /* server was already up */
@@ -147,7 +147,7 @@ static void fwrr_set_server_status_up(struct server *srv)
 out_update_backend:
        /* check/update tot_used, tot_weight */
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
        srv_lb_commit_status(srv);
@@ -191,7 +191,7 @@ static void fwrr_update_server_weight(struct server *srv)
                return;
        }
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        grp = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fwrr.bck : &p->lbprm.fwrr.act;
        grp->next_weight = grp->next_weight - srv->cur_eweight + srv->next_eweight;
@@ -239,7 +239,7 @@ static void fwrr_update_server_weight(struct server *srv)
        }
 
        update_backend_weight(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
        srv_lb_commit_status(srv);
 }
@@ -514,7 +514,7 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
        struct fwrr_group *grp;
        int switched;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        if (p->srv_act)
                grp = &p->lbprm.fwrr.act;
        else if (p->lbprm.fbck) {
@@ -611,7 +611,7 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
                }
        }
  out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
        return srv;
 }
 
index ef32deb3fdbe5a2203607042bf2d7aedd73a1673..14329133167a089a0c6b4b3342173720c02586d2 100644 (file)
@@ -32,11 +32,11 @@ static void map_set_server_status_down(struct server *srv)
                goto out_update_state;
 
        /* FIXME: could be optimized since we know what changed */
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        recount_servers(p);
        update_backend_weight(p);
        recalc_server_map(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
  out_update_state:
        srv_lb_commit_status(srv);
 }
@@ -56,11 +56,11 @@ static void map_set_server_status_up(struct server *srv)
                goto out_update_state;
 
        /* FIXME: could be optimized since we know what changed */
-       HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
        recount_servers(p);
        update_backend_weight(p);
        recalc_server_map(p);
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
  out_update_state:
        srv_lb_commit_status(srv);
 }
@@ -216,7 +216,7 @@ struct server *map_get_server_rr(struct proxy *px, struct server *srvtoavoid)
        int newidx, avoididx;
        struct server *srv, *avoided;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &px->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &px->lbprm.lock);
        if (px->lbprm.tot_weight == 0) {
                avoided = NULL;
                goto out;
@@ -248,7 +248,7 @@ struct server *map_get_server_rr(struct proxy *px, struct server *srvtoavoid)
                px->lbprm.map.rr_idx = avoididx;
 
   out:
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &px->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &px->lbprm.lock);
        /* return NULL or srvtoavoid if found */
        return avoided;
 }
@@ -265,10 +265,10 @@ struct server *map_get_server_hash(struct proxy *px, unsigned int hash)
 {
        struct server *srv = NULL;
 
-       HA_SPIN_LOCK(LBPRM_LOCK, &px->lbprm.lock);
+       HA_RWLOCK_WRLOCK(LBPRM_LOCK, &px->lbprm.lock);
        if (px->lbprm.tot_weight)
                srv = px->lbprm.map.srv[hash % px->lbprm.tot_weight];
-       HA_SPIN_UNLOCK(LBPRM_LOCK, &px->lbprm.lock);
+       HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &px->lbprm.lock);
        return srv;
 }