mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-31 02:22:07 +00:00
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%.
This commit is contained in:
parent
ccea3c54f4
commit
751153e0f1
@ -228,7 +228,7 @@ struct server {
|
||||
struct be_counters counters; /* statistics counters */
|
||||
|
||||
struct eb_root pendconns; /* pending connections */
|
||||
struct list actconns; /* active connections */
|
||||
struct mt_list actconns; /* active connections (used by "shutdown server sessions") */
|
||||
struct eb_root *idle_conns_tree; /* shareable idle connections*/
|
||||
struct eb_root *safe_conns_tree; /* safe idle connections */
|
||||
struct eb_root *available_conns_tree; /* Connection in used, but with still new streams available */
|
||||
|
@ -140,7 +140,7 @@ struct stream {
|
||||
int32_t priority_offset; /* priority offset of the stream for the pending queue */
|
||||
|
||||
struct list list; /* position in global streams list */
|
||||
struct list by_srv; /* position in server stream list */
|
||||
struct mt_list by_srv; /* position in server stream list */
|
||||
struct list back_refs; /* list of users tracking this stream */
|
||||
struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */
|
||||
|
||||
|
@ -285,17 +285,10 @@ static inline void stream_inc_http_fail_ctr(struct stream *s)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __stream_add_srv_conn(struct stream *sess, struct server *srv)
|
||||
{
|
||||
sess->srv_conn = srv;
|
||||
LIST_ADD(&srv->actconns, &sess->by_srv);
|
||||
}
|
||||
|
||||
static inline void stream_add_srv_conn(struct stream *sess, struct server *srv)
|
||||
{
|
||||
HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
|
||||
__stream_add_srv_conn(sess, srv);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
MT_LIST_ADD(&srv->actconns, &sess->by_srv);
|
||||
HA_ATOMIC_STORE(&sess->srv_conn, srv);
|
||||
}
|
||||
|
||||
static inline void stream_del_srv_conn(struct stream *sess)
|
||||
@ -305,16 +298,14 @@ static inline void stream_del_srv_conn(struct stream *sess)
|
||||
if (!srv)
|
||||
return;
|
||||
|
||||
HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
|
||||
sess->srv_conn = NULL;
|
||||
LIST_DEL(&sess->by_srv);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
MT_LIST_DEL(&sess->by_srv);
|
||||
HA_ATOMIC_STORE(&sess->srv_conn, NULL);
|
||||
}
|
||||
|
||||
static inline void stream_init_srv_conn(struct stream *sess)
|
||||
{
|
||||
sess->srv_conn = NULL;
|
||||
LIST_INIT(&sess->by_srv);
|
||||
MT_LIST_INIT(&sess->by_srv);
|
||||
}
|
||||
|
||||
static inline void stream_choose_redispatch(struct stream *s)
|
||||
|
@ -9175,7 +9175,7 @@ void hlua_init(void) {
|
||||
socket_tcp.next = NULL;
|
||||
socket_tcp.proxy = &socket_proxy;
|
||||
socket_tcp.obj_type = OBJ_TYPE_SERVER;
|
||||
LIST_INIT(&socket_tcp.actconns);
|
||||
MT_LIST_INIT(&socket_tcp.actconns);
|
||||
socket_tcp.pendconns = EB_ROOT;
|
||||
socket_tcp.idle_conns_tree = NULL;
|
||||
socket_tcp.safe_conns_tree = NULL;
|
||||
@ -9220,7 +9220,7 @@ void hlua_init(void) {
|
||||
socket_ssl.next = NULL;
|
||||
socket_ssl.proxy = &socket_proxy;
|
||||
socket_ssl.obj_type = OBJ_TYPE_SERVER;
|
||||
LIST_INIT(&socket_ssl.actconns);
|
||||
MT_LIST_INIT(&socket_ssl.actconns);
|
||||
socket_ssl.pendconns = EB_ROOT;
|
||||
socket_ssl.idle_conns_tree = NULL;
|
||||
socket_ssl.safe_conns_tree = NULL;
|
||||
|
@ -328,7 +328,7 @@ static int pendconn_process_next_strm(struct server *srv, struct proxy *px)
|
||||
__ha_barrier_atomic_store();
|
||||
if (px->lbprm.server_take_conn)
|
||||
px->lbprm.server_take_conn(srv);
|
||||
__stream_add_srv_conn(p->strm, srv);
|
||||
stream_add_srv_conn(p->strm, srv);
|
||||
|
||||
task_wakeup(p->strm->task, TASK_WOKEN_RES);
|
||||
|
||||
|
@ -900,9 +900,10 @@ static int srv_parse_tfo(char **args, int *cur_arg, struct proxy *px, struct ser
|
||||
*/
|
||||
void srv_shutdown_streams(struct server *srv, int why)
|
||||
{
|
||||
struct stream *stream, *stream_bck;
|
||||
struct stream *stream;
|
||||
struct mt_list *elt1, elt2;
|
||||
|
||||
list_for_each_entry_safe(stream, stream_bck, &srv->actconns, by_srv)
|
||||
mt_list_for_each_entry_safe(stream, &srv->actconns, by_srv, elt1, elt2)
|
||||
if (stream->srv_conn == srv)
|
||||
stream_shutdown(stream, why);
|
||||
}
|
||||
@ -1757,7 +1758,7 @@ struct server *new_server(struct proxy *proxy)
|
||||
|
||||
srv->obj_type = OBJ_TYPE_SERVER;
|
||||
srv->proxy = proxy;
|
||||
LIST_INIT(&srv->actconns);
|
||||
MT_LIST_INIT(&srv->actconns);
|
||||
srv->pendconns = EB_ROOT;
|
||||
|
||||
srv->next_state = SRV_ST_RUNNING; /* early server setup */
|
||||
|
18
src/stream.c
18
src/stream.c
@ -2532,17 +2532,19 @@ void stream_update_time_stats(struct stream *s)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user