mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
MINOR: server: move actconns to the per-thread structure
The actconns list creates massive contention on low server counts because it's in fact a list of streams using a server, all threads compete on the list's head and it's still possible to see some watchdog panics on 48 threads under extreme contention with 47 threads trying to add and one thread trying to delete. Moving this list per thread is trivial because it's only used by srv_shutdown_streams(), which simply required to iterate over the list. The field was renamed to "streams" as it's really a list of streams rather than a list of connections.
This commit is contained in:
parent
430bf4a483
commit
d4e78d873c
@ -205,6 +205,7 @@ struct tree_occ {
|
|||||||
|
|
||||||
/* Each server will have one occurrence of this structure per thread */
|
/* Each server will have one occurrence of this structure per thread */
|
||||||
struct srv_per_thread {
|
struct srv_per_thread {
|
||||||
|
struct mt_list streams; /* streams using this server (used by "shutdown server sessions") */
|
||||||
struct eb_root idle_conns; /* Shareable idle connections */
|
struct eb_root idle_conns; /* Shareable idle connections */
|
||||||
struct eb_root safe_conns; /* Safe idle connections */
|
struct eb_root safe_conns; /* Safe idle connections */
|
||||||
struct eb_root avail_conns; /* Connections in use, but with still new streams available */
|
struct eb_root avail_conns; /* Connections in use, but with still new streams available */
|
||||||
@ -236,8 +237,7 @@ struct server {
|
|||||||
struct be_counters counters; /* statistics counters */
|
struct be_counters counters; /* statistics counters */
|
||||||
|
|
||||||
struct eb_root pendconns; /* pending connections */
|
struct eb_root pendconns; /* pending connections */
|
||||||
struct mt_list actconns; /* active connections (used by "shutdown server sessions") */
|
struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists */
|
||||||
struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists, may be null */
|
|
||||||
unsigned int pool_purge_delay; /* Delay before starting to purge the idle conns pool */
|
unsigned int pool_purge_delay; /* Delay before starting to purge the idle conns pool */
|
||||||
unsigned int low_idle_conns; /* min idle connection count to start picking from other threads */
|
unsigned int low_idle_conns; /* min idle connection count to start picking from other threads */
|
||||||
unsigned int max_idle_conns; /* Max number of connection allowed in the orphan connections list */
|
unsigned int max_idle_conns; /* Max number of connection allowed in the orphan connections list */
|
||||||
|
@ -292,7 +292,7 @@ static inline void stream_add_srv_conn(struct stream *sess, struct server *srv)
|
|||||||
* from a conflict with an adjacent MT_LIST_DEL, and using it improves
|
* from a conflict with an adjacent MT_LIST_DEL, and using it improves
|
||||||
* the performance by about 3% on 32-cores.
|
* the performance by about 3% on 32-cores.
|
||||||
*/
|
*/
|
||||||
MT_LIST_ADD(&srv->actconns, &sess->by_srv);
|
MT_LIST_ADD(&srv->per_thr[tid].streams, &sess->by_srv);
|
||||||
HA_ATOMIC_STORE(&sess->srv_conn, srv);
|
HA_ATOMIC_STORE(&sess->srv_conn, srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3259,6 +3259,7 @@ out_uri_auth_compat:
|
|||||||
newsrv->per_thr[i].idle_conns = EB_ROOT;
|
newsrv->per_thr[i].idle_conns = EB_ROOT;
|
||||||
newsrv->per_thr[i].safe_conns = EB_ROOT;
|
newsrv->per_thr[i].safe_conns = EB_ROOT;
|
||||||
newsrv->per_thr[i].avail_conns = EB_ROOT;
|
newsrv->per_thr[i].avail_conns = EB_ROOT;
|
||||||
|
MT_LIST_INIT(&newsrv->per_thr[i].streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newsrv->max_idle_conns != 0) {
|
if (newsrv->max_idle_conns != 0) {
|
||||||
|
@ -9175,7 +9175,6 @@ void hlua_init(void) {
|
|||||||
socket_tcp.next = NULL;
|
socket_tcp.next = NULL;
|
||||||
socket_tcp.proxy = &socket_proxy;
|
socket_tcp.proxy = &socket_proxy;
|
||||||
socket_tcp.obj_type = OBJ_TYPE_SERVER;
|
socket_tcp.obj_type = OBJ_TYPE_SERVER;
|
||||||
MT_LIST_INIT(&socket_tcp.actconns);
|
|
||||||
socket_tcp.pendconns = EB_ROOT;
|
socket_tcp.pendconns = EB_ROOT;
|
||||||
LIST_ADD(&servers_list, &socket_tcp.global_list);
|
LIST_ADD(&servers_list, &socket_tcp.global_list);
|
||||||
socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
|
socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
|
||||||
@ -9221,7 +9220,6 @@ void hlua_init(void) {
|
|||||||
socket_ssl.next = NULL;
|
socket_ssl.next = NULL;
|
||||||
socket_ssl.proxy = &socket_proxy;
|
socket_ssl.proxy = &socket_proxy;
|
||||||
socket_ssl.obj_type = OBJ_TYPE_SERVER;
|
socket_ssl.obj_type = OBJ_TYPE_SERVER;
|
||||||
MT_LIST_INIT(&socket_ssl.actconns);
|
|
||||||
socket_ssl.pendconns = EB_ROOT;
|
socket_ssl.pendconns = EB_ROOT;
|
||||||
LIST_ADD(&servers_list, &socket_ssl.global_list);
|
LIST_ADD(&servers_list, &socket_ssl.global_list);
|
||||||
socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
|
socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
|
||||||
|
@ -891,10 +891,12 @@ void srv_shutdown_streams(struct server *srv, int why)
|
|||||||
{
|
{
|
||||||
struct stream *stream;
|
struct stream *stream;
|
||||||
struct mt_list *elt1, elt2;
|
struct mt_list *elt1, elt2;
|
||||||
|
int thr;
|
||||||
|
|
||||||
mt_list_for_each_entry_safe(stream, &srv->actconns, by_srv, elt1, elt2)
|
for (thr = 0; thr < global.nbthread; thr++)
|
||||||
if (stream->srv_conn == srv)
|
mt_list_for_each_entry_safe(stream, &srv->per_thr[thr].streams, by_srv, elt1, elt2)
|
||||||
stream_shutdown(stream, why);
|
if (stream->srv_conn == srv)
|
||||||
|
stream_shutdown(stream, why);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shutdown all connections of all backup servers of a proxy. The caller must
|
/* Shutdown all connections of all backup servers of a proxy. The caller must
|
||||||
@ -1750,7 +1752,6 @@ struct server *new_server(struct proxy *proxy)
|
|||||||
|
|
||||||
srv->obj_type = OBJ_TYPE_SERVER;
|
srv->obj_type = OBJ_TYPE_SERVER;
|
||||||
srv->proxy = proxy;
|
srv->proxy = proxy;
|
||||||
MT_LIST_INIT(&srv->actconns);
|
|
||||||
srv->pendconns = EB_ROOT;
|
srv->pendconns = EB_ROOT;
|
||||||
LIST_ADDQ(&servers_list, &srv->global_list);
|
LIST_ADDQ(&servers_list, &srv->global_list);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user