From: Mukund Sivaraman Date: Mon, 9 Mar 2015 04:59:03 +0000 (+0530) Subject: Fix a possible race in updating stats counters (#38826) X-Git-Tag: v9.11.0a1~923 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=24f2cc7d06e4bb6625f90323e44b42e0cad63588;p=thirdparty%2Fbind9.git Fix a possible race in updating stats counters (#38826) and do some other isc mem cleanups. --- diff --git a/CHANGES b/CHANGES index a603cbca4c7..955658b63d3 100644 --- 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 diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 2e9308fae2a..669ea2a3763 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -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);