2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Replace locked mempools with memory contexts

Current mempools are kind of hybrid structures - they serve two
purposes:

 1. mempool with a lock is basically static sized allocator with
    pre-allocated free items

 2. mempool without a lock is a doubly-linked list of preallocated items

The first kind of usage could be easily replaced with jemalloc small
sized arena objects and thread-local caches.

The second usage not-so-much and we need to keep this (in
libdns:message.c) for performance reasons.
This commit is contained in:
Ondřej Surý
2021-05-12 21:16:17 +02:00
parent fd3ceec475
commit f487c6948b
12 changed files with 161 additions and 653 deletions

View File

@@ -112,14 +112,8 @@ struct dns_adb {
unsigned int irefcnt;
unsigned int erefcnt;
isc_mutex_t mplock;
isc_mempool_t *nmp; /*%< dns_adbname_t */
isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
isc_mempool_t *limp; /*%< dns_adblameinfo_t */
isc_mempool_t *emp; /*%< dns_adbentry_t */
isc_mempool_t *ahmp; /*%< dns_adbfind_t */
isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
isc_mempool_t *afmp; /*%< dns_adbfetch_t */
isc_refcount_t ahrefcnt;
isc_refcount_t nhrefcnt;
/*!
* Bucketized locks and lists for names.
@@ -624,12 +618,6 @@ grow_entries(isc_task_t *task, isc_event_t *ev) {
newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
if (newentries == NULL || newdeadentries == NULL ||
newentrylocks == NULL || newentry_sd == NULL ||
newentry_refcnt == NULL)
{
goto cleanup;
}
/*
* Initialise the new resources.
@@ -795,11 +783,6 @@ grow_names(isc_task_t *task, isc_event_t *ev) {
newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
if (newnames == NULL || newdeadnames == NULL || newnamelocks == NULL ||
newname_sd == NULL || newname_refcnt == NULL)
{
goto cleanup;
}
/*
* Initialise the new resources.
@@ -1734,10 +1717,7 @@ static inline dns_adbname_t *
new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) {
dns_adbname_t *name;
name = isc_mempool_get(adb->nmp);
if (name == NULL) {
return (NULL);
}
name = isc_mem_get(adb->mctx, sizeof(*name));
dns_name_init(&name->name, NULL);
dns_name_dup(dnsname, adb->mctx, &name->name);
@@ -1795,7 +1775,7 @@ free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
n->magic = 0;
dns_name_free(&n->name, adb->mctx);
isc_mempool_put(adb->nmp, n);
isc_mem_put(adb->mctx, n, sizeof(*n));
LOCK(&adb->namescntlock);
adb->namescnt--;
dec_adbstats(adb, dns_adbstats_namescnt);
@@ -1806,10 +1786,8 @@ static inline dns_adbnamehook_t *
new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
dns_adbnamehook_t *nh;
nh = isc_mempool_get(adb->nhmp);
if (nh == NULL) {
return (NULL);
}
nh = isc_mem_get(adb->mctx, sizeof(*nh));
isc_refcount_increment0(&adb->nhrefcnt);
nh->magic = DNS_ADBNAMEHOOK_MAGIC;
nh->entry = entry;
@@ -1830,7 +1808,9 @@ free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
INSIST(!ISC_LINK_LINKED(nh, plink));
nh->magic = 0;
isc_mempool_put(adb->nhmp, nh);
isc_refcount_decrement(&adb->nhrefcnt);
isc_mem_put(adb->mctx, nh, sizeof(*nh));
}
static inline dns_adblameinfo_t *
@@ -1838,10 +1818,7 @@ new_adblameinfo(dns_adb_t *adb, const dns_name_t *qname,
dns_rdatatype_t qtype) {
dns_adblameinfo_t *li;
li = isc_mempool_get(adb->limp);
if (li == NULL) {
return (NULL);
}
li = isc_mem_get(adb->mctx, sizeof(*li));
dns_name_init(&li->qname, NULL);
dns_name_dup(qname, adb->mctx, &li->qname);
@@ -1867,17 +1844,14 @@ free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
li->magic = 0;
isc_mempool_put(adb->limp, li);
isc_mem_put(adb->mctx, li, sizeof(*li));
}
static inline dns_adbentry_t *
new_adbentry(dns_adb_t *adb) {
dns_adbentry_t *e;
e = isc_mempool_get(adb->emp);
if (e == NULL) {
return (NULL);
}
e = isc_mem_get(adb->mctx, sizeof(*e));
e->magic = DNS_ADBENTRY_MAGIC;
e->lock_bucket = DNS_ADB_INVALIDBUCKET;
@@ -1944,7 +1918,7 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
li = ISC_LIST_HEAD(e->lameinfo);
}
isc_mempool_put(adb->emp, e);
isc_mem_put(adb->mctx, e, sizeof(*e));
LOCK(&adb->entriescntlock);
adb->entriescnt--;
dec_adbstats(adb, dns_adbstats_entriescnt);
@@ -1955,10 +1929,8 @@ static inline dns_adbfind_t *
new_adbfind(dns_adb_t *adb) {
dns_adbfind_t *h;
h = isc_mempool_get(adb->ahmp);
if (h == NULL) {
return (NULL);
}
h = isc_mem_get(adb->mctx, sizeof(*h));
isc_refcount_increment0(&adb->ahrefcnt);
/*
* Public members.
@@ -1993,10 +1965,7 @@ static inline dns_adbfetch_t *
new_adbfetch(dns_adb_t *adb) {
dns_adbfetch_t *f;
f = isc_mempool_get(adb->afmp);
if (f == NULL) {
return (NULL);
}
f = isc_mem_get(adb->mctx, sizeof(*f));
f->magic = 0;
f->fetch = NULL;
@@ -2022,7 +1991,7 @@ free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
dns_rdataset_disassociate(&f->rdataset);
}
isc_mempool_put(adb->afmp, f);
isc_mem_put(adb->mctx, f, sizeof(*f));
}
static inline bool
@@ -2042,7 +2011,9 @@ free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
find->magic = 0;
isc_mutex_destroy(&find->lock);
isc_mempool_put(adb->ahmp, find);
isc_refcount_decrement(&adb->ahrefcnt);
isc_mem_put(adb->mctx, find, sizeof(*find));
return (dec_adb_irefcnt(adb));
}
@@ -2055,10 +2026,7 @@ static inline dns_adbaddrinfo_t *
new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
dns_adbaddrinfo_t *ai;
ai = isc_mempool_get(adb->aimp);
if (ai == NULL) {
return (NULL);
}
ai = isc_mem_get(adb->mctx, sizeof(*ai));
ai->magic = DNS_ADBADDRINFO_MAGIC;
ai->sockaddr = entry->sockaddr;
@@ -2085,7 +2053,7 @@ free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
ai->magic = 0;
isc_mempool_put(adb->aimp, ai);
isc_mem_put(adb->mctx, ai, sizeof(*ai));
}
/*
@@ -2539,14 +2507,6 @@ destroy(dns_adb_t *adb) {
isc_task_detach(&adb->excl);
}
isc_mempool_destroy(&adb->nmp);
isc_mempool_destroy(&adb->nhmp);
isc_mempool_destroy(&adb->limp);
isc_mempool_destroy(&adb->emp);
isc_mempool_destroy(&adb->ahmp);
isc_mempool_destroy(&adb->aimp);
isc_mempool_destroy(&adb->afmp);
isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
isc_mem_put(adb->mctx, adb->entries,
sizeof(*adb->entries) * adb->nentries);
@@ -2572,7 +2532,6 @@ destroy(dns_adb_t *adb) {
isc_mutex_destroy(&adb->reflock);
isc_mutex_destroy(&adb->lock);
isc_mutex_destroy(&adb->mplock);
isc_mutex_destroy(&adb->overmemlock);
isc_mutex_destroy(&adb->entriescntlock);
isc_mutex_destroy(&adb->namescntlock);
@@ -2608,13 +2567,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
adb->magic = 0;
adb->erefcnt = 1;
adb->irefcnt = 0;
adb->nmp = NULL;
adb->nhmp = NULL;
adb->limp = NULL;
adb->emp = NULL;
adb->ahmp = NULL;
adb->aimp = NULL;
adb->afmp = NULL;
adb->task = NULL;
adb->excl = NULL;
adb->mctx = NULL;
@@ -2670,7 +2622,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
isc_mem_attach(mem, &adb->mctx);
isc_mutex_init(&adb->lock);
isc_mutex_init(&adb->mplock);
isc_mutex_init(&adb->reflock);
isc_mutex_init(&adb->overmemlock);
isc_mutex_init(&adb->entriescntlock);
@@ -2680,10 +2631,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
do { \
(adb)->el = isc_mem_get((adb)->mctx, \
sizeof(*(adb)->el) * (adb)->nentries); \
if ((adb)->el == NULL) { \
result = ISC_R_NOMEMORY; \
goto fail1; \
} \
} while (0)
ALLOCENTRY(adb, entries);
ALLOCENTRY(adb, deadentries);
@@ -2696,10 +2643,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
do { \
(adb)->el = isc_mem_get((adb)->mctx, \
sizeof(*(adb)->el) * (adb)->nnames); \
if ((adb)->el == NULL) { \
result = ISC_R_NOMEMORY; \
goto fail1; \
} \
} while (0)
ALLOCNAME(adb, names);
ALLOCNAME(adb, deadnames);
@@ -2730,27 +2673,8 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
}
isc_mutexblock_init(adb->entrylocks, adb->nentries);
/*
* Memory pools
*/
#define MPINIT(t, p, n) \
do { \
isc_mempool_create(mem, sizeof(t), &(p)); \
isc_mempool_setfreemax((p), FREE_ITEMS); \
isc_mempool_setfillcount((p), FILL_COUNT); \
isc_mempool_setname((p), n); \
isc_mempool_associatelock((p), &adb->mplock); \
} while (0)
MPINIT(dns_adbname_t, adb->nmp, "adbname");
MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
MPINIT(dns_adbentry_t, adb->emp, "adbentry");
MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
#undef MPINIT
isc_refcount_init(&adb->ahrefcnt, 0);
isc_refcount_init(&adb->nhrefcnt, 0);
/*
* Allocate an internal task.
@@ -2786,7 +2710,6 @@ fail2:
isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
isc_mutexblock_destroy(adb->namelocks, adb->nnames);
fail1: /* clean up only allocated memory */
if (adb->entries != NULL) {
isc_mem_put(adb->mctx, adb->entries,
sizeof(*adb->entries) * adb->nentries);
@@ -2827,33 +2750,11 @@ fail1: /* clean up only allocated memory */
isc_mem_put(adb->mctx, adb->name_refcnt,
sizeof(*adb->name_refcnt) * adb->nnames);
}
if (adb->nmp != NULL) {
isc_mempool_destroy(&adb->nmp);
}
if (adb->nhmp != NULL) {
isc_mempool_destroy(&adb->nhmp);
}
if (adb->limp != NULL) {
isc_mempool_destroy(&adb->limp);
}
if (adb->emp != NULL) {
isc_mempool_destroy(&adb->emp);
}
if (adb->ahmp != NULL) {
isc_mempool_destroy(&adb->ahmp);
}
if (adb->aimp != NULL) {
isc_mempool_destroy(&adb->aimp);
}
if (adb->afmp != NULL) {
isc_mempool_destroy(&adb->afmp);
}
isc_mutex_destroy(&adb->namescntlock);
isc_mutex_destroy(&adb->entriescntlock);
isc_mutex_destroy(&adb->overmemlock);
isc_mutex_destroy(&adb->reflock);
isc_mutex_destroy(&adb->mplock);
isc_mutex_destroy(&adb->lock);
if (adb->excl != NULL) {
isc_task_detach(&adb->excl);
@@ -2918,7 +2819,7 @@ dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
zeroirefcnt = (adb->irefcnt == 0);
if (adb->shutting_down && zeroirefcnt &&
isc_mempool_getallocated(adb->ahmp) == 0)
isc_refcount_current(&adb->ahrefcnt) == 0)
{
/*
* We're already shutdown. Send the event.
@@ -3523,9 +3424,11 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
fprintf(f, "; [plain success/timeout]\n;\n");
if (debug) {
LOCK(&adb->reflock);
fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
fprintf(f,
"; addr %p, erefcnt %u, irefcnt %u, finds out "
"%" PRIuFAST32 "\n",
adb, adb->erefcnt, adb->irefcnt,
isc_mempool_getallocated(adb->nhmp));
isc_refcount_current(&adb->nhrefcnt));
UNLOCK(&adb->reflock);
}