Add memory pools for isc_nmsocket_t structures

To reduce memory pressure, we can add light per-loop (netmgr worker)
memory pools for isc_nmsocket_t structures.  This will help in
situations where there's a lot of churn creating and destroying the
nmsockets.
This commit is contained in:
Ondřej Surý 2023-09-12 19:13:45 +02:00
parent 750bd364b5
commit 15329d471e
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
9 changed files with 24 additions and 19 deletions

View file

@ -1482,7 +1482,7 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
local = &local_interface;
}
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_httpsocket, local, NULL);
http_initsocket(sock);
@ -1694,7 +1694,7 @@ server_on_begin_headers_callback(nghttp2_session *ngsession,
INSIST(session->handle->sock->tid == isc_tid());
worker = session->handle->sock->worker;
socket = isc_mem_get(worker->mctx, sizeof(isc_nmsocket_t));
socket = isc_mempool_get(worker->nmsocket_pool);
local = isc_nmhandle_localaddr(session->handle);
isc__nmsocket_init(socket, worker, isc_nm_httpsocket, &local, NULL);
http_initsocket(socket);
@ -2515,7 +2515,7 @@ isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
REQUIRE(isc_tid() == 0);
worker = &mgr->workers[isc_tid()];
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_httplistener, iface, NULL);
http_initsocket(sock);
atomic_init(&sock->h2->max_concurrent_streams,

View file

@ -109,6 +109,7 @@ STATIC_ASSERT(ISC_NETMGR_TCP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE,
* How many isc_nmhandles and isc_nm_uvreqs will we be
* caching for reuse in a socket.
*/
#define ISC_NM_NMSOCKET_MAX 64
#define ISC_NM_NMHANDLES_MAX 64
#define ISC_NM_UVREQS_MAX 64
@ -210,6 +211,7 @@ typedef struct isc__networker {
ISC_LIST(isc_nmsocket_t) active_sockets;
isc_mempool_t *nmsocket_pool;
isc_mempool_t *uvreq_pool;
} isc__networker_t;

View file

@ -222,6 +222,11 @@ isc_netmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t **netmgrp) {
isc_mem_attach(loop->mctx, &worker->mctx);
isc_mempool_create(worker->mctx, sizeof(isc_nmsocket_t),
&worker->nmsocket_pool);
isc_mempool_setfreemax(worker->nmsocket_pool,
ISC_NM_NMSOCKET_MAX);
isc_mempool_create(worker->mctx, sizeof(isc__nm_uvreq_t),
&worker->uvreq_pool);
isc_mempool_setfreemax(worker->uvreq_pool, ISC_NM_UVREQS_MAX);
@ -492,7 +497,7 @@ nmsocket_cleanup(void *arg) {
ISC_LIST_UNLINK(worker->active_sockets, sock, active_link);
isc_mem_put(worker->mctx, sock, sizeof(*sock));
isc_mempool_put(worker->nmsocket_pool, sock);
}
isc__networker_detach(&worker);
@ -2571,6 +2576,7 @@ isc__networker_destroy(isc__networker_t *worker) {
isc_loop_detach(&worker->loop);
isc_mempool_destroy(&worker->uvreq_pool);
isc_mempool_destroy(&worker->nmsocket_pool);
isc_mem_putanddetach(&worker->mctx, worker->recvbuf,
ISC_NETMGR_RECVBUF_SIZE);

View file

@ -236,7 +236,7 @@ proxystream_sock_new(isc__networker_t *worker, const isc_nmsocket_type_t type,
INSIST(type == isc_nm_proxystreamsocket ||
type == isc_nm_proxystreamlistener);
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, type, addr, NULL);
sock->result = ISC_R_UNSET;
if (type == isc_nm_proxystreamsocket) {

View file

@ -209,7 +209,7 @@ proxyudp_sock_new(isc__networker_t *worker, const isc_nmsocket_type_t type,
INSIST(type == isc_nm_proxyudpsocket ||
type == isc_nm_proxyudplistener);
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, type, addr, NULL);
sock->result = ISC_R_UNSET;
if (type == isc_nm_proxyudpsocket) {

View file

@ -250,7 +250,7 @@ streamdns_sock_new(isc__networker_t *worker, const isc_nmsocket_type_t type,
INSIST(type == isc_nm_streamdnssocket ||
type == isc_nm_streamdnslistener);
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, type, addr, NULL);
sock->result = ISC_R_UNSET;
if (type == isc_nm_streamdnssocket) {

View file

@ -245,7 +245,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
return;
}
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_tcpsocket, local, NULL);
sock->connect_timeout = timeout;
@ -459,7 +459,7 @@ isc_nm_listentcp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
REQUIRE(workers <= mgr->nloops);
worker = &mgr->workers[0];
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_tcplistener, iface, NULL);
sock->nchildren = (workers == ISC_NM_LISTEN_ALL) ? (uint32_t)mgr->nloops
@ -539,8 +539,7 @@ tcp_connection_cb(uv_stream_t *server, int status) {
}
/* Prepare the child socket */
isc_nmsocket_t *csock = isc_mem_get(ssock->worker->mctx,
sizeof(isc_nmsocket_t));
isc_nmsocket_t *csock = isc_mempool_get(ssock->worker->nmsocket_pool);
isc__nmsocket_init(csock, ssock->worker, isc_nm_tcpsocket,
&ssock->iface, NULL);
isc__nmsocket_attach(ssock, &csock->server);

View file

@ -913,7 +913,7 @@ tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
/*
* We need to create a 'wrapper' tlssocket for this connection.
*/
tlssock = isc_mem_get(handle->sock->worker->mctx, sizeof(*tlssock));
tlssock = isc_mempool_get(handle->sock->worker->nmsocket_pool);
isc__nmsocket_init(tlssock, handle->sock->worker, isc_nm_tlssocket,
&local, NULL);
@ -978,8 +978,7 @@ isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
}
REQUIRE(workers <= mgr->nloops);
tlssock = isc_mem_get(worker->mctx, sizeof(*tlssock));
tlssock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(tlssock, worker, isc_nm_tlslistener, iface, NULL);
tlssock->accept_cb = accept_cb;
tlssock->accept_cbarg = accept_cbarg;
@ -1213,7 +1212,7 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
return;
}
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_tlssocket, local, NULL);
sock->connect_cb = connect_cb;
sock->connect_cbarg = connect_cbarg;

View file

@ -227,7 +227,7 @@ isc_nm_listenudp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
}
REQUIRE(workers <= mgr->nloops);
sock = isc_mem_get(worker->mctx, sizeof(isc_nmsocket_t));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_udplistener, iface, NULL);
sock->nchildren = (workers == ISC_NM_LISTEN_ALL) ? (uint32_t)mgr->nloops
@ -376,7 +376,7 @@ isc_nm_routeconnect(isc_nm_t *mgr, isc_nm_cb_t cb, void *cbarg) {
return (result);
}
sock = isc_mem_get(worker->mctx, sizeof(*sock));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_udpsocket, NULL, NULL);
sock->connect_cb = cb;
@ -796,8 +796,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
}
/* Initialize the new socket */
/* FIXME: Use per-worker mempool for new sockets */
sock = isc_mem_get(worker->mctx, sizeof(isc_nmsocket_t));
sock = isc_mempool_get(worker->nmsocket_pool);
isc__nmsocket_init(sock, worker, isc_nm_udpsocket, local, NULL);
sock->connect_cb = cb;