OPTIM: server: switch the actconn list to an mt-list
The remaining contention on the server lock solely comes from
sess_change_server() which takes the lock to add and remove a
stream from the server's actconn list. This is both expensive
and pointless since we have mt-lists, and this list is only
used by the CLI's "shutdown server sessions" command!
Let's migrate to an mt-list and remove the need for this costly
lock. By doing so, the request rate increased by ~1.8%.
(cherry picked from commit 751153e0f119bec90455cda95166f1b29d8b0326)
[wt: the contention is extreme on high threads counts, thus this
actconn series is backported; ctx adjustments]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/stream.c b/src/stream.c
index a2feea1..7b58e2a 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -2496,17 +2496,19 @@
*/
void sess_change_server(struct stream *sess, struct server *newsrv)
{
- if (sess->srv_conn == newsrv)
+ struct server *oldsrv = sess->srv_conn;
+
+ if (oldsrv == newsrv)
return;
- if (sess->srv_conn) {
- _HA_ATOMIC_SUB(&sess->srv_conn->served, 1);
- _HA_ATOMIC_SUB(&sess->srv_conn->proxy->served, 1);
+ if (oldsrv) {
+ _HA_ATOMIC_SUB(&oldsrv->served, 1);
+ _HA_ATOMIC_SUB(&oldsrv->proxy->served, 1);
__ha_barrier_atomic_store();
- if (sess->srv_conn->proxy->lbprm.server_drop_conn) {
- HA_SPIN_LOCK(SERVER_LOCK, &sess->srv_conn->lock);
- sess->srv_conn->proxy->lbprm.server_drop_conn(sess->srv_conn);
- HA_SPIN_UNLOCK(SERVER_LOCK, &sess->srv_conn->lock);
+ if (oldsrv->proxy->lbprm.server_drop_conn) {
+ HA_SPIN_LOCK(SERVER_LOCK, &oldsrv->lock);
+ oldsrv->proxy->lbprm.server_drop_conn(oldsrv);
+ HA_SPIN_UNLOCK(SERVER_LOCK, &oldsrv->lock);
}
stream_del_srv_conn(sess);
}