Reduce false sharing in dns_qpzone

Instead of having many node_lock_count * sizeof(<member>) arrays, pack
all the members into a qpzone_bucket_t that is cacheline aligned and have
a single array of those.
This commit is contained in:
Ondřej Surý
2025-02-04 16:50:27 +01:00
parent c602d76c1f
commit 6dcc398726
2 changed files with 71 additions and 64 deletions

View File

@@ -101,21 +101,22 @@ const char *ownercase_vectors[12][2] = {
static bool
ownercase_test_one(const char *str1, const char *str2) {
isc_result_t result;
isc_rwlock_t node_locks[1];
qpzonedb_t qpdb = {
uint8_t qpdb_s[sizeof(qpzonedb_t) + sizeof(qpzone_bucket_t)];
qpzonedb_t *qpdb = (qpzonedb_t *)&qpdb_s;
*qpdb = (qpzonedb_t){
.common.methods = &qpdb_zonemethods,
.common.mctx = mctx,
.node_locks = node_locks,
.buckets_count = 1,
};
qpznode_t node = { .locknum = 0 };
dns_slabheader_t header = {
.node = (dns_dbnode_t *)&node,
.db = (dns_db_t *)&qpdb,
.db = (dns_db_t *)qpdb,
};
unsigned char *raw = (unsigned char *)(&header) + sizeof(header);
dns_rdataset_t rdataset = {
.magic = DNS_RDATASET_MAGIC,
.slab = { .db = (dns_db_t *)&qpdb,
.slab = { .db = (dns_db_t *)qpdb,
.node = (dns_dbnode_t *)&node,
.raw = raw,
},
@@ -126,9 +127,8 @@ ownercase_test_one(const char *str1, const char *str2) {
dns_name_t *name1 = dns_fixedname_initname(&fname1);
dns_name_t *name2 = dns_fixedname_initname(&fname2);
memset(node_locks, 0, sizeof(node_locks));
/* Minimal initialization of the mock objects */
NODE_INITLOCK(&qpdb.node_locks[0]);
NODE_INITLOCK(&qpdb->buckets[0].lock);
isc_buffer_constinit(&b, str1, strlen(str1));
isc_buffer_add(&b, strlen(str1));
@@ -148,7 +148,7 @@ ownercase_test_one(const char *str1, const char *str2) {
/* Retrieve the case to name2 */
dns_rdataset_getownercase(&rdataset, name2);
NODE_DESTROYLOCK(&qpdb.node_locks[0]);
NODE_DESTROYLOCK(&qpdb->buckets[0].lock);
return dns_name_caseequal(name1, name2);
}
@@ -169,21 +169,22 @@ ISC_RUN_TEST_IMPL(ownercase) {
ISC_RUN_TEST_IMPL(setownercase) {
isc_result_t result;
isc_rwlock_t node_locks[1];
qpzonedb_t qpdb = {
uint8_t qpdb_s[sizeof(qpzonedb_t) + sizeof(qpzone_bucket_t)];
qpzonedb_t *qpdb = (qpzonedb_t *)&qpdb_s;
*qpdb = (qpzonedb_t){
.common.methods = &qpdb_zonemethods,
.common.mctx = mctx,
.node_locks = node_locks,
.buckets_count = 1,
};
qpznode_t node = { .locknum = 0 };
dns_slabheader_t header = {
.node = (dns_dbnode_t *)&node,
.db = (dns_db_t *)&qpdb,
.db = (dns_db_t *)qpdb,
};
unsigned char *raw = (unsigned char *)(&header) + sizeof(header);
dns_rdataset_t rdataset = {
.magic = DNS_RDATASET_MAGIC,
.slab = { .db = (dns_db_t *)&qpdb,
.slab = { .db = (dns_db_t *)qpdb,
.node = (dns_dbnode_t *)&node,
.raw = raw,
},
@@ -199,8 +200,7 @@ ISC_RUN_TEST_IMPL(setownercase) {
UNUSED(state);
/* Minimal initialization of the mock objects */
memset(node_locks, 0, sizeof(node_locks));
NODE_INITLOCK(&qpdb.node_locks[0]);
NODE_INITLOCK(&qpdb->buckets[0].lock);
isc_buffer_constinit(&b, str1, strlen(str1));
isc_buffer_add(&b, strlen(str1));
@@ -217,7 +217,7 @@ ISC_RUN_TEST_IMPL(setownercase) {
/* Retrieve the case to name2 */
dns_rdataset_getownercase(&rdataset, name2);
NODE_DESTROYLOCK(&qpdb.node_locks[0]);
NODE_DESTROYLOCK(&qpdb->buckets[0].lock);
assert_true(dns_name_caseequal(name1, name2));
}