]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: queue: use atomic-ops to update the queue's index
authorWilly Tarreau <w@1wt.eu>
Fri, 18 Jun 2021 08:51:58 +0000 (10:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 22 Jun 2021 16:57:18 +0000 (18:57 +0200)
Doing so allows to retrieve and update the pendconn's queue index outside
of the queue's lock and to save one more percent CPU on a highly-contented
backend.

src/queue.c

index 92089112233e81152851266deb55d7078f184faa..20880a2390d9b1d742ca45e2423d781ce1c2e66e 100644 (file)
@@ -133,7 +133,7 @@ unsigned int srv_dynamic_maxconn(const struct server *s)
  */
 static void __pendconn_unlink_srv(struct pendconn *p)
 {
-       p->strm->logs.srv_queue_pos += p->srv->queue.idx - p->queue_idx;
+       p->strm->logs.srv_queue_pos += _HA_ATOMIC_LOAD(&p->srv->queue.idx) - p->queue_idx;
        eb32_delete(&p->node);
 }
 
@@ -146,7 +146,7 @@ static void __pendconn_unlink_srv(struct pendconn *p)
  */
 static void __pendconn_unlink_prx(struct pendconn *p)
 {
-       p->strm->logs.prx_queue_pos += p->px->queue.idx - p->queue_idx;
+       p->strm->logs.prx_queue_pos += _HA_ATOMIC_LOAD(&p->px->queue.idx) - p->queue_idx;
        eb32_delete(&p->node);
 }
 
@@ -313,16 +313,16 @@ static struct pendconn *pendconn_process_next_strm(struct server *srv, struct pr
  use_pp:
        /* Let's switch from the server pendconn to the proxy pendconn */
        __pendconn_unlink_prx(pp);
+       _HA_ATOMIC_INC(&px->queue.idx);
        _HA_ATOMIC_DEC(&px->queue.length);
        _HA_ATOMIC_DEC(&px->totpend);
-       px->queue.idx++;
        p = pp;
        goto unlinked;
  use_p:
        __pendconn_unlink_srv(p);
+       _HA_ATOMIC_INC(&srv->queue.idx);
        _HA_ATOMIC_DEC(&srv->queue.length);
        _HA_ATOMIC_DEC(&px->totpend);
-       srv->queue.idx++;
  unlinked:
        p->strm_flags |= SF_ASSIGNED;
        p->target = srv;
@@ -422,6 +422,7 @@ struct pendconn *pendconn_add(struct stream *strm)
                max_ptr = &px->be_counters.nbpend_max;
        }
 
+       p->queue_idx  = _HA_ATOMIC_LOAD(&q->idx) - 1; // for logging only
        new_max = _HA_ATOMIC_ADD_FETCH(&q->length, 1);
        old_max = _HA_ATOMIC_LOAD(max_ptr);
        while (new_max > old_max) {
@@ -431,7 +432,6 @@ struct pendconn *pendconn_add(struct stream *strm)
        __ha_barrier_atomic_store();
 
        HA_SPIN_LOCK(QUEUE_LOCK, &q->lock);
-       p->queue_idx = q->idx - 1; // for increment
        eb32_insert(&q->head, &p->node);
        HA_SPIN_UNLOCK(QUEUE_LOCK, &q->lock);