From: Witold Kręcicki Date: Tue, 22 Jan 2019 09:47:18 +0000 (+0100) Subject: lib/dns/adb.c: don't use more than 64 lock simultaneously when run under TSAN X-Git-Tag: v9.17.0~14^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d933715812500885e2743b1d3adcffa46e8b08e;p=thirdparty%2Fbind9.git lib/dns/adb.c: don't use more than 64 lock simultaneously when run under TSAN - TSAN can't handle more than 64 locks in one thread, lock ADB bucket-by-bucket in TSAN mode. This means that the dump won't be consistent but it's good enough for testing - Use proper order when unlocking adb->namelocks and adb->entrylocks when dumping ADB. --- diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 4c670f07c89..ce879f09d54 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -3388,7 +3388,6 @@ dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) { static void dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) { - unsigned int i; dns_adbname_t *name; dns_adbentry_t *entry; @@ -3401,28 +3400,46 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) { adb, adb->erefcnt, adb->irefcnt, isc_mempool_getallocated(adb->nhmp)); - for (i = 0; i < adb->nnames; i++) +/* + * In TSAN mode we need to lock the locks individually, as TSAN + * can't handle more than 64 locks locked by one thread. + * In regular mode we want a consistent dump so we need to + * lock everything. + */ +#ifndef __SANITIZE_THREAD__ + for (size_t i = 0; i < adb->nnames; i++) { LOCK(&adb->namelocks[i]); - for (i = 0; i < adb->nentries; i++) + } + for (size_t i = 0; i < adb->nentries; i++) { LOCK(&adb->entrylocks[i]); + } +#endif /* * Dump the names */ - for (i = 0; i < adb->nnames; i++) { + for (size_t i = 0; i < adb->nnames; i++) { +#ifdef __SANITIZE_THREAD__ + LOCK(&adb->namelocks[i]); +#endif name = ISC_LIST_HEAD(adb->names[i]); - if (name == NULL) + if (name == NULL) { +#ifdef __SANITIZE_THREAD__ + UNLOCK(&adb->namelocks[i]); +#endif continue; - if (debug) - fprintf(f, "; bucket %u\n", i); + } + if (debug) { + fprintf(f, "; bucket %zu\n", i); + } for (; name != NULL; name = ISC_LIST_NEXT(name, plink)) { - if (debug) + if (debug) { fprintf(f, "; name %p (flags %08x)\n", name, name->flags); - + } fprintf(f, "; "); print_dns_name(f, &name->name); if (dns_name_countlabels(&name->target) > 0) { @@ -3450,26 +3467,39 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) { print_find_list(f, name); } } +#ifdef __SANITIZE_THREAD__ + UNLOCK(&adb->namelocks[i]); +#endif } fprintf(f, ";\n; Unassociated entries\n;\n"); - for (i = 0; i < adb->nentries; i++) { + for (size_t i = 0; i < adb->nentries; i++) { +#ifdef __SANITIZE_THREAD__ + LOCK(&adb->entrylocks[i]); +#endif entry = ISC_LIST_HEAD(adb->entries[i]); while (entry != NULL) { if (entry->nh == 0) dump_entry(f, adb, entry, debug, now); entry = ISC_LIST_NEXT(entry, plink); } +#ifdef __SANITIZE_THREAD__ + UNLOCK(&adb->entrylocks[i]); +#endif } +#ifndef __SANITIZE_THREAD__ /* * Unlock everything */ - for (i = 0; i < adb->nentries; i++) + for (ssize_t i = adb->nentries-1; i >= 0; i--) { UNLOCK(&adb->entrylocks[i]); - for (i = 0; i < adb->nnames; i++) + } + for (ssize_t i = adb->nnames-1; i >= 0; i--) { UNLOCK(&adb->namelocks[i]); + } +#endif } static void