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.
(cherry picked from commit 85b2fb03580f60d20d20ecbda8c9b63804d8e900)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/lb_fwlc.c b/src/lb_fwlc.c
index 4239a4c..7bbeb62 100644
--- a/src/lb_fwlc.c
+++ b/src/lb_fwlc.c
@@ -30,7 +30,7 @@
/* 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)
{
@@ -53,11 +53,11 @@
* state is not yet committed. The current value is used to reposition the
* 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)
{
- 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;
eb32_insert(s->lb_tree, &s->lb_node);
@@ -72,18 +72,12 @@
*/
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);
if (s->lb_tree) {
fwlc_dequeue_srv(s);
fwlc_queue_srv(s, s->cur_eweight);
}
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