]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use atomics to update counters.
authorMark Andrews <marka@isc.org>
Thu, 27 Aug 2020 05:12:10 +0000 (15:12 +1000)
committerMark Andrews <marka@isc.org>
Mon, 7 Sep 2020 23:25:43 +0000 (09:25 +1000)
WARNING: ThreadSanitizer: data race
  Write of size 4 at 0x000000000001 by thread T1:
    #0 dns_acache_countquerymiss lib/dns/acache.c:1184:22
    #1 rdataset_getadditional lib/dns/rbtdb.c:9875:3
    #2 dns_rdataset_getadditional lib/dns/rdataset.c:711:11
    #3 query_addadditional2 bin/named/query.c:1967:11
    #4 additionaldata_ns lib/dns/./rdata/generic/ns_2.c:198:10
    #5 dns_rdata_additionaldata lib/dns/rdata.c:1246:2
    #6 dns_rdataset_additionaldata lib/dns/rdataset.c:629:12
    #7 query_addrdataset bin/named/query.c:2411:8
    #8 query_addrrset bin/named/query.c:2802:2
    #9 query_find bin/named/query.c:9135:4
    #10 query_resume bin/named/query.c:4164:12
    #11 dispatch lib/isc/task.c:1157:7
    #12 run lib/isc/task.c:1331:2

  Previous write of size 4 at 0x000000000001 by thread T2:
    #0 dns_acache_countquerymiss lib/dns/acache.c:1184:22
    #1 rdataset_getadditional lib/dns/rbtdb.c:9875:3
    #2 dns_rdataset_getadditional lib/dns/rdataset.c:711:11
    #3 query_addadditional2 bin/named/query.c:1967:11
    #4 additionaldata_ns lib/dns/./rdata/generic/ns_2.c:198:10
    #5 dns_rdata_additionaldata lib/dns/rdata.c:1246:2
    #6 dns_rdataset_additionaldata lib/dns/rdataset.c:629:12
    #7 query_addrdataset bin/named/query.c:2411:8
    #8 query_addrrset bin/named/query.c:2802:2
    #9 query_find bin/named/query.c:9135:4
    #10 query_resume bin/named/query.c:4164:12
    #11 dispatch lib/isc/task.c:1157:7
    #12 run lib/isc/task.c:1331:2

lib/dns/acache.c

index fc6973f4cca95db1fab86f918a4c1305642b6902..14ba672135df81c9226071d0643efbfba9c78901 100644 (file)
@@ -174,9 +174,24 @@ struct acache_cleaner {
 };
 
 struct dns_acachestats {
+#ifdef ACACHE_HAVESTDATOMIC
+       _Atomic(unsigned int)           hits;
+       _Atomic(unsigned int)           queries;
+       _Atomic(unsigned int)           misses;
+#define ACACHE_INC(x)  atomic_fetch_add(&(x), 1)
+#define ACACHE_LOAD(x)  atomic_load(&(x))
+#else
        unsigned int                    hits;
        unsigned int                    queries;
        unsigned int                    misses;
+#if defined(ISC_PLATFORM_HAVEXADD)
+#define ACACHE_INC(x) isc_atomic_xadd((int32_t*)&(x), 1)
+#define ACACHE_LOAD(x) isc_atomic_xadd((int32_t*)&(x), 0)
+#else
+#define ACACHE_INC(x) ((x)++)
+#define ACACHE_LOAD(x) (x)
+#endif
+#endif
        unsigned int                    adds;
        unsigned int                    deleted;
        unsigned int                    cleaned;
@@ -716,8 +731,9 @@ end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) {
                      "cleaned=%d cleaner_runs=%d overmem=%d "
                      "overmem_nocreates=%d nomem=%d",
                      acache,
-                     acache->stats.hits, acache->stats.misses,
-                     acache->stats.queries,
+                     ACACHE_LOAD(acache->stats.hits),
+                     ACACHE_LOAD(acache->stats.misses),
+                     ACACHE_LOAD(acache->stats.queries),
                      acache->stats.adds, acache->stats.deleted,
                      acache->stats.cleaned, acache->stats.cleaner_runs,
                      acache->stats.overmem, acache->stats.overmem_nocreates,
@@ -1181,8 +1197,8 @@ dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) {
 
 void
 dns_acache_countquerymiss(dns_acache_t *acache) {
-       acache->stats.misses++;         /* XXXSK danger: unlocked! */
-       acache->stats.queries++;        /* XXXSK danger: unlocked! */
+       ACACHE_INC(acache->stats.misses);
+       ACACHE_INC(acache->stats.queries);
 }
 
 void
@@ -1529,8 +1545,8 @@ dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
                }
        }
 
-       entry->acache->stats.hits++; /* XXXMLG danger: unlocked! */
-       entry->acache->stats.queries++;
+       ACACHE_INC(entry->acache->stats.hits);
+       ACACHE_INC(entry->acache->stats.queries);
 
        ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read);