OPTIM: lb-leastconn: do not take the server lock on take_conn/drop_conn

The operations are only an insert and a delete into the LB tree, which
doesn't require the server's lock at all as the lbprm lock is already
held. Let's drop it. Just for the sake of cleanness, given that the
served and nbpend values used to be atomically updated, we'll use an
atomic load to read them.
This commit is contained in:
Willy Tarreau 2021-02-17 16:14:00 +01:00
parent 6b96e0e9d2
commit 85b2fb0358
1 changed files with 3 additions and 9 deletions

View File

@ -30,7 +30,7 @@ static inline void fwlc_remove_from_tree(struct server *s)
/* simply removes a server from a tree. /* simply removes a server from a tree.
* *
* The server's lock and the lbprm's lock must be held. * The lbprm's lock must be held.
*/ */
static inline void fwlc_dequeue_srv(struct server *s) static inline void fwlc_dequeue_srv(struct server *s)
{ {
@ -53,11 +53,11 @@ static inline void fwlc_dequeue_srv(struct server *s)
* state is not yet committed. The current value is used to reposition the * state is not yet committed. The current value is used to reposition the
* server in the tree. This happens when the server is used. * server in the tree. This happens when the server is used.
* *
* The server's lock and the lbprm's lock must be held. * The lbprm's lock must be held.
*/ */
static inline void fwlc_queue_srv(struct server *s, unsigned int eweight) static inline void fwlc_queue_srv(struct server *s, unsigned int eweight)
{ {
unsigned int inflight = s->served + s->nbpend; unsigned int inflight = _HA_ATOMIC_LOAD(&s->served) + _HA_ATOMIC_LOAD(&s->nbpend);
s->lb_node.key = inflight ? (inflight + 1) * SRV_EWGHT_MAX / eweight : 0; s->lb_node.key = inflight ? (inflight + 1) * SRV_EWGHT_MAX / eweight : 0;
eb32_insert(s->lb_tree, &s->lb_node); eb32_insert(s->lb_tree, &s->lb_node);
@ -72,18 +72,12 @@ static inline void fwlc_queue_srv(struct server *s, unsigned int eweight)
*/ */
static void fwlc_srv_reposition(struct server *s, int locked) static void fwlc_srv_reposition(struct server *s, int locked)
{ {
if (!locked)
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock); HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
if (s->lb_tree) { if (s->lb_tree) {
fwlc_dequeue_srv(s); fwlc_dequeue_srv(s);
fwlc_queue_srv(s, s->cur_eweight); fwlc_queue_srv(s, s->cur_eweight);
} }
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock); HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
if (!locked)
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
} }
/* This function updates the server trees according to server <srv>'s new /* This function updates the server trees according to server <srv>'s new