]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix a possible race in updating stats counters (#38826)
authorMukund Sivaraman <muks@isc.org>
Mon, 9 Mar 2015 04:59:03 +0000 (10:29 +0530)
committerMukund Sivaraman <muks@isc.org>
Mon, 9 Mar 2015 05:00:47 +0000 (10:30 +0530)
and do some other isc mem cleanups.

CHANGES
lib/isc/mem.c

diff --git a/CHANGES b/CHANGES
index a603cbca4c7f830823918d039c542452e3e05720..955658b63d32c30bd2a200e0ea1e2b7b53eb5f4a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4094.  [bug]           Fix a possible race in updating stats counters.
+                       [RT #38826]
+
 4083.  [cleanup]       Print the number of CPUs and UDP listeners
                        consistently in the log and in "rndc status"
                        output; indicate whether threads are supported
index 2e9308fae2a636cda8a3acc40808bfcfdf0ca955..669ea2a3763b4db35893c6eb0ab603b9c0772a84 100644 (file)
@@ -1262,13 +1262,10 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
        }
 
        ADD_TRACE(ctx, ptr, size, file, line);
-       if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
-           !ctx->is_overmem) {
+       if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
                ctx->is_overmem = ISC_TRUE;
-       }
-       if (ctx->hi_water != 0U && !ctx->hi_called &&
-           ctx->inuse > ctx->hi_water) {
-               call_water = ISC_TRUE;
+               if (!ctx->hi_called)
+                       call_water = ISC_TRUE;
        }
        if (ctx->inuse > ctx->maxinuse) {
                ctx->maxinuse = ctx->inuse;
@@ -1279,7 +1276,7 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
        }
        MCTXUNLOCK(ctx, &ctx->lock);
 
-       if (call_water)
+       if (call_water && (ctx->water != NULL))
                (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
 
        return (ptr);
@@ -1323,18 +1320,15 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
         * when the context was pushed over hi_water but then had
         * isc_mem_setwater() called with 0 for hi_water and lo_water.
         */
-       if (ctx->is_overmem &&
-           (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
+       if ((ctx->inuse < ctx->lo_water) || (ctx->lo_water == 0U)) {
                ctx->is_overmem = ISC_FALSE;
-       }
-       if (ctx->hi_called &&
-           (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
-               if (ctx->water != NULL)
+               if (ctx->hi_called)
                        call_water = ISC_TRUE;
        }
+
        MCTXUNLOCK(ctx, &ctx->lock);
 
-       if (call_water)
+       if (call_water && (ctx->water != NULL))
                (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
 }
 
@@ -1387,8 +1381,8 @@ print_active(isc__mem_t *mctx, FILE *out) {
                        }
                }
                if (!found)
-                       fprintf(out, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
-                                                   ISC_MSG_NONE, "\tNone.\n"));
+                       fputs(isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
+                                            ISC_MSG_NONE, "\tNone.\n"), out);
        }
 }
 #endif
@@ -1510,15 +1504,10 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
 
        REQUIRE(VALID_CONTEXT(ctx));
 
-       if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
-               MCTXLOCK(ctx, &ctx->lock);
-               si = mem_allocateunlocked((isc_mem_t *)ctx, size);
-       } else {
-               si = mem_allocateunlocked((isc_mem_t *)ctx, size);
-               MCTXLOCK(ctx, &ctx->lock);
-               if (si != NULL)
-                       mem_getstats(ctx, si[-1].u.size);
-       }
+       MCTXLOCK(ctx, &ctx->lock);
+       si = mem_allocateunlocked((isc_mem_t *)ctx, size);
+       if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0) && (si != NULL))
+               mem_getstats(ctx, si[-1].u.size);
 
 #if ISC_MEM_TRACKLINES
        ADD_TRACE(ctx, si, si[-1].u.size, file, line);
@@ -1773,7 +1762,6 @@ isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
                ctx->water_arg = NULL;
                ctx->hi_water = 0;
                ctx->lo_water = 0;
-               ctx->hi_called = ISC_FALSE;
        } else {
                if (ctx->hi_called &&
                    (ctx->water != water || ctx->water_arg != water_arg ||
@@ -2596,6 +2584,8 @@ json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) {
        CHECKMEM(obj);
        json_object_object_add(ctxobj, "pools", obj);
 
+       summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t);
+
        obj = json_object_new_int64(ctx->hi_water);
        CHECKMEM(obj);
        json_object_object_add(ctxobj, "hiwater", obj);