2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +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

@@ -153,7 +153,6 @@ unsigned int digestbits = 0;
isc_buffer_t *namebuf = NULL; isc_buffer_t *namebuf = NULL;
dns_tsigkey_t *tsigkey = NULL; dns_tsigkey_t *tsigkey = NULL;
bool validated = true; bool validated = true;
isc_mempool_t *commctx = NULL;
bool debugging = false; bool debugging = false;
bool debugtiming = false; bool debugtiming = false;
bool memdebugging = false; bool memdebugging = false;
@@ -1367,15 +1366,6 @@ setup_libs(void) {
check_result(result, "dst_lib_init"); check_result(result, "dst_lib_init");
is_dst_up = true; is_dst_up = true;
isc_mempool_create(mctx, COMMSIZE, &commctx);
isc_mempool_setname(commctx, "COMMPOOL");
/*
* 6 and 2 set as reasonable parameters for 3 or 4 nameserver
* systems.
*/
isc_mempool_setfreemax(commctx, 6);
isc_mempool_setfillcount(commctx, 2);
isc_mutex_init(&lookup_lock); isc_mutex_init(&lookup_lock);
} }
@@ -1559,7 +1549,7 @@ _destroy_lookup(dig_lookup_t *lookup) {
isc_buffer_free(&lookup->querysig); isc_buffer_free(&lookup->querysig);
} }
if (lookup->sendspace != NULL) { if (lookup->sendspace != NULL) {
isc_mempool_put(commctx, lookup->sendspace); isc_mem_put(mctx, lookup->sendspace, COMMSIZE);
} }
if (lookup->tsigctx != NULL) { if (lookup->tsigctx != NULL) {
@@ -1645,8 +1635,8 @@ destroy_query(dig_query_t *query, const char *file, unsigned int line) {
INSIST(query->recvspace != NULL); INSIST(query->recvspace != NULL);
isc_mempool_put(commctx, query->recvspace); isc_mem_put(mctx, query->recvspace, COMMSIZE);
isc_mempool_put(commctx, query->tmpsendspace); isc_mem_put(mctx, query->tmpsendspace, COMMSIZE);
query->magic = 0; query->magic = 0;
isc_mem_free(mctx, query); isc_mem_free(mctx, query);
@@ -2087,8 +2077,8 @@ _new_query(dig_lookup_t *lookup, char *servname, char *userarg,
.userarg = userarg, .userarg = userarg,
.first_pass = true, .first_pass = true,
.warn_id = true, .warn_id = true,
.recvspace = isc_mempool_get(commctx), .recvspace = isc_mem_get(mctx, COMMSIZE),
.tmpsendspace = isc_mempool_get(commctx) }; .tmpsendspace = isc_mem_get(mctx, COMMSIZE) };
lookup_attach(lookup, &query->lookup); lookup_attach(lookup, &query->lookup);
@@ -2381,10 +2371,7 @@ setup_lookup(dig_lookup_t *lookup) {
check_result(result, "dns_message_settsigkey"); check_result(result, "dns_message_settsigkey");
} }
lookup->sendspace = isc_mempool_get(commctx); lookup->sendspace = isc_mem_get(mctx, COMMSIZE);
if (lookup->sendspace == NULL) {
fatal("memory allocation failure");
}
result = dns_compress_init(&cctx, -1, mctx); result = dns_compress_init(&cctx, -1, mctx);
check_result(result, "dns_compress_init"); check_result(result, "dns_compress_init");
@@ -4250,10 +4237,6 @@ destroy_libs(void) {
clear_searchlist(); clear_searchlist();
if (commctx != NULL) {
debug("freeing commctx");
isc_mempool_destroy(&commctx);
}
if (tsigkey != NULL) { if (tsigkey != NULL) {
debug("freeing key %p", tsigkey); debug("freeing key %p", tsigkey);
dns_tsigkey_detach(&tsigkey); dns_tsigkey_detach(&tsigkey);

View File

@@ -77,12 +77,6 @@ typedef struct filter_instance {
ns_plugin_t *module; ns_plugin_t *module;
isc_mem_t *mctx; isc_mem_t *mctx;
/*
* Memory pool for use with persistent data.
*/
isc_mempool_t *datapool;
isc_mutex_t plock;
/* /*
* Hash table associating a client object with its persistent data. * Hash table associating a client object with its persistent data.
*/ */
@@ -353,25 +347,9 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
cfg_line, mctx, lctx, actx)); cfg_line, mctx, lctx, actx));
} }
isc_mempool_create(mctx, sizeof(filter_data_t), &inst->datapool);
CHECK(isc_ht_init(&inst->ht, mctx, 16)); CHECK(isc_ht_init(&inst->ht, mctx, 16));
isc_mutex_init(&inst->hlock); isc_mutex_init(&inst->hlock);
/*
* Fill the mempool with 1K filter_a state objects at
* a time; ideally after a single allocation, the mempool will
* have enough to handle all the simultaneous queries the system
* requires and it won't be necessary to allocate more.
*
* We don't set any limit on the number of free state objects
* so that they'll always be returned to the pool and not
* freed until the pool is destroyed on shutdown.
*/
isc_mempool_setfillcount(inst->datapool, 1024);
isc_mempool_setfreemax(inst->datapool, UINT_MAX);
isc_mutex_init(&inst->plock);
isc_mempool_associatelock(inst->datapool, &inst->plock);
/* /*
* Set hook points in the view's hooktable. * Set hook points in the view's hooktable.
*/ */
@@ -427,10 +405,6 @@ plugin_destroy(void **instp) {
isc_ht_destroy(&inst->ht); isc_ht_destroy(&inst->ht);
isc_mutex_destroy(&inst->hlock); isc_mutex_destroy(&inst->hlock);
} }
if (inst->datapool != NULL) {
isc_mempool_destroy(&inst->datapool);
isc_mutex_destroy(&inst->plock);
}
if (inst->a_acl != NULL) { if (inst->a_acl != NULL) {
dns_acl_detach(&inst->a_acl); dns_acl_detach(&inst->a_acl);
} }
@@ -512,10 +486,7 @@ client_state_create(const query_ctx_t *qctx, filter_instance_t *inst) {
filter_data_t *client_state; filter_data_t *client_state;
isc_result_t result; isc_result_t result;
client_state = isc_mempool_get(inst->datapool); client_state = isc_mem_get(inst->mctx, sizeof(*client_state));
if (client_state == NULL) {
return;
}
client_state->mode = NONE; client_state->mode = NONE;
client_state->flags = 0; client_state->flags = 0;
@@ -542,7 +513,7 @@ client_state_destroy(const query_ctx_t *qctx, filter_instance_t *inst) {
UNLOCK(&inst->hlock); UNLOCK(&inst->hlock);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_mempool_put(inst->datapool, client_state); isc_mem_put(inst->mctx, client_state, sizeof(*client_state));
} }
/*% /*%

View File

@@ -77,12 +77,6 @@ typedef struct filter_instance {
ns_plugin_t *module; ns_plugin_t *module;
isc_mem_t *mctx; isc_mem_t *mctx;
/*
* Memory pool for use with persistent data.
*/
isc_mempool_t *datapool;
isc_mutex_t plock;
/* /*
* Hash table associating a client object with its persistent data. * Hash table associating a client object with its persistent data.
*/ */
@@ -356,25 +350,9 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
cfg_line, mctx, lctx, actx)); cfg_line, mctx, lctx, actx));
} }
isc_mempool_create(mctx, sizeof(filter_data_t), &inst->datapool);
CHECK(isc_ht_init(&inst->ht, mctx, 16)); CHECK(isc_ht_init(&inst->ht, mctx, 16));
isc_mutex_init(&inst->hlock); isc_mutex_init(&inst->hlock);
/*
* Fill the mempool with 1K filter_aaaa state objects at
* a time; ideally after a single allocation, the mempool will
* have enough to handle all the simultaneous queries the system
* requires and it won't be necessary to allocate more.
*
* We don't set any limit on the number of free state objects
* so that they'll always be returned to the pool and not
* freed until the pool is destroyed on shutdown.
*/
isc_mempool_setfillcount(inst->datapool, 1024);
isc_mempool_setfreemax(inst->datapool, UINT_MAX);
isc_mutex_init(&inst->plock);
isc_mempool_associatelock(inst->datapool, &inst->plock);
/* /*
* Set hook points in the view's hooktable. * Set hook points in the view's hooktable.
*/ */
@@ -430,10 +408,6 @@ plugin_destroy(void **instp) {
isc_ht_destroy(&inst->ht); isc_ht_destroy(&inst->ht);
isc_mutex_destroy(&inst->hlock); isc_mutex_destroy(&inst->hlock);
} }
if (inst->datapool != NULL) {
isc_mempool_destroy(&inst->datapool);
isc_mutex_destroy(&inst->plock);
}
if (inst->aaaa_acl != NULL) { if (inst->aaaa_acl != NULL) {
dns_acl_detach(&inst->aaaa_acl); dns_acl_detach(&inst->aaaa_acl);
} }
@@ -515,10 +489,7 @@ client_state_create(const query_ctx_t *qctx, filter_instance_t *inst) {
filter_data_t *client_state; filter_data_t *client_state;
isc_result_t result; isc_result_t result;
client_state = isc_mempool_get(inst->datapool); client_state = isc_mem_get(inst->mctx, sizeof(*client_state));
if (client_state == NULL) {
return;
}
client_state->mode = NONE; client_state->mode = NONE;
client_state->flags = 0; client_state->flags = 0;
@@ -545,7 +516,7 @@ client_state_destroy(const query_ctx_t *qctx, filter_instance_t *inst) {
UNLOCK(&inst->hlock); UNLOCK(&inst->hlock);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_mempool_put(inst->datapool, client_state); isc_mem_put(inst->mctx, client_state, sizeof(*client_state));
} }
/*% /*%

View File

@@ -53,7 +53,6 @@
typedef struct async_instance { typedef struct async_instance {
ns_plugin_t *module; ns_plugin_t *module;
isc_mem_t *mctx; isc_mem_t *mctx;
isc_mempool_t *datapool;
isc_ht_t *ht; isc_ht_t *ht;
isc_mutex_t hlock; isc_mutex_t hlock;
isc_log_t *lctx; isc_log_t *lctx;
@@ -146,7 +145,6 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
*inst = (async_instance_t){ .mctx = NULL }; *inst = (async_instance_t){ .mctx = NULL };
isc_mem_attach(mctx, &inst->mctx); isc_mem_attach(mctx, &inst->mctx);
isc_mempool_create(mctx, sizeof(state_t), &inst->datapool);
CHECK(isc_ht_init(&inst->ht, mctx, 16)); CHECK(isc_ht_init(&inst->ht, mctx, 16));
isc_mutex_init(&inst->hlock); isc_mutex_init(&inst->hlock);
@@ -194,9 +192,6 @@ plugin_destroy(void **instp) {
isc_ht_destroy(&inst->ht); isc_ht_destroy(&inst->ht);
isc_mutex_destroy(&inst->hlock); isc_mutex_destroy(&inst->hlock);
} }
if (inst->datapool != NULL) {
isc_mempool_destroy(&inst->datapool);
}
isc_mem_putanddetach(&inst->mctx, inst, sizeof(*inst)); isc_mem_putanddetach(&inst->mctx, inst, sizeof(*inst));
*instp = NULL; *instp = NULL;
@@ -230,7 +225,7 @@ client_state_create(const query_ctx_t *qctx, async_instance_t *inst) {
state_t *state = NULL; state_t *state = NULL;
isc_result_t result; isc_result_t result;
state = isc_mempool_get(inst->datapool); state = isc_mem_get(inst->mctx, sizeof(*state));
if (state == NULL) { if (state == NULL) {
return; return;
} }
@@ -257,7 +252,7 @@ client_state_destroy(const query_ctx_t *qctx, async_instance_t *inst) {
UNLOCK(&inst->hlock); UNLOCK(&inst->hlock);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_mempool_put(inst->datapool, state); isc_mem_put(inst->mctx, state, sizeof(*state));
} }
static ns_hookresult_t static ns_hookresult_t

View File

@@ -112,14 +112,8 @@ struct dns_adb {
unsigned int irefcnt; unsigned int irefcnt;
unsigned int erefcnt; unsigned int erefcnt;
isc_mutex_t mplock; isc_refcount_t ahrefcnt;
isc_mempool_t *nmp; /*%< dns_adbname_t */ isc_refcount_t nhrefcnt;
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 */
/*! /*!
* Bucketized locks and lists for names. * 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); newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n); newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * 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. * 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); newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n); newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * 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. * Initialise the new resources.
@@ -1734,10 +1717,7 @@ static inline dns_adbname_t *
new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) { new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) {
dns_adbname_t *name; dns_adbname_t *name;
name = isc_mempool_get(adb->nmp); name = isc_mem_get(adb->mctx, sizeof(*name));
if (name == NULL) {
return (NULL);
}
dns_name_init(&name->name, NULL); dns_name_init(&name->name, NULL);
dns_name_dup(dnsname, adb->mctx, &name->name); 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; n->magic = 0;
dns_name_free(&n->name, adb->mctx); dns_name_free(&n->name, adb->mctx);
isc_mempool_put(adb->nmp, n); isc_mem_put(adb->mctx, n, sizeof(*n));
LOCK(&adb->namescntlock); LOCK(&adb->namescntlock);
adb->namescnt--; adb->namescnt--;
dec_adbstats(adb, dns_adbstats_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) { new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
dns_adbnamehook_t *nh; dns_adbnamehook_t *nh;
nh = isc_mempool_get(adb->nhmp); nh = isc_mem_get(adb->mctx, sizeof(*nh));
if (nh == NULL) { isc_refcount_increment0(&adb->nhrefcnt);
return (NULL);
}
nh->magic = DNS_ADBNAMEHOOK_MAGIC; nh->magic = DNS_ADBNAMEHOOK_MAGIC;
nh->entry = entry; nh->entry = entry;
@@ -1830,7 +1808,9 @@ free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
INSIST(!ISC_LINK_LINKED(nh, plink)); INSIST(!ISC_LINK_LINKED(nh, plink));
nh->magic = 0; 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 * 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_rdatatype_t qtype) {
dns_adblameinfo_t *li; dns_adblameinfo_t *li;
li = isc_mempool_get(adb->limp); li = isc_mem_get(adb->mctx, sizeof(*li));
if (li == NULL) {
return (NULL);
}
dns_name_init(&li->qname, NULL); dns_name_init(&li->qname, NULL);
dns_name_dup(qname, adb->mctx, &li->qname); 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; li->magic = 0;
isc_mempool_put(adb->limp, li); isc_mem_put(adb->mctx, li, sizeof(*li));
} }
static inline dns_adbentry_t * static inline dns_adbentry_t *
new_adbentry(dns_adb_t *adb) { new_adbentry(dns_adb_t *adb) {
dns_adbentry_t *e; dns_adbentry_t *e;
e = isc_mempool_get(adb->emp); e = isc_mem_get(adb->mctx, sizeof(*e));
if (e == NULL) {
return (NULL);
}
e->magic = DNS_ADBENTRY_MAGIC; e->magic = DNS_ADBENTRY_MAGIC;
e->lock_bucket = DNS_ADB_INVALIDBUCKET; 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); li = ISC_LIST_HEAD(e->lameinfo);
} }
isc_mempool_put(adb->emp, e); isc_mem_put(adb->mctx, e, sizeof(*e));
LOCK(&adb->entriescntlock); LOCK(&adb->entriescntlock);
adb->entriescnt--; adb->entriescnt--;
dec_adbstats(adb, dns_adbstats_entriescnt); dec_adbstats(adb, dns_adbstats_entriescnt);
@@ -1955,10 +1929,8 @@ static inline dns_adbfind_t *
new_adbfind(dns_adb_t *adb) { new_adbfind(dns_adb_t *adb) {
dns_adbfind_t *h; dns_adbfind_t *h;
h = isc_mempool_get(adb->ahmp); h = isc_mem_get(adb->mctx, sizeof(*h));
if (h == NULL) { isc_refcount_increment0(&adb->ahrefcnt);
return (NULL);
}
/* /*
* Public members. * Public members.
@@ -1993,10 +1965,7 @@ static inline dns_adbfetch_t *
new_adbfetch(dns_adb_t *adb) { new_adbfetch(dns_adb_t *adb) {
dns_adbfetch_t *f; dns_adbfetch_t *f;
f = isc_mempool_get(adb->afmp); f = isc_mem_get(adb->mctx, sizeof(*f));
if (f == NULL) {
return (NULL);
}
f->magic = 0; f->magic = 0;
f->fetch = NULL; f->fetch = NULL;
@@ -2022,7 +1991,7 @@ free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
dns_rdataset_disassociate(&f->rdataset); dns_rdataset_disassociate(&f->rdataset);
} }
isc_mempool_put(adb->afmp, f); isc_mem_put(adb->mctx, f, sizeof(*f));
} }
static inline bool static inline bool
@@ -2042,7 +2011,9 @@ free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
find->magic = 0; find->magic = 0;
isc_mutex_destroy(&find->lock); 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)); 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) { new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
dns_adbaddrinfo_t *ai; dns_adbaddrinfo_t *ai;
ai = isc_mempool_get(adb->aimp); ai = isc_mem_get(adb->mctx, sizeof(*ai));
if (ai == NULL) {
return (NULL);
}
ai->magic = DNS_ADBADDRINFO_MAGIC; ai->magic = DNS_ADBADDRINFO_MAGIC;
ai->sockaddr = entry->sockaddr; ai->sockaddr = entry->sockaddr;
@@ -2085,7 +2053,7 @@ free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
ai->magic = 0; 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_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_mutexblock_destroy(adb->entrylocks, adb->nentries);
isc_mem_put(adb->mctx, adb->entries, isc_mem_put(adb->mctx, adb->entries,
sizeof(*adb->entries) * adb->nentries); sizeof(*adb->entries) * adb->nentries);
@@ -2572,7 +2532,6 @@ destroy(dns_adb_t *adb) {
isc_mutex_destroy(&adb->reflock); isc_mutex_destroy(&adb->reflock);
isc_mutex_destroy(&adb->lock); isc_mutex_destroy(&adb->lock);
isc_mutex_destroy(&adb->mplock);
isc_mutex_destroy(&adb->overmemlock); isc_mutex_destroy(&adb->overmemlock);
isc_mutex_destroy(&adb->entriescntlock); isc_mutex_destroy(&adb->entriescntlock);
isc_mutex_destroy(&adb->namescntlock); 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->magic = 0;
adb->erefcnt = 1; adb->erefcnt = 1;
adb->irefcnt = 0; 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->task = NULL;
adb->excl = NULL; adb->excl = NULL;
adb->mctx = 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_mem_attach(mem, &adb->mctx);
isc_mutex_init(&adb->lock); isc_mutex_init(&adb->lock);
isc_mutex_init(&adb->mplock);
isc_mutex_init(&adb->reflock); isc_mutex_init(&adb->reflock);
isc_mutex_init(&adb->overmemlock); isc_mutex_init(&adb->overmemlock);
isc_mutex_init(&adb->entriescntlock); 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 { \ do { \
(adb)->el = isc_mem_get((adb)->mctx, \ (adb)->el = isc_mem_get((adb)->mctx, \
sizeof(*(adb)->el) * (adb)->nentries); \ sizeof(*(adb)->el) * (adb)->nentries); \
if ((adb)->el == NULL) { \
result = ISC_R_NOMEMORY; \
goto fail1; \
} \
} while (0) } while (0)
ALLOCENTRY(adb, entries); ALLOCENTRY(adb, entries);
ALLOCENTRY(adb, deadentries); ALLOCENTRY(adb, deadentries);
@@ -2696,10 +2643,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
do { \ do { \
(adb)->el = isc_mem_get((adb)->mctx, \ (adb)->el = isc_mem_get((adb)->mctx, \
sizeof(*(adb)->el) * (adb)->nnames); \ sizeof(*(adb)->el) * (adb)->nnames); \
if ((adb)->el == NULL) { \
result = ISC_R_NOMEMORY; \
goto fail1; \
} \
} while (0) } while (0)
ALLOCNAME(adb, names); ALLOCNAME(adb, names);
ALLOCNAME(adb, deadnames); 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); isc_mutexblock_init(adb->entrylocks, adb->nentries);
/* isc_refcount_init(&adb->ahrefcnt, 0);
* Memory pools isc_refcount_init(&adb->nhrefcnt, 0);
*/
#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
/* /*
* Allocate an internal task. * Allocate an internal task.
@@ -2786,7 +2710,6 @@ fail2:
isc_mutexblock_destroy(adb->entrylocks, adb->nentries); isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
isc_mutexblock_destroy(adb->namelocks, adb->nnames); isc_mutexblock_destroy(adb->namelocks, adb->nnames);
fail1: /* clean up only allocated memory */
if (adb->entries != NULL) { if (adb->entries != NULL) {
isc_mem_put(adb->mctx, adb->entries, isc_mem_put(adb->mctx, adb->entries,
sizeof(*adb->entries) * adb->nentries); sizeof(*adb->entries) * adb->nentries);
@@ -2827,33 +2750,11 @@ fail1: /* clean up only allocated memory */
isc_mem_put(adb->mctx, adb->name_refcnt, isc_mem_put(adb->mctx, adb->name_refcnt,
sizeof(*adb->name_refcnt) * adb->nnames); 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->namescntlock);
isc_mutex_destroy(&adb->entriescntlock); isc_mutex_destroy(&adb->entriescntlock);
isc_mutex_destroy(&adb->overmemlock); isc_mutex_destroy(&adb->overmemlock);
isc_mutex_destroy(&adb->reflock); isc_mutex_destroy(&adb->reflock);
isc_mutex_destroy(&adb->mplock);
isc_mutex_destroy(&adb->lock); isc_mutex_destroy(&adb->lock);
if (adb->excl != NULL) { if (adb->excl != NULL) {
isc_task_detach(&adb->excl); 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); zeroirefcnt = (adb->irefcnt == 0);
if (adb->shutting_down && zeroirefcnt && if (adb->shutting_down && zeroirefcnt &&
isc_mempool_getallocated(adb->ahmp) == 0) isc_refcount_current(&adb->ahrefcnt) == 0)
{ {
/* /*
* We're already shutdown. Send the event. * 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"); fprintf(f, "; [plain success/timeout]\n;\n");
if (debug) { if (debug) {
LOCK(&adb->reflock); 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, adb, adb->erefcnt, adb->irefcnt,
isc_mempool_getallocated(adb->nhmp)); isc_refcount_current(&adb->nhrefcnt));
UNLOCK(&adb->reflock); UNLOCK(&adb->reflock);
} }

View File

@@ -74,17 +74,7 @@ struct dns_dispatchmgr {
unsigned int buffersize; /*%< size of each buffer */ unsigned int buffersize; /*%< size of each buffer */
unsigned int maxbuffers; /*%< max buffers */ unsigned int maxbuffers; /*%< max buffers */
/* Locked internally. */ isc_refcount_t irefs;
isc_mutex_t depool_lock;
isc_mempool_t *depool; /*%< pool for dispatch events */
isc_mutex_t rpool_lock;
isc_mempool_t *rpool; /*%< pool for replies */
isc_mutex_t dpool_lock;
isc_mempool_t *dpool; /*%< dispatch allocations */
isc_mutex_t bpool_lock;
isc_mempool_t *bpool; /*%< pool for buffers */
isc_mutex_t spool_lock;
isc_mempool_t *spool; /*%< pool for dispsocks */
/*% /*%
* Locked by qid->lock if qid exists; otherwise, can be used without * Locked by qid->lock if qid exists; otherwise, can be used without
@@ -206,8 +196,7 @@ struct dns_dispatch {
unsigned int maxrequests; /*%< max requests */ unsigned int maxrequests; /*%< max requests */
isc_event_t *ctlevent; isc_event_t *ctlevent;
isc_mutex_t sepool_lock; isc_mem_t *sepool; /*%< pool for socket events */
isc_mempool_t *sepool; /*%< pool for socket events */
/*% Locked by mgr->lock. */ /*% Locked by mgr->lock. */
ISC_LINK(dns_dispatch_t) link; ISC_LINK(dns_dispatch_t) link;
@@ -232,7 +221,6 @@ struct dns_dispatch {
dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ dns_tcpmsg_t tcpmsg; /*%< for tcp streams */
dns_qid_t *qid; dns_qid_t *qid;
dispportlist_t *port_table; /*%< hold ports 'owned' by us */ dispportlist_t *port_table; /*%< hold ports 'owned' by us */
isc_mempool_t *portpool; /*%< port table entries */
}; };
#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ') #define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
@@ -547,8 +535,7 @@ destroy_disp(isc_task_t *task, isc_event_t *event) {
disp->socket, disp->task[0]); /* XXXX */ disp->socket, disp->task[0]); /* XXXX */
if (disp->sepool != NULL) { if (disp->sepool != NULL) {
isc_mempool_destroy(&disp->sepool); isc_mem_destroy(&disp->sepool);
isc_mutex_destroy(&disp->sepool_lock);
} }
if (disp->socket != NULL) { if (disp->socket != NULL) {
@@ -601,10 +588,7 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
REQUIRE(disp->port_table != NULL); REQUIRE(disp->port_table != NULL);
portentry = isc_mempool_get(disp->portpool); portentry = isc_mem_get(disp->mgr->mctx, sizeof(*portentry));
if (portentry == NULL) {
return (portentry);
}
portentry->port = port; portentry->port = port;
isc_refcount_init(&portentry->refs, 1); isc_refcount_init(&portentry->refs, 1);
@@ -633,7 +617,7 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
ISC_LIST_UNLINK(disp->port_table[portentry->port % ISC_LIST_UNLINK(disp->port_table[portentry->port %
DNS_DISPATCH_PORTTABLESIZE], DNS_DISPATCH_PORTTABLESIZE],
portentry, link); portentry, link);
isc_mempool_put(disp->portpool, portentry); isc_mem_put(disp->mgr->mctx, portentry, sizeof(*portentry));
} }
} }
@@ -703,10 +687,7 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest,
sock = dispsock->socket; sock = dispsock->socket;
dispsock->socket = NULL; dispsock->socket = NULL;
} else { } else {
dispsock = isc_mempool_get(mgr->spool); dispsock = isc_mem_get(mgr->mctx, sizeof(*dispsock));
if (dispsock == NULL) {
return (ISC_R_NOMEMORY);
}
disp->nsockets++; disp->nsockets++;
dispsock->socket = NULL; dispsock->socket = NULL;
@@ -832,7 +813,7 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
if (dispsock->task != NULL) { if (dispsock->task != NULL) {
isc_task_detach(&dispsock->task); isc_task_detach(&dispsock->task);
} }
isc_mempool_put(disp->mgr->spool, dispsock); isc_mem_put(disp->mgr->mctx, dispsock, sizeof(*dispsock));
} }
/*% /*%
@@ -911,7 +892,7 @@ entry_search(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id,
static void static void
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
isc_mempool_t *bpool; unsigned int buffersize;
INSIST(buf != NULL && len != 0); INSIST(buf != NULL && len != 0);
switch (disp->socktype) { switch (disp->socktype) {
@@ -925,9 +906,9 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
INSIST(disp->mgr->buffers > 0); INSIST(disp->mgr->buffers > 0);
INSIST(len == disp->mgr->buffersize); INSIST(len == disp->mgr->buffersize);
disp->mgr->buffers--; disp->mgr->buffers--;
bpool = disp->mgr->bpool; buffersize = disp->mgr->buffersize;
UNLOCK(&disp->mgr->buffer_lock); UNLOCK(&disp->mgr->buffer_lock);
isc_mempool_put(bpool, buf); isc_mem_put(disp->mgr->mctx, buf, buffersize);
break; break;
default: default:
INSIST(0); INSIST(0);
@@ -937,34 +918,25 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
static void * static void *
allocate_udp_buffer(dns_dispatch_t *disp) { allocate_udp_buffer(dns_dispatch_t *disp) {
isc_mempool_t *bpool; unsigned int buffersize;
void *temp;
LOCK(&disp->mgr->buffer_lock); LOCK(&disp->mgr->buffer_lock);
if (disp->mgr->buffers >= disp->mgr->maxbuffers) { if (disp->mgr->buffers >= disp->mgr->maxbuffers) {
UNLOCK(&disp->mgr->buffer_lock); UNLOCK(&disp->mgr->buffer_lock);
return (NULL); return (NULL);
} }
bpool = disp->mgr->bpool; buffersize = disp->mgr->buffersize;
disp->mgr->buffers++; disp->mgr->buffers++;
UNLOCK(&disp->mgr->buffer_lock); UNLOCK(&disp->mgr->buffer_lock);
temp = isc_mempool_get(bpool); return (isc_mem_get(disp->mgr->mctx, buffersize));
if (temp == NULL) {
LOCK(&disp->mgr->buffer_lock);
disp->mgr->buffers--;
UNLOCK(&disp->mgr->buffer_lock);
}
return (temp);
} }
static inline void static inline void
free_sevent(isc_event_t *ev) { free_sevent(isc_event_t *ev) {
isc_mempool_t *pool = ev->ev_destroy_arg; isc_mem_t *pool = ev->ev_destroy_arg;
isc_socketevent_t *sev = (isc_socketevent_t *)ev; isc_socketevent_t *sev = (isc_socketevent_t *)ev;
isc_mempool_put(pool, sev); isc_mem_put(pool, sev, sizeof(*sev));
} }
static inline isc_socketevent_t * static inline isc_socketevent_t *
@@ -973,10 +945,7 @@ allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock, isc_eventtype_t type,
isc_socketevent_t *ev; isc_socketevent_t *ev;
void *deconst_arg; void *deconst_arg;
ev = isc_mempool_get(disp->sepool); ev = isc_mem_get(disp->sepool, sizeof(*ev));
if (ev == NULL) {
return (NULL);
}
DE_CONST(arg, deconst_arg); DE_CONST(arg, deconst_arg);
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, action, deconst_arg, ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, action, deconst_arg,
sock, free_sevent, disp->sepool); sock, free_sevent, disp->sepool);
@@ -999,17 +968,16 @@ free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
return; return;
} }
isc_mempool_put(disp->mgr->depool, ev); isc_refcount_decrement(&disp->mgr->irefs);
isc_mem_put(disp->mgr->mctx, ev, sizeof(*ev));
} }
static inline dns_dispatchevent_t * static inline dns_dispatchevent_t *
allocate_devent(dns_dispatch_t *disp) { allocate_devent(dns_dispatch_t *disp) {
dns_dispatchevent_t *ev; dns_dispatchevent_t *ev;
ev = isc_mempool_get(disp->mgr->depool); ev = isc_mem_get(disp->mgr->mctx, sizeof(*ev));
if (ev == NULL) { isc_refcount_increment0(&disp->mgr->irefs);
return (NULL);
}
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL, ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL,
NULL); NULL);
@@ -1627,25 +1595,15 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
static bool static bool
destroy_mgr_ok(dns_dispatchmgr_t *mgr) { destroy_mgr_ok(dns_dispatchmgr_t *mgr) {
mgr_log(mgr, LVL(90), mgr_log(mgr, LVL(90),
"destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, " "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, ",
"depool=%d, rpool=%d, dpool=%d", MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list));
MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),
isc_mempool_getallocated(mgr->depool),
isc_mempool_getallocated(mgr->rpool),
isc_mempool_getallocated(mgr->dpool));
if (!MGR_IS_SHUTTINGDOWN(mgr)) { if (!MGR_IS_SHUTTINGDOWN(mgr)) {
return (false); return (false);
} }
if (!ISC_LIST_EMPTY(mgr->list)) { if (!ISC_LIST_EMPTY(mgr->list)) {
return (false); return (false);
} }
if (isc_mempool_getallocated(mgr->depool) != 0) { if (isc_refcount_current(&mgr->irefs) != 0) {
return (false);
}
if (isc_mempool_getallocated(mgr->rpool) != 0) {
return (false);
}
if (isc_mempool_getallocated(mgr->dpool) != 0) {
return (false); return (false);
} }
@@ -1666,22 +1624,6 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
isc_mutex_destroy(&mgr->lock); isc_mutex_destroy(&mgr->lock);
mgr->state = 0; mgr->state = 0;
isc_mempool_destroy(&mgr->depool);
isc_mempool_destroy(&mgr->rpool);
isc_mempool_destroy(&mgr->dpool);
if (mgr->bpool != NULL) {
isc_mempool_destroy(&mgr->bpool);
}
if (mgr->spool != NULL) {
isc_mempool_destroy(&mgr->spool);
}
isc_mutex_destroy(&mgr->spool_lock);
isc_mutex_destroy(&mgr->bpool_lock);
isc_mutex_destroy(&mgr->dpool_lock);
isc_mutex_destroy(&mgr->rpool_lock);
isc_mutex_destroy(&mgr->depool_lock);
if (mgr->qid != NULL) { if (mgr->qid != NULL) {
qid_destroy(mgr->mctx, &mgr->qid); qid_destroy(mgr->mctx, &mgr->qid);
} }
@@ -1791,61 +1733,17 @@ dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) {
REQUIRE(mgrp != NULL && *mgrp == NULL); REQUIRE(mgrp != NULL && *mgrp == NULL);
mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t)); mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
*mgr = (dns_dispatchmgr_t){ 0 };
mgr->mctx = NULL;
isc_mem_attach(mctx, &mgr->mctx); isc_mem_attach(mctx, &mgr->mctx);
mgr->blackhole = NULL;
mgr->stats = NULL;
isc_mutex_init(&mgr->lock); isc_mutex_init(&mgr->lock);
isc_mutex_init(&mgr->buffer_lock); isc_mutex_init(&mgr->buffer_lock);
isc_mutex_init(&mgr->depool_lock);
isc_mutex_init(&mgr->rpool_lock);
isc_mutex_init(&mgr->dpool_lock);
isc_mutex_init(&mgr->bpool_lock);
isc_mutex_init(&mgr->spool_lock);
mgr->depool = NULL; isc_refcount_init(&mgr->irefs, 0);
isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
&mgr->depool);
mgr->rpool = NULL;
isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t), &mgr->rpool);
mgr->dpool = NULL;
isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t), &mgr->dpool);
isc_mempool_setname(mgr->depool, "dispmgr_depool");
isc_mempool_setmaxalloc(mgr->depool, 32768);
isc_mempool_setfreemax(mgr->depool, 32768);
isc_mempool_associatelock(mgr->depool, &mgr->depool_lock);
isc_mempool_setfillcount(mgr->depool, 32);
isc_mempool_setname(mgr->rpool, "dispmgr_rpool");
isc_mempool_setmaxalloc(mgr->rpool, 32768);
isc_mempool_setfreemax(mgr->rpool, 32768);
isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock);
isc_mempool_setfillcount(mgr->rpool, 32);
isc_mempool_setname(mgr->dpool, "dispmgr_dpool");
isc_mempool_setmaxalloc(mgr->dpool, 32768);
isc_mempool_setfreemax(mgr->dpool, 32768);
isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
isc_mempool_setfillcount(mgr->dpool, 32);
mgr->buffers = 0;
mgr->buffersize = 0;
mgr->maxbuffers = 0;
mgr->bpool = NULL;
mgr->spool = NULL;
mgr->qid = NULL;
mgr->state = 0;
ISC_LIST_INIT(mgr->list); ISC_LIST_INIT(mgr->list);
mgr->v4ports = NULL;
mgr->v6ports = NULL;
mgr->nv4ports = 0;
mgr->nv6ports = 0;
mgr->magic = DNS_DISPATCHMGR_MAGIC; mgr->magic = DNS_DISPATCHMGR_MAGIC;
result = create_default_portset(mctx, &v4portset); result = create_default_portset(mctx, &v4portset);
@@ -1870,14 +1768,6 @@ dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) {
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
kill_dpool: kill_dpool:
isc_mempool_destroy(&mgr->dpool);
isc_mempool_destroy(&mgr->rpool);
isc_mempool_destroy(&mgr->depool);
isc_mutex_destroy(&mgr->spool_lock);
isc_mutex_destroy(&mgr->bpool_lock);
isc_mutex_destroy(&mgr->dpool_lock);
isc_mutex_destroy(&mgr->rpool_lock);
isc_mutex_destroy(&mgr->depool_lock);
isc_mutex_destroy(&mgr->buffer_lock); isc_mutex_destroy(&mgr->buffer_lock);
isc_mutex_destroy(&mgr->lock); isc_mutex_destroy(&mgr->lock);
isc_mem_putanddetach(&mctx, mgr, sizeof(dns_dispatchmgr_t)); isc_mem_putanddetach(&mctx, mgr, sizeof(dns_dispatchmgr_t));
@@ -1965,6 +1855,7 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, unsigned int buffersize,
REQUIRE(maxbuffers > 0); REQUIRE(maxbuffers > 0);
REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
REQUIRE(increment > buckets); REQUIRE(increment > buckets);
UNUSED(maxrequests);
/* /*
* Keep some number of items around. This should be a config * Keep some number of items around. This should be a config
@@ -1985,48 +1876,15 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, unsigned int buffersize,
LOCK(&mgr->buffer_lock); LOCK(&mgr->buffer_lock);
/* Create or adjust buffer pool */ if (maxbuffers > mgr->maxbuffers) {
if (mgr->bpool != NULL) { mgr->maxbuffers = maxbuffers;
/*
* We only increase the maxbuffers to avoid accidental buffer
* shortage. Ideally we'd separate the manager-wide maximum
* from per-dispatch limits and respect the latter within the
* global limit. But at this moment that's deemed to be
* overkilling and isn't worth additional implementation
* complexity.
*/
if (maxbuffers > mgr->maxbuffers) {
isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
isc_mempool_setfreemax(mgr->bpool, maxbuffers);
mgr->maxbuffers = maxbuffers;
}
} else {
isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool);
isc_mempool_setname(mgr->bpool, "dispmgr_bpool");
isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
isc_mempool_setfreemax(mgr->bpool, maxbuffers);
isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock);
isc_mempool_setfillcount(mgr->bpool, 32);
} }
/* Create or adjust socket pool */ /* Create or adjust socket pool */
if (mgr->spool != NULL) { if (mgr->qid != NULL) {
if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2) {
isc_mempool_setmaxalloc(mgr->spool,
DNS_DISPATCH_POOLSOCKS * 2);
isc_mempool_setfreemax(mgr->spool,
DNS_DISPATCH_POOLSOCKS * 2);
}
UNLOCK(&mgr->buffer_lock); UNLOCK(&mgr->buffer_lock);
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
isc_mempool_create(mgr->mctx, sizeof(dispsocket_t), &mgr->spool);
isc_mempool_setname(mgr->spool, "dispmgr_spool");
isc_mempool_setmaxalloc(mgr->spool, maxrequests);
isc_mempool_setfreemax(mgr->spool, maxrequests);
isc_mempool_associatelock(mgr->spool, &mgr->spool_lock);
isc_mempool_setfillcount(mgr->spool, 32);
result = qid_allocate(mgr, buckets, increment, &mgr->qid, true); result = qid_allocate(mgr, buckets, increment, &mgr->qid, true);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@@ -2039,10 +1897,6 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, unsigned int buffersize,
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup: cleanup:
isc_mempool_destroy(&mgr->bpool);
if (mgr->spool != NULL) {
isc_mempool_destroy(&mgr->spool);
}
UNLOCK(&mgr->buffer_lock); UNLOCK(&mgr->buffer_lock);
return (result); return (result);
} }
@@ -2308,10 +2162,8 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
* the options that are controlled by tcp vs. udp, etc. * the options that are controlled by tcp vs. udp, etc.
*/ */
disp = isc_mempool_get(mgr->dpool); disp = isc_mem_get(mgr->mctx, sizeof(*disp));
if (disp == NULL) { isc_refcount_increment0(&mgr->irefs);
return (ISC_R_NOMEMORY);
}
disp->magic = 0; disp->magic = 0;
disp->mgr = mgr; disp->mgr = mgr;
@@ -2335,7 +2187,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
ISC_LIST_INIT(disp->inactivesockets); ISC_LIST_INIT(disp->inactivesockets);
disp->nsockets = 0; disp->nsockets = 0;
disp->port_table = NULL; disp->port_table = NULL;
disp->portpool = NULL;
disp->dscp = -1; disp->dscp = -1;
isc_mutex_init(&disp->lock); isc_mutex_init(&disp->lock);
@@ -2356,7 +2207,8 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
*/ */
kill_lock: kill_lock:
isc_mutex_destroy(&disp->lock); isc_mutex_destroy(&disp->lock);
isc_mempool_put(mgr->dpool, disp); isc_refcount_decrement(&mgr->irefs);
isc_mem_put(mgr->mctx, disp, sizeof(*disp));
return (result); return (result);
} }
@@ -2387,7 +2239,8 @@ dispatch_free(dns_dispatch_t **dispp) {
INSIST(ISC_LIST_EMPTY(disp->activesockets)); INSIST(ISC_LIST_EMPTY(disp->activesockets));
INSIST(ISC_LIST_EMPTY(disp->inactivesockets)); INSIST(ISC_LIST_EMPTY(disp->inactivesockets));
isc_mempool_put(mgr->depool, disp->failsafe_ev); isc_refcount_decrement(&mgr->irefs);
isc_mem_put(mgr->mctx, disp->failsafe_ev, sizeof(*disp->failsafe_ev));
disp->failsafe_ev = NULL; disp->failsafe_ev = NULL;
if (disp->qid != NULL) { if (disp->qid != NULL) {
@@ -2403,14 +2256,11 @@ dispatch_free(dns_dispatch_t **dispp) {
DNS_DISPATCH_PORTTABLESIZE); DNS_DISPATCH_PORTTABLESIZE);
} }
if (disp->portpool != NULL) {
isc_mempool_destroy(&disp->portpool);
}
disp->mgr = NULL; disp->mgr = NULL;
isc_mutex_destroy(&disp->lock); isc_mutex_destroy(&disp->lock);
disp->magic = 0; disp->magic = 0;
isc_mempool_put(mgr->dpool, disp); isc_refcount_decrement(&mgr->irefs);
isc_mem_put(mgr->mctx, disp, sizeof(*disp));
} }
isc_result_t isc_result_t
@@ -2886,11 +2736,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) { for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) {
ISC_LIST_INIT(disp->port_table[i]); ISC_LIST_INIT(disp->port_table[i]);
} }
isc_mempool_create(mgr->mctx, sizeof(dispportentry_t),
&disp->portpool);
isc_mempool_setname(disp->portpool, "disp_portpool");
isc_mempool_setfreemax(disp->portpool, 128);
} }
disp->socket = sock; disp->socket = sock;
disp->local = *localaddr; disp->local = *localaddr;
@@ -2918,15 +2763,8 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
destroy_disp, disp, sizeof(isc_event_t)); destroy_disp, disp, sizeof(isc_event_t));
disp->sepool = NULL; disp->sepool = NULL;
isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t), &disp->sepool); isc_mem_create(&disp->sepool);
isc_mem_setname(disp->sepool, "disp_sepool");
isc_mutex_init(&disp->sepool_lock);
isc_mempool_setname(disp->sepool, "disp_sepool");
isc_mempool_setmaxalloc(disp->sepool, 32768);
isc_mempool_setfreemax(disp->sepool, 32768);
isc_mempool_associatelock(disp->sepool, &disp->sepool_lock);
isc_mempool_setfillcount(disp->sepool, 16);
attributes &= ~DNS_DISPATCHATTR_TCP; attributes &= ~DNS_DISPATCHATTR_TCP;
attributes |= DNS_DISPATCHATTR_UDP; attributes |= DNS_DISPATCHATTR_UDP;
@@ -3142,14 +2980,8 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
return (ISC_R_NOMORE); return (ISC_R_NOMORE);
} }
res = isc_mempool_get(disp->mgr->rpool); res = isc_mem_get(disp->mgr->mctx, sizeof(*res));
if (res == NULL) { isc_refcount_increment0(&disp->mgr->irefs);
if (dispsocket != NULL) {
destroy_dispsocket(disp, &dispsocket);
}
UNLOCK(&disp->lock);
return (ISC_R_NOMEMORY);
}
disp->refcount++; disp->refcount++;
disp->requests++; disp->requests++;
@@ -3204,7 +3036,8 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
UNLOCK(&disp->lock); UNLOCK(&disp->lock);
isc_task_detach(&res->task); isc_task_detach(&res->task);
isc_mempool_put(disp->mgr->rpool, res); isc_refcount_decrement(&disp->mgr->irefs);
isc_mem_put(disp->mgr->mctx, res, sizeof(*res));
return (result); return (result);
} }
} }
@@ -3392,7 +3225,8 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
ev = ISC_LIST_HEAD(res->items); ev = ISC_LIST_HEAD(res->items);
} }
res->magic = 0; res->magic = 0;
isc_mempool_put(disp->mgr->rpool, res); isc_refcount_decrement(&disp->mgr->irefs);
isc_mem_put(disp->mgr->mctx, res, sizeof(*res));
if (disp->shutting_down == 1) { if (disp->shutting_down == 1) {
do_cancel(disp); do_cancel(disp);
} else { } else {

View File

@@ -275,8 +275,7 @@ dispatch_getnext(void **state) {
isc_sockaddr_fromin(&local, &ina, 0); isc_sockaddr_fromin(&local, &ina, 0);
attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local, result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local,
512, 6, 1024, 17, 19, attrs, attrs, 512, 6, 1024, 17, 19, attrs, &dispatch);
&dispatch);
assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(result, ISC_R_SUCCESS);
/* /*

View File

@@ -406,33 +406,6 @@ isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
*\li name != NULL; *\li name != NULL;
*/ */
void
isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
/*%<
* Associate a lock with this memory pool.
*
* This lock is used when getting or putting items using this memory
*pool, and it is also used to set or get internal state via the
*isc_mempool_get*() and isc_mempool_set*() set of functions.
*
* Multiple pools can each share a single lock. For instance, if
*"manager" type object contained pools for various sizes of events, and
*each of these pools used a common lock. Note that this lock must
*NEVER be used by other than mempool routines once it is given to a
*pool, since that can easily cause double locking.
*
* Requires:
*
*\li mpctpx is a valid pool.
*
*\li lock != NULL.
*
*\li No previous lock is assigned to this pool.
*
*\li The lock is initialized before calling this function via the
*normal means of doing that.
*/
/* /*
* The following functions get/set various parameters. Note that due to * The following functions get/set various parameters. Note that due to
* the unlocked nature of pools these are potentially random values * the unlocked nature of pools these are potentially random values

View File

@@ -48,14 +48,6 @@
#define MCTXLOCK(m) LOCK(&m->lock) #define MCTXLOCK(m) LOCK(&m->lock)
#define MCTXUNLOCK(m) UNLOCK(&m->lock) #define MCTXUNLOCK(m) UNLOCK(&m->lock)
#define MPCTXLOCK(mp) \
if (mp->lock != NULL) { \
LOCK(mp->lock); \
}
#define MPCTXUNLOCK(mp) \
if (mp->lock != NULL) { \
UNLOCK(mp->lock); \
}
#ifndef ISC_MEM_DEBUGGING #ifndef ISC_MEM_DEBUGGING
#define ISC_MEM_DEBUGGING 0 #define ISC_MEM_DEBUGGING 0
@@ -158,18 +150,15 @@ struct isc_mem {
struct isc_mempool { struct isc_mempool {
/* always unlocked */ /* always unlocked */
unsigned int magic; unsigned int magic;
isc_mutex_t *lock; /*%< optional lock */ isc_mem_t *mctx; /*%< our memory context */
isc_mem_t *mctx; /*%< our memory context */
/*%< locked via the memory context's lock */
ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */ ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
/*%< optionally locked from here down */ element *items; /*%< low water item list */
element *items; /*%< low water item list */ size_t size; /*%< size of each item on this pool */
size_t size; /*%< size of each item on this pool */ atomic_size_t maxalloc; /*%< max number of items allowed */
atomic_size_t maxalloc; /*%< max number of items allowed */ atomic_size_t allocated; /*%< # of items currently given out */
atomic_size_t allocated; /*%< # of items currently given out */ atomic_size_t freecount; /*%< # of items on reserved list */
atomic_size_t freecount; /*%< # of items on reserved list */ atomic_size_t freemax; /*%< # of items allowed on free list */
atomic_size_t freemax; /*%< # of items allowed on free list */ atomic_size_t fillcount; /*%< # of items to fetch on each fill */
atomic_size_t fillcount; /*%< # of items to fetch on each fill */
/*%< Stats only. */ /*%< Stats only. */
atomic_size_t gets; /*%< # of requests to this pool */ atomic_size_t gets; /*%< # of requests to this pool */
/*%< Debugging only. */ /*%< Debugging only. */
@@ -209,6 +198,7 @@ static inline size_t
increment_malloced(isc_mem_t *ctx, size_t size) { increment_malloced(isc_mem_t *ctx, size_t size) {
size_t malloced = atomic_fetch_add_relaxed(&ctx->malloced, size) + size; size_t malloced = atomic_fetch_add_relaxed(&ctx->malloced, size) + size;
size_t maxmalloced = atomic_load_acquire(&ctx->maxmalloced); size_t maxmalloced = atomic_load_acquire(&ctx->maxmalloced);
if (malloced > maxmalloced) { if (malloced > maxmalloced) {
atomic_compare_exchange_strong(&ctx->maxmalloced, &maxmalloced, atomic_compare_exchange_strong(&ctx->maxmalloced, &maxmalloced,
malloced); malloced);
@@ -230,7 +220,7 @@ decrement_malloced(isc_mem_t *ctx, size_t size) {
*/ */
static void static void
add_trace_entry(isc_mem_t *mctx, const void *ptr, size_t size FLARG) { add_trace_entry(isc_mem_t *mctx, const void *ptr, size_t size FLARG) {
debuglink_t *dl; debuglink_t *dl = NULL;
uint32_t hash; uint32_t hash;
uint32_t idx; uint32_t idx;
@@ -275,7 +265,7 @@ unlock:
static void static void
delete_trace_entry(isc_mem_t *mctx, const void *ptr, size_t size, delete_trace_entry(isc_mem_t *mctx, const void *ptr, size_t size,
const char *file, unsigned int line) { const char *file, unsigned int line) {
debuglink_t *dl; debuglink_t *dl = NULL;
uint32_t hash; uint32_t hash;
uint32_t idx; uint32_t idx;
@@ -328,9 +318,7 @@ unlock:
*/ */
static inline void * static inline void *
mem_get(isc_mem_t *ctx, size_t size) { mem_get(isc_mem_t *ctx, size_t size) {
char *ret; char *ret = mallocx(size, 0);
ret = mallocx(size, 0);
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) { if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
memset(ret, 0xbe, size); /* Mnemonic for "beef". */ memset(ret, 0xbe, size); /* Mnemonic for "beef". */
@@ -421,9 +409,9 @@ isc__mem_shutdown(void) {
static void static void
mem_create(isc_mem_t **ctxp, unsigned int flags) { mem_create(isc_mem_t **ctxp, unsigned int flags) {
REQUIRE(ctxp != NULL && *ctxp == NULL); isc_mem_t *ctx = NULL;
isc_mem_t *ctx; REQUIRE(ctxp != NULL && *ctxp == NULL);
ctx = mallocx(sizeof(*ctx), 0); ctx = mallocx(sizeof(*ctx), 0);
@@ -556,9 +544,11 @@ isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
void void
isc__mem_detach(isc_mem_t **ctxp FLARG) { isc__mem_detach(isc_mem_t **ctxp FLARG) {
isc_mem_t *ctx = NULL;
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
isc_mem_t *ctx = *ctxp; ctx = *ctxp;
*ctxp = NULL; *ctxp = NULL;
if (isc_refcount_decrement(&ctx->references) == 1) { if (isc_refcount_decrement(&ctx->references) == 1) {
@@ -585,10 +575,12 @@ isc__mem_detach(isc_mem_t **ctxp FLARG) {
void void
isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
isc_mem_t *ctx = NULL;
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
REQUIRE(ptr != NULL); REQUIRE(ptr != NULL);
isc_mem_t *ctx = *ctxp; ctx = *ctxp;
*ctxp = NULL; *ctxp = NULL;
DELETE_TRACE(ctx, ptr, size, file, line); DELETE_TRACE(ctx, ptr, size, file, line);
@@ -604,6 +596,8 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
void void
isc__mem_destroy(isc_mem_t **ctxp FLARG) { isc__mem_destroy(isc_mem_t **ctxp FLARG) {
isc_mem_t *ctx = NULL;
/* /*
* This routine provides legacy support for callers who use mctxs * This routine provides legacy support for callers who use mctxs
* without attaching/detaching. * without attaching/detaching.
@@ -611,7 +605,8 @@ isc__mem_destroy(isc_mem_t **ctxp FLARG) {
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp)); REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
isc_mem_t *ctx = *ctxp; ctx = *ctxp;
*ctxp = NULL;
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) { if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) {
@@ -692,11 +687,11 @@ lo_water(isc_mem_t *ctx) {
void * void *
isc__mem_get(isc_mem_t *ctx, size_t size FLARG) { isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
REQUIRE(VALID_CONTEXT(ctx)); void *ptr = NULL;
void *ptr;
bool call_water = false; bool call_water = false;
REQUIRE(VALID_CONTEXT(ctx));
ptr = mem_get(ctx, size); ptr = mem_get(ctx, size);
mem_getstats(ctx, size); mem_getstats(ctx, size);
@@ -778,9 +773,9 @@ print_active(isc_mem_t *mctx, FILE *out) {
*/ */
void void
isc_mem_stats(isc_mem_t *ctx, FILE *out) { isc_mem_stats(isc_mem_t *ctx, FILE *out) {
REQUIRE(VALID_CONTEXT(ctx)); isc_mempool_t *pool = NULL;
isc_mempool_t *pool; REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx); MCTXLOCK(ctx);
@@ -823,8 +818,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
atomic_load_relaxed(&pool->freecount), atomic_load_relaxed(&pool->freecount),
atomic_load_relaxed(&pool->freemax), atomic_load_relaxed(&pool->freemax),
atomic_load_relaxed(&pool->fillcount), atomic_load_relaxed(&pool->fillcount),
atomic_load_relaxed(&pool->gets), atomic_load_relaxed(&pool->gets), "N");
(pool->lock == NULL ? "N" : "Y"));
pool = ISC_LIST_NEXT(pool, link); pool = ISC_LIST_NEXT(pool, link);
} }
@@ -837,11 +831,11 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
void * void *
isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) { isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
REQUIRE(VALID_CONTEXT(ctx)); void *ptr = NULL;
void *ptr;
bool call_water = false; bool call_water = false;
REQUIRE(VALID_CONTEXT(ctx));
ptr = mem_get(ctx, size); ptr = mem_get(ctx, size);
/* Recalculate the real allocated size */ /* Recalculate the real allocated size */
@@ -861,11 +855,13 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
void * void *
isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) { isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
REQUIRE(VALID_CONTEXT(ctx));
void *new_ptr = NULL; void *new_ptr = NULL;
if (new_size == 0) { REQUIRE(VALID_CONTEXT(ctx));
if (old_ptr == NULL) {
new_ptr = isc__mem_allocate(ctx, new_size FLARG_PASS);
} else if (new_size == 0) {
/* /*
* FIXME: We should not call isc__mem_reallocate with size == 0, * FIXME: We should not call isc__mem_reallocate with size == 0,
* this is undefined behaviour. This code is kept only for * this is undefined behaviour. This code is kept only for
@@ -909,10 +905,12 @@ isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
void void
isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) { isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
size_t size;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL); REQUIRE(ptr != NULL);
size_t size = sallocx(ptr, 0); size = sallocx(ptr, 0);
DELETE_TRACE(ctx, ptr, size, file, line); DELETE_TRACE(ctx, ptr, size, file, line);
@@ -928,12 +926,12 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
char * char *
isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) { isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
size_t len;
char *ns = NULL;
REQUIRE(VALID_CONTEXT(mctx)); REQUIRE(VALID_CONTEXT(mctx));
REQUIRE(s != NULL); REQUIRE(s != NULL);
size_t len;
char *ns;
len = strlen(s) + 1; len = strlen(s) + 1;
ns = isc__mem_allocate(mctx, len FLARG_PASS); ns = isc__mem_allocate(mctx, len FLARG_PASS);
@@ -947,12 +945,12 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
char * char *
isc__mem_strndup(isc_mem_t *mctx, const char *s, size_t size FLARG) { isc__mem_strndup(isc_mem_t *mctx, const char *s, size_t size FLARG) {
size_t len;
char *ns = NULL;
REQUIRE(VALID_CONTEXT(mctx)); REQUIRE(VALID_CONTEXT(mctx));
REQUIRE(s != NULL); REQUIRE(s != NULL);
size_t len;
char *ns;
len = strlen(s) + 1; len = strlen(s) + 1;
if (len > size) { if (len > size) {
len = size; len = size;
@@ -1016,12 +1014,12 @@ isc_mem_maxmalloced(isc_mem_t *ctx) {
void void
isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater) { size_t hiwater, size_t lowater) {
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(hiwater >= lowater);
bool callwater = false; bool callwater = false;
isc_mem_water_t oldwater; isc_mem_water_t oldwater;
void *oldwater_arg; void *oldwater_arg = NULL;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(hiwater >= lowater);
MCTXLOCK(ctx); MCTXLOCK(ctx);
oldwater = ctx->water; oldwater = ctx->water;
@@ -1086,12 +1084,12 @@ isc_mem_getname(isc_mem_t *ctx) {
void void
isc__mempool_create(isc_mem_t *mctx, size_t size, isc__mempool_create(isc_mem_t *mctx, size_t size,
isc_mempool_t **mpctxp FLARG) { isc_mempool_t **mpctxp FLARG) {
isc_mempool_t *mpctx = NULL;
REQUIRE(VALID_CONTEXT(mctx)); REQUIRE(VALID_CONTEXT(mctx));
REQUIRE(size > 0U); REQUIRE(size > 0U);
REQUIRE(mpctxp != NULL && *mpctxp == NULL); REQUIRE(mpctxp != NULL && *mpctxp == NULL);
isc_mempool_t *mpctx;
/* /*
* Mempools are stored as a linked list of element. * Mempools are stored as a linked list of element.
*/ */
@@ -1138,26 +1136,23 @@ isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(VALID_MEMPOOL(mpctx));
REQUIRE(name != NULL); REQUIRE(name != NULL);
MPCTXLOCK(mpctx);
strlcpy(mpctx->name, name, sizeof(mpctx->name)); strlcpy(mpctx->name, name, sizeof(mpctx->name));
MPCTXUNLOCK(mpctx);
} }
void void
isc__mempool_destroy(isc_mempool_t **mpctxp FLARG) { isc__mempool_destroy(isc_mempool_t **mpctxp FLARG) {
isc_mempool_t *mpctx = NULL;
isc_mem_t *mctx = NULL;
element *item = NULL;
REQUIRE(mpctxp != NULL); REQUIRE(mpctxp != NULL);
REQUIRE(VALID_MEMPOOL(*mpctxp)); REQUIRE(VALID_MEMPOOL(*mpctxp));
isc_mempool_t *mpctx;
isc_mem_t *mctx;
isc_mutex_t *lock;
element *item;
mpctx = *mpctxp; mpctx = *mpctxp;
*mpctxp = NULL; *mpctxp = NULL;
mctx = mpctx->mctx;
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) { if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) {
fprintf(stderr, "destroy pool %p file %s line %u mctx %p\n", fprintf(stderr, "destroy pool %p file %s line %u mctx %p\n",
@@ -1173,14 +1168,6 @@ isc__mempool_destroy(isc_mempool_t **mpctxp FLARG) {
} }
REQUIRE(atomic_load_acquire(&mpctx->allocated) == 0); REQUIRE(atomic_load_acquire(&mpctx->allocated) == 0);
mctx = mpctx->mctx;
lock = mpctx->lock;
if (lock != NULL) {
LOCK(lock);
}
/* /*
* Return any items on the free list * Return any items on the free list
*/ */
@@ -1205,19 +1192,6 @@ isc__mempool_destroy(isc_mempool_t **mpctxp FLARG) {
mpctx->magic = 0; mpctx->magic = 0;
isc_mem_put(mpctx->mctx, mpctx, sizeof(isc_mempool_t)); isc_mem_put(mpctx->mctx, mpctx, sizeof(isc_mempool_t));
if (lock != NULL) {
UNLOCK(lock);
}
}
void
isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
REQUIRE(VALID_MEMPOOL(mpctx));
REQUIRE(lock != NULL);
REQUIRE(mpctx->lock == NULL);
mpctx->lock = lock;
} }
#if __SANITIZE_ADDRESS__ #if __SANITIZE_ADDRESS__
@@ -1225,8 +1199,8 @@ void *
isc__mempool_get(isc_mempool_t *mpctx FLARG) { isc__mempool_get(isc_mempool_t *mpctx FLARG) {
REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(VALID_MEMPOOL(mpctx));
size_t allocated = atomic_fetch_add_release(&mpctx->allocated, 1); allocated = atomic_fetch_add_release(&mpctx->allocated, 1);
size_t maxalloc = atomic_load_acquire(&mpctx->maxalloc); maxalloc = atomic_load_acquire(&mpctx->maxalloc);
/* /*
* Don't let the caller go over quota. * Don't let the caller go over quota.
@@ -1255,11 +1229,13 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
void * void *
isc__mempool_get(isc_mempool_t *mpctx FLARG) { isc__mempool_get(isc_mempool_t *mpctx FLARG) {
element *item = NULL; element *item = NULL;
size_t allocated;
size_t maxalloc;
REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(VALID_MEMPOOL(mpctx));
size_t allocated = atomic_fetch_add_release(&mpctx->allocated, 1); allocated = atomic_fetch_add_release(&mpctx->allocated, 1);
size_t maxalloc = atomic_load_acquire(&mpctx->maxalloc); maxalloc = atomic_load_acquire(&mpctx->maxalloc);
/* /*
* Don't let the caller go over quota * Don't let the caller go over quota
@@ -1269,7 +1245,6 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
return (NULL); return (NULL);
} }
MPCTXLOCK(mpctx);
if (ISC_UNLIKELY(mpctx->items == NULL)) { if (ISC_UNLIKELY(mpctx->items == NULL)) {
isc_mem_t *mctx = mpctx->mctx; isc_mem_t *mctx = mpctx->mctx;
size_t fillcount = atomic_load_acquire(&mpctx->fillcount); size_t fillcount = atomic_load_acquire(&mpctx->fillcount);
@@ -1294,8 +1269,6 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
ADD_TRACE(mpctx->mctx, item, mpctx->size, file, line); ADD_TRACE(mpctx->mctx, item, mpctx->size, file, line);
MPCTXUNLOCK(mpctx);
return (item); return (item);
} }
@@ -1327,14 +1300,10 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
/* /*
* Otherwise, attach it to our free list and bump the counter. * Otherwise, attach it to our free list and bump the counter.
*/ */
MPCTXLOCK(mpctx);
item = (element *)mem; item = (element *)mem;
item->next = mpctx->items; item->next = mpctx->items;
mpctx->items = item; mpctx->items = item;
atomic_fetch_add_relaxed(&mpctx->freecount, 1); atomic_fetch_add_relaxed(&mpctx->freecount, 1);
MPCTXUNLOCK(mpctx);
} }
#endif /* __SANITIZE_ADDRESS__ */ #endif /* __SANITIZE_ADDRESS__ */

View File

@@ -669,12 +669,6 @@ struct isc_nm {
isc_stats_t *stats; isc_stats_t *stats;
isc_mempool_t *reqpool;
isc_mutex_t reqlock;
isc_mempool_t *evpool;
isc_mutex_t evlock;
uint_fast32_t workers_running; uint_fast32_t workers_running;
atomic_uint_fast32_t workers_paused; atomic_uint_fast32_t workers_paused;
atomic_uint_fast32_t maxudp; atomic_uint_fast32_t maxudp;

View File

@@ -281,21 +281,6 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
atomic_init(&mgr->keepalive, 30000); atomic_init(&mgr->keepalive, 30000);
atomic_init(&mgr->advertised, 30000); atomic_init(&mgr->advertised, 30000);
isc_mutex_init(&mgr->reqlock);
isc_mempool_create(mgr->mctx, sizeof(isc__nm_uvreq_t), &mgr->reqpool);
isc_mempool_setname(mgr->reqpool, "nm_reqpool");
isc_mempool_setfreemax(mgr->reqpool, 4096);
isc_mempool_associatelock(mgr->reqpool, &mgr->reqlock);
isc_mempool_setfillcount(mgr->reqpool, 32);
isc_mutex_init(&mgr->evlock);
isc_mempool_create(mgr->mctx, sizeof(isc__netievent_storage_t),
&mgr->evpool);
isc_mempool_setname(mgr->evpool, "nm_evpool");
isc_mempool_setfreemax(mgr->evpool, 4096);
isc_mempool_associatelock(mgr->evpool, &mgr->evlock);
isc_mempool_setfillcount(mgr->evpool, 32);
isc_barrier_init(&mgr->pausing, workers); isc_barrier_init(&mgr->pausing, workers);
isc_barrier_init(&mgr->resuming, workers); isc_barrier_init(&mgr->resuming, workers);
@@ -377,14 +362,14 @@ nm_destroy(isc_nm_t **mgr0) {
/* Empty the async event queues */ /* Empty the async event queues */
while ((ievent = DEQUEUE_PRIORITY_NETIEVENT(worker)) != NULL) { while ((ievent = DEQUEUE_PRIORITY_NETIEVENT(worker)) != NULL) {
isc_mempool_put(mgr->evpool, ievent); isc_mem_put(mgr->mctx, ievent, sizeof(*ievent));
} }
INSIST(DEQUEUE_PRIVILEGED_NETIEVENT(worker) == NULL); INSIST(DEQUEUE_PRIVILEGED_NETIEVENT(worker) == NULL);
INSIST(DEQUEUE_TASK_NETIEVENT(worker) == NULL); INSIST(DEQUEUE_TASK_NETIEVENT(worker) == NULL);
while ((ievent = DEQUEUE_PRIORITY_NETIEVENT(worker)) != NULL) { while ((ievent = DEQUEUE_PRIORITY_NETIEVENT(worker)) != NULL) {
isc_mempool_put(mgr->evpool, ievent); isc_mem_put(mgr->mctx, ievent, sizeof(*ievent));
} }
isc_condition_destroy(&worker->cond_prio); isc_condition_destroy(&worker->cond_prio);
@@ -413,12 +398,6 @@ nm_destroy(isc_nm_t **mgr0) {
isc_condition_destroy(&mgr->wkpausecond); isc_condition_destroy(&mgr->wkpausecond);
isc_mutex_destroy(&mgr->lock); isc_mutex_destroy(&mgr->lock);
isc_mempool_destroy(&mgr->evpool);
isc_mutex_destroy(&mgr->evlock);
isc_mempool_destroy(&mgr->reqpool);
isc_mutex_destroy(&mgr->reqlock);
isc_mem_put(mgr->mctx, mgr->workers, isc_mem_put(mgr->mctx, mgr->workers,
mgr->nworkers * sizeof(isc__networker_t)); mgr->nworkers * sizeof(isc__networker_t));
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
@@ -1038,7 +1017,8 @@ process_queue(isc__networker_t *worker, netievent_type_t type) {
void * void *
isc__nm_get_netievent(isc_nm_t *mgr, isc__netievent_type type) { isc__nm_get_netievent(isc_nm_t *mgr, isc__netievent_type type) {
isc__netievent_storage_t *event = isc_mempool_get(mgr->evpool); isc__netievent_storage_t *event = isc_mem_get(mgr->mctx,
sizeof(*event));
*event = (isc__netievent_storage_t){ .ni.type = type }; *event = (isc__netievent_storage_t){ .ni.type = type };
return (event); return (event);
@@ -1046,7 +1026,7 @@ isc__nm_get_netievent(isc_nm_t *mgr, isc__netievent_type type) {
void void
isc__nm_put_netievent(isc_nm_t *mgr, void *ievent) { isc__nm_put_netievent(isc_nm_t *mgr, void *ievent) {
isc_mempool_put(mgr->evpool, ievent); isc_mem_put(mgr->mctx, ievent, sizeof(isc__netievent_storage_t));
} }
NETIEVENT_SOCKET_DEF(tcpclose); NETIEVENT_SOCKET_DEF(tcpclose);
@@ -1273,7 +1253,7 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
isc_astack_destroy(sock->inactivehandles); isc_astack_destroy(sock->inactivehandles);
while ((uvreq = isc_astack_pop(sock->inactivereqs)) != NULL) { while ((uvreq = isc_astack_pop(sock->inactivereqs)) != NULL) {
isc_mempool_put(sock->mgr->reqpool, uvreq); isc_mem_put(sock->mgr->mctx, uvreq, sizeof(*uvreq));
} }
isc_astack_destroy(sock->inactivereqs); isc_astack_destroy(sock->inactivereqs);
@@ -2428,7 +2408,7 @@ isc___nm_uvreq_get(isc_nm_t *mgr, isc_nmsocket_t *sock FLARG) {
} }
if (req == NULL) { if (req == NULL) {
req = isc_mempool_get(mgr->reqpool); req = isc_mem_get(mgr->mctx, sizeof(*req));
} }
*req = (isc__nm_uvreq_t){ .magic = 0 }; *req = (isc__nm_uvreq_t){ .magic = 0 };
@@ -2464,7 +2444,7 @@ isc___nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock FLARG) {
if (!isc__nmsocket_active(sock) || if (!isc__nmsocket_active(sock) ||
!isc_astack_trypush(sock->inactivereqs, req)) { !isc_astack_trypush(sock->inactivereqs, req)) {
isc_mempool_put(sock->mgr->reqpool, req); isc_mem_put(sock->mgr->mctx, req, sizeof(*req));
} }
if (handle != NULL) { if (handle != NULL) {

View File

@@ -428,68 +428,6 @@ isc_mem_benchmark(void **state) {
(nthreads * ITERS * NUM_ITEMS) / (t / 1000000.0)); (nthreads * ITERS * NUM_ITEMS) / (t / 1000000.0));
} }
static isc_threadresult_t
mempool_thread(isc_threadarg_t arg) {
isc_mempool_t *mp = (isc_mempool_t *)arg;
void *items[NUM_ITEMS];
for (int i = 0; i < ITERS; i++) {
for (int j = 0; j < NUM_ITEMS; j++) {
items[j] = isc_mempool_get(mp);
}
for (int j = 0; j < NUM_ITEMS; j++) {
isc_mempool_put(mp, items[j]);
}
}
return ((isc_threadresult_t)0);
}
static void
isc_mempool_benchmark(void **state) {
int nthreads = ISC_MAX(ISC_MIN(isc_os_ncpus(), 32), 1);
isc_thread_t threads[32];
isc_time_t ts1, ts2;
double t;
isc_result_t result;
isc_mempool_t *mp = NULL;
isc_mutex_t mplock;
isc_mutex_init(&mplock);
isc_mempool_create(test_mctx, ITEM_SIZE, &mp);
isc_mempool_associatelock(mp, &mplock);
isc_mempool_setfreemax(mp, 32768);
isc_mempool_setfillcount(mp, ISC_MAX(NUM_ITEMS / nthreads, 1));
UNUSED(state);
result = isc_time_now(&ts1);
assert_int_equal(result, ISC_R_SUCCESS);
for (int i = 0; i < nthreads; i++) {
isc_thread_create(mempool_thread, mp, &threads[i]);
}
for (int i = 0; i < nthreads; i++) {
isc_thread_join(threads[i], NULL);
}
result = isc_time_now(&ts2);
assert_int_equal(result, ISC_R_SUCCESS);
t = isc_time_microdiff(&ts2, &ts1);
printf("[ TIME ] isc_mempool_benchmark: "
"%d isc_mempool_{get,put} calls, %f seconds, %f calls/second\n",
nthreads * ITERS * NUM_ITEMS, t / 1000000.0,
(nthreads * ITERS * NUM_ITEMS) / (t / 1000000.0));
isc_mempool_destroy(&mp);
isc_mutex_destroy(&mplock);
}
#endif /* __SANITIZE_THREAD */ #endif /* __SANITIZE_THREAD */
/* /*
@@ -509,8 +447,6 @@ main(void) {
#if !defined(__SANITIZE_THREAD__) #if !defined(__SANITIZE_THREAD__)
cmocka_unit_test_setup_teardown(isc_mem_benchmark, _setup, cmocka_unit_test_setup_teardown(isc_mem_benchmark, _setup,
_teardown), _teardown),
cmocka_unit_test_setup_teardown(isc_mempool_benchmark, _setup,
_teardown),
#endif /* __SANITIZE_THREAD__ */ #endif /* __SANITIZE_THREAD__ */
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
cmocka_unit_test_setup_teardown(isc_mem_noflags_test, _setup, cmocka_unit_test_setup_teardown(isc_mem_noflags_test, _setup,