Profiles show that an high amount of CPU time spent in memset.
By removing zero initalization of certain large buffers we improve
performance in certain authoritative workloads.
REQUIRE(QP_VALID(qp));
REQUIRE(chain != NULL);
- *chain = (dns_qpchain_t){
- .magic = QPCHAIN_MAGIC,
- .qp = qp,
- };
+ /*
+ * dns_qpchain_t contains a 2kb buffer, which is slow to
+ * zero-initialize. Therefore we avoid designated initializers, and
+ * initialize each field manually.
+ */
+ chain->magic = QPCHAIN_MAGIC;
+ chain->qp = qp;
+ chain->len = 0;
}
unsigned int
dns_qpreader_t *qp = dns_qpreader(qpr);
REQUIRE(QP_VALID(qp));
REQUIRE(qpi != NULL);
- *qpi = (dns_qpiter_t){
- .qp = qp,
- .magic = QPITER_MAGIC,
- };
+
+ /*
+ * dns_qpiter_t contains a 4kb buffer, which is slow to zero-initialize.
+ * Therefore we avoid designated initializers, and initialize each
+ * field manually.
+ */
+ qpi->qp = qp;
+ qpi->sp = 0;
+ qpi->magic = QPITER_MAGIC;
+ /*
+ * The top of the stack must be initialized.
+ */
+ qpi->stack[qpi->sp] = NULL;
}
/*
(DNS_TRUST_PENDING((found)->trust) && \
(((options) & DNS_DBFIND_PENDINGOK) == 0)))
+static void
+qpc_search_init(qpc_search_t *search, qpcache_t *db, unsigned int options,
+ isc_stdtime_t now) {
+ /*
+ * qpc_search_t contains two structures with large buffers (dns_qpiter_t
+ * and dns_qpchain_t). Those two structures will be initialized later by
+ * dns_qp_lookup anyway.
+ * To avoid the overhead of zero initialization, we avoid designated
+ * initializers and initialize all "small" fields manually.
+ */
+ search->qpdb = (qpcache_t *)db;
+ search->options = options;
+ /*
+ * qpch->in - Init by dns_qp_lookup
+ * qpiter - Init by dns_qp_lookup
+ */
+ search->need_cleanup = false;
+ search->now = now ? now : isc_stdtime_now();
+ search->zonecut = NULL;
+ search->zonecut_header = NULL;
+ search->zonecut_sigheader = NULL;
+}
+
static isc_result_t
qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t __now,
dns_slabheader_t *foundsig = NULL, *nssig = NULL, *cnamesig = NULL;
dns_slabheader_t *nsecheader = NULL, *nsecsig = NULL;
dns_typepair_t sigtype, negtype;
- qpc_search_t search = (qpc_search_t){
- .qpdb = (qpcache_t *)db,
- .options = options,
- .now = __now ? __now : isc_stdtime_now(),
- };
+
+ qpc_search_t search;
+ qpc_search_init(&search, (qpcache_t *)db, options, __now);
REQUIRE(VALID_QPDB((qpcache_t *)db));
REQUIRE(version == NULL);
return result;
}
+static void
+qpz_search_init(qpz_search_t *search, qpzonedb_t *db, qpz_version_t *version,
+ unsigned int options) {
+ /*
+ * qpz_search_t contains two structures with large buffers (dns_qpiter_t
+ * and dns_qpchain_t). Those two structures will be initialized later by
+ * dns_qp_lookup anyway.
+ * To avoid the overhead of zero initialization, we avoid designated
+ * initializers and initialize all "small" fields manually.
+ */
+ search->qpdb = db;
+ search->version = version;
+ search->qpr = (dns_qpread_t){};
+ search->serial = version->serial;
+ search->options = options;
+ /*
+ * qpch->in -- init in dns_qp_lookup
+ * qpiter -- init in dns_qp_lookup
+ */
+ search->copy_name = false;
+ search->need_cleanup = false;
+ search->wild = false;
+ search->zonecut = NULL;
+ search->zonecut_header = NULL;
+ search->zonecut_sigheader = NULL;
+ dns_fixedname_init(&search->zonecut_name);
+}
+
static isc_result_t
qpzone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options,
isc_result_t result;
qpzonedb_t *qpdb = (qpzonedb_t *)db;
qpznode_t *node = NULL;
- qpz_search_t search;
bool cname_ok = true, close_version = false;
bool maybe_zonecut = false, at_zonecut = false;
bool wild = false, empty_node = false;
close_version = true;
}
- search = (qpz_search_t){
- .qpdb = (qpzonedb_t *)db,
- .version = (qpz_version_t *)version,
- .serial = ((qpz_version_t *)version)->serial,
- .options = options,
- };
- dns_fixedname_init(&search.zonecut_name);
+ qpz_search_t search;
+ qpz_search_init(&search, (qpzonedb_t *)db, (qpz_version_t *)version,
+ options);
if ((options & DNS_DBFIND_FORCENSEC3) != 0) {
dns_qpmulti_query(qpdb->nsec3, &search.qpr);