]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix memory ordering for operations with quota->used and quota->waiting
authorAram Sargsyan <aram@isc.org>
Thu, 27 Feb 2025 16:48:52 +0000 (16:48 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Tue, 4 Mar 2025 09:57:34 +0000 (09:57 +0000)
Change all the non-locked operations on 'quota->used' and
'quota->waiting' to "acq/rel" for inter-thread synchronization. Some
loads are left as "relaxed", because they are under a locked mutex
which also provides protection.

lib/isc/quota.c

index ccafd240ea0377e4104775012eda7ba0f648228e..fa2d562c9c1d92c3370c2f5547060135667d603a 100644 (file)
@@ -42,11 +42,10 @@ isc_quota_destroy(isc_quota_t *quota) {
        REQUIRE(VALID_QUOTA(quota));
        quota->magic = 0;
 
-       INSIST(atomic_load(&quota->used) == 0);
-       INSIST(atomic_load(&quota->waiting) == 0);
+       INSIST(atomic_load_acquire(&quota->used) == 0);
+       INSIST(atomic_load_acquire(&quota->waiting) == 0);
        INSIST(ISC_LIST_EMPTY(quota->cbs));
        atomic_store_relaxed(&quota->max, 0);
-       atomic_store_release(&quota->used, 0);
        atomic_store_relaxed(&quota->soft, 0);
        isc_mutex_destroy(&quota->cblock);
 }
@@ -78,7 +77,7 @@ isc_quota_getsoft(isc_quota_t *quota) {
 unsigned int
 isc_quota_getused(isc_quota_t *quota) {
        REQUIRE(VALID_QUOTA(quota));
-       return atomic_load_relaxed(&quota->used);
+       return atomic_load_acquire(&quota->used);
 }
 
 static isc_result_t
@@ -106,6 +105,7 @@ static void
 enqueue(isc_quota_t *quota, isc_quota_cb_t *cb) {
        REQUIRE(cb != NULL);
        ISC_LIST_ENQUEUE(quota->cbs, cb, link);
+       /* No need for acquire; the lock protects from other writers. */
        atomic_fetch_add_release(&quota->waiting, 1);
 }
 
@@ -115,7 +115,8 @@ dequeue(isc_quota_t *quota) {
        isc_quota_cb_t *cb = ISC_LIST_HEAD(quota->cbs);
        INSIST(cb != NULL);
        ISC_LIST_DEQUEUE(quota->cbs, cb, link);
-       atomic_fetch_sub_relaxed(&quota->waiting, 1);
+       /* No need for acquire; the lock protects from other writers. */
+       atomic_fetch_sub_release(&quota->waiting, 1);
        return cb;
 }
 
@@ -133,6 +134,7 @@ quota_release(isc_quota_t *quota) {
        if (atomic_load_acquire(&quota->waiting) > 0) {
                isc_quota_cb_t *cb = NULL;
                LOCK(&quota->cblock);
+               /* No need for acquire; the lock protects from other writers. */
                if (atomic_load_relaxed(&quota->waiting) > 0) {
                        cb = dequeue(quota);
                }
@@ -143,7 +145,7 @@ quota_release(isc_quota_t *quota) {
                }
        }
 
-       used = atomic_fetch_sub_release(&quota->used, 1);
+       used = atomic_fetch_sub_acq_rel(&quota->used, 1);
        INSIST(used > 0);
 }