Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit 359faf2

Browse files
committed
Convert isc_astack usage in netmgr to mempool and ISC_LIST
Change the per-socket inactive uvreq cache (implemented as isc_astack) to per-worker memory pool. Change the per-socket inactive nmhandle cache (implemented as isc_astack) to unlocked per-socket ISC_LIST.
1 parent 8de2c73 commit 359faf2

File tree

2 files changed

+57
-70
lines changed

2 files changed

+57
-70
lines changed

lib/isc/netmgr/netmgr-int.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <openssl/err.h>
1919
#include <openssl/ssl.h>
2020

21-
#include <isc/astack.h>
2221
#include <isc/atomic.h>
2322
#include <isc/barrier.h>
2423
#include <isc/buffer.h>
@@ -201,6 +200,7 @@ typedef struct isc__networker {
201200

202201
ISC_LIST(isc_nmsocket_t) active_sockets;
203202

203+
isc_mempool_t *uvreq_pool;
204204
} isc__networker_t;
205205

206206
ISC_REFCOUNT_DECL(isc__networker);
@@ -245,6 +245,7 @@ struct isc_nmhandle {
245245
int backtrace_size;
246246
#endif
247247
LINK(isc_nmhandle_t) active_link;
248+
LINK(isc_nmhandle_t) inactive_link;
248249
void *opaque;
249250
};
250251

@@ -323,6 +324,7 @@ struct isc__nm_uvreq {
323324
uv_fs_t fs;
324325
} uv_req;
325326
ISC_LINK(isc__nm_uvreq_t) link;
327+
ISC_LINK(isc__nm_uvreq_t) inactive_link;
326328
};
327329

328330
void *
@@ -987,8 +989,7 @@ struct isc_nmsocket {
987989
* 'spare' handles for that can be reused to avoid allocations,
988990
* for UDP.
989991
*/
990-
isc_astack_t *inactivehandles;
991-
isc_astack_t *inactivereqs;
992+
ISC_LIST(isc_nmhandle_t) inactive_handles;
992993

993994
/*%
994995
* Used to pass a result back from listen or connect events.

lib/isc/netmgr/netmgr.c

Lines changed: 53 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ isc_netmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t **netmgrp) {
248248

249249
isc_mem_attach(loop->mctx, &worker->mctx);
250250

251+
isc_mempool_create(worker->mctx, sizeof(isc__nm_uvreq_t),
252+
&worker->uvreq_pool);
253+
isc_mempool_setfreemax(worker->uvreq_pool,
254+
ISC_NM_REQS_STACK_SIZE);
255+
251256
isc_loop_attach(loop, &worker->loop);
252257
isc_loop_teardown(loop, networker_teardown, worker);
253258
isc_refcount_init(&worker->references, 1);
@@ -596,7 +601,6 @@ nmsocket_cleanup(isc_nmsocket_t *sock) {
596601
REQUIRE(!isc__nmsocket_active(sock));
597602

598603
isc_nmhandle_t *handle = NULL;
599-
isc__nm_uvreq_t *uvreq = NULL;
600604
isc__networker_t *worker = sock->worker;
601605

602606
isc_refcount_destroy(&sock->references);
@@ -635,7 +639,8 @@ nmsocket_cleanup(isc_nmsocket_t *sock) {
635639
isc___nmsocket_detach(&sock->outer FLARG_PASS);
636640
}
637641

638-
while ((handle = isc_astack_pop(sock->inactivehandles)) != NULL) {
642+
while ((handle = ISC_LIST_HEAD(sock->inactive_handles)) != NULL) {
643+
ISC_LIST_DEQUEUE(sock->inactive_handles, handle, inactive_link);
639644
nmhandle_free(sock, handle);
640645
}
641646

@@ -645,14 +650,6 @@ nmsocket_cleanup(isc_nmsocket_t *sock) {
645650

646651
sock->pquota = NULL;
647652

648-
isc_astack_destroy(sock->inactivehandles);
649-
650-
while ((uvreq = isc_astack_pop(sock->inactivereqs)) != NULL) {
651-
isc_mem_put(sock->worker->mctx, uvreq, sizeof(*uvreq));
652-
}
653-
654-
isc_astack_destroy(sock->inactivereqs);
655-
656653
isc__nm_tls_cleanup_data(sock);
657654
#if HAVE_LIBNGHTTP2
658655
isc__nm_http_cleanup_data(sock);
@@ -855,10 +852,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc__networker_t *worker,
855852
.type = type,
856853
.tid = worker->loop->tid,
857854
.fd = -1,
858-
.inactivehandles = isc_astack_new(worker->mctx,
859-
ISC_NM_HANDLES_STACK_SIZE),
860-
.inactivereqs = isc_astack_new(worker->mctx,
861-
ISC_NM_REQS_STACK_SIZE),
855+
.inactive_handles = ISC_LIST_INITIALIZER,
862856
.result = ISC_R_UNSET,
863857
.active_handles = ISC_LIST_INITIALIZER,
864858
.active_link = ISC_LINK_INITIALIZER,
@@ -988,27 +982,38 @@ alloc_handle(isc_nmsocket_t *sock) {
988982
*handle = (isc_nmhandle_t){
989983
.magic = NMHANDLE_MAGIC,
990984
.active_link = ISC_LINK_INITIALIZER,
985+
.inactive_link = ISC_LINK_INITIALIZER,
991986
};
992987
isc_refcount_init(&handle->references, 1);
993988

994989
return (handle);
995990
}
996991

992+
static isc_nmhandle_t *
993+
dequeue_handle(isc_nmsocket_t *sock) {
994+
#if !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__
995+
isc_nmhandle_t *handle = ISC_LIST_HEAD(sock->inactive_handles);
996+
if (handle != NULL) {
997+
ISC_LIST_DEQUEUE(sock->inactive_handles, handle, inactive_link);
998+
999+
isc_refcount_init(&handle->references, 1);
1000+
INSIST(VALID_NMHANDLE(handle));
1001+
return (handle);
1002+
}
1003+
#else
1004+
UNUSED(sock);
1005+
#endif /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
1006+
return (NULL);
1007+
}
1008+
9971009
isc_nmhandle_t *
9981010
isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t const *peer,
9991011
isc_sockaddr_t const *local FLARG) {
1000-
isc_nmhandle_t *handle = NULL;
1001-
10021012
REQUIRE(VALID_NMSOCK(sock));
10031013

1004-
handle = isc_astack_pop(sock->inactivehandles);
1005-
1014+
isc_nmhandle_t *handle = dequeue_handle(sock);
10061015
if (handle == NULL) {
10071016
handle = alloc_handle(sock);
1008-
} else {
1009-
isc_refcount_init(&handle->references, 1);
1010-
INSIST(VALID_NMHANDLE(handle));
1011-
ISC_LINK_INIT(handle, active_link);
10121017
}
10131018

10141019
NETMGR_TRACE_LOG(
@@ -1107,25 +1112,17 @@ nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
11071112

11081113
static void
11091114
nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
1110-
bool reuse = false;
1111-
uint_fast32_t ah;
1115+
uint_fast32_t ah = atomic_fetch_sub(&sock->ah, 1);
1116+
INSIST(ah > 0);
11121117

1113-
/*
1114-
* We do all of this under lock to avoid races with socket
1115-
* destruction. We have to do this now, because at this point the
1116-
* socket is either unused or still attached to event->sock.
1117-
*/
11181118
ISC_LIST_UNLINK(sock->active_handles, handle, active_link);
11191119

1120-
ah = atomic_fetch_sub(&sock->ah, 1);
1121-
INSIST(ah > 0);
1122-
11231120
#if !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__
11241121
if (atomic_load(&sock->active)) {
1125-
reuse = isc_astack_trypush(sock->inactivehandles, handle);
1126-
}
1122+
ISC_LIST_APPEND(sock->inactive_handles, handle, inactive_link);
1123+
} else
11271124
#endif /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
1128-
if (!reuse) {
1125+
{
11291126
nmhandle_free(sock, handle);
11301127
}
11311128
}
@@ -1196,6 +1193,11 @@ nmhandle_detach_cb(isc_nmhandle_t **handlep FLARG) {
11961193
}
11971194
#endif
11981195

1196+
if (handle == sock->statichandle) {
1197+
/* statichandle is assigned, not attached. */
1198+
sock->statichandle = NULL;
1199+
}
1200+
11991201
nmhandle_deactivate(sock, handle);
12001202

12011203
/*
@@ -1207,11 +1209,6 @@ nmhandle_detach_cb(isc_nmhandle_t **handlep FLARG) {
12071209
sock->closehandle_cb(sock);
12081210
}
12091211

1210-
if (handle == sock->statichandle) {
1211-
/* statichandle is assigned, not attached. */
1212-
sock->statichandle = NULL;
1213-
}
1214-
12151212
isc___nmsocket_detach(&sock FLARG_PASS);
12161213
}
12171214

@@ -1761,35 +1758,31 @@ isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG) {
17611758

17621759
REQUIRE(worker != NULL);
17631760
REQUIRE(VALID_NMSOCK(sock));
1761+
REQUIRE(sock->tid == isc_tid());
17641762

1765-
if (sock != NULL && isc__nmsocket_active(sock)) {
1766-
/* Try to reuse one */
1767-
req = isc_astack_pop(sock->inactivereqs);
1768-
}
1769-
1770-
if (req == NULL) {
1771-
req = isc_mem_get(worker->mctx, sizeof(*req));
1772-
}
1773-
1763+
req = isc_mempool_get(worker->uvreq_pool);
17741764
*req = (isc__nm_uvreq_t){
1775-
.magic = 0,
17761765
.connect_tries = 3,
1766+
.link = ISC_LINK_INITIALIZER,
1767+
.inactive_link = ISC_LINK_INITIALIZER,
1768+
.uv_req.req.data = req,
1769+
.magic = UVREQ_MAGIC,
17771770
};
1778-
ISC_LINK_INIT(req, link);
1779-
req->uv_req.req.data = req;
17801771
isc___nmsocket_attach(sock, &req->sock FLARG_PASS);
1781-
req->magic = UVREQ_MAGIC;
17821772

17831773
return (req);
17841774
}
17851775

17861776
void
17871777
isc___nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock FLARG) {
1788-
isc__nm_uvreq_t *req = NULL;
1789-
isc_nmhandle_t *handle = NULL;
1790-
17911778
REQUIRE(req0 != NULL);
17921779
REQUIRE(VALID_UVREQ(*req0));
1780+
REQUIRE(VALID_NMSOCK(sock));
1781+
REQUIRE(sock->tid == isc_tid());
1782+
1783+
isc__nm_uvreq_t *req = NULL;
1784+
isc_nmhandle_t *handle = NULL;
1785+
isc__networker_t *worker = sock->worker;
17931786

17941787
req = *req0;
17951788
*req0 = NULL;
@@ -1802,18 +1795,9 @@ isc___nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock FLARG) {
18021795
* We need to save this first to make sure that handle,
18031796
* sock, and the netmgr won't all disappear.
18041797
*/
1805-
handle = req->handle;
1806-
req->handle = NULL;
1798+
ISC_SWAP(handle, req->handle);
18071799

1808-
#if !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__
1809-
if (!isc__nmsocket_active(sock) ||
1810-
!isc_astack_trypush(sock->inactivereqs, req))
1811-
{
1812-
isc_mem_put(sock->worker->mctx, req, sizeof(*req));
1813-
}
1814-
#else /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
1815-
isc_mem_put(sock->worker->mctx, req, sizeof(*req));
1816-
#endif /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
1800+
isc_mempool_put(worker->uvreq_pool, req);
18171801

18181802
if (handle != NULL) {
18191803
isc__nmhandle_detach(&handle FLARG_PASS);
@@ -2633,6 +2617,8 @@ isc__networker_destroy(isc__networker_t *worker) {
26332617

26342618
isc_loop_detach(&worker->loop);
26352619

2620+
isc_mempool_destroy(&worker->uvreq_pool);
2621+
26362622
isc_mem_put(worker->mctx, worker->sendbuf, ISC_NETMGR_SENDBUF_SIZE);
26372623
isc_mem_putanddetach(&worker->mctx, worker->recvbuf,
26382624
ISC_NETMGR_RECVBUF_SIZE);

0 commit comments

Comments
 (0)