Please try this patch.
Mark
Revised.
Index: lib/isc/mem.c
===================================================================
RCS file: /proj/cvs/prod/bind9/lib/isc/mem.c,v
retrieving revision 1.140
diff -u -r1.140 mem.c
--- lib/isc/mem.c 18 Jan 2008 23:46:58 -0000 1.140
+++ lib/isc/mem.c 4 Feb 2008 00:29:44 -0000
@@ -1086,7 +1086,6 @@
ADD_TRACE(ctx, ptr, size, file, line);
if (ctx->hi_water != 0U && !ctx->hi_called &&
ctx->inuse > ctx->hi_water) {
- ctx->hi_called = ISC_TRUE;
call_water = ISC_TRUE;
}
if (ctx->inuse > ctx->maxinuse) {
@@ -1144,8 +1143,6 @@
*/
if (ctx->hi_called &&
(ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
- ctx->hi_called = ISC_FALSE;
-
if (ctx->water != NULL)
call_water = ISC_TRUE;
}
@@ -1155,6 +1152,18 @@
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
}
+void
+isc_mem_water(isc_mem_t *ctx, int flag) {
+ REQUIRE(VALID_CONTEXT(ctx));
+
+ MCTXLOCK(ctx, &ctx->lock);
+ if (flag == ISC_MEM_LOWATER)
+ ctx->hi_called = ISC_FALSE;
+ else if (flag == ISC_MEM_HIWATER)
+ ctx->hi_called = ISC_TRUE;
+ MCTXUNLOCK(ctx, &ctx->lock);
+}
+
#if ISC_MEM_TRACKLINES
static void
print_active(isc_mem_t *mctx, FILE *out) {
Index: lib/dns/acache.c
===================================================================
RCS file: /proj/cvs/prod/bind9/lib/dns/acache.c,v
retrieving revision 1.20
diff -u -r1.20 acache.c
--- lib/dns/acache.c 19 Jun 2007 23:47:16 -0000 1.20
+++ lib/dns/acache.c 4 Feb 2008 00:29:46 -0000
@@ -965,10 +965,14 @@
LOCK(&acache->cleaner.lock);
- acache->cleaner.overmem = overmem;
+ if (acache->cleaner.overmem != overmem) {
+ acache->cleaner.overmem = overmem;
- if (acache->cleaner.overmem_event != NULL)
- isc_task_send(acache->task, &acache->cleaner.overmem_event);
+ if (acache->cleaner.overmem_event != NULL)
+ isc_task_send(acache->task,
+ &acache->cleaner.overmem_event);
+ isc_mem_water(acache->mctx, mark);
+ }
UNLOCK(&acache->cleaner.lock);
}
Index: lib/dns/adb.c
===================================================================
RCS file: /proj/cvs/prod/bind9/lib/dns/adb.c,v
retrieving revision 1.233
diff -u -r1.233 adb.c
--- lib/dns/adb.c 19 Oct 2007 17:15:53 -0000 1.233
+++ lib/dns/adb.c 4 Feb 2008 00:29:50 -0000
@@ -128,6 +128,7 @@
isc_mutex_t lock;
isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt
*/
+ isc_mutex_t overmemlock; /*%< Covers overmem */
isc_mem_t *mctx;
dns_view_t *view;
isc_timermgr_t *timermgr;
@@ -2138,6 +2139,7 @@
DESTROYLOCK(&adb->reflock);
DESTROYLOCK(&adb->lock);
DESTROYLOCK(&adb->mplock);
+ DESTROYLOCK(&adb->overmemlock);
isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
}
@@ -2225,6 +2227,10 @@
if (result != ISC_R_SUCCESS)
goto fail0d;
+ result = isc_mutex_init(&adb->overmemlock);
+ if (result != ISC_R_SUCCESS)
+ goto fail0e;
+
/*
* Initialize the bucket locks for names and elements.
* May as well initialize the list heads, too.
@@ -2343,6 +2349,8 @@
if (adb->afmp != NULL)
isc_mempool_destroy(&adb->afmp);
+ DESTROYLOCK(&adb->overmemlock);
+ fail0e:
DESTROYLOCK(&adb->reflock);
fail0d:
DESTROYLOCK(&adb->mplock);
@@ -3782,16 +3790,21 @@
DP(ISC_LOG_DEBUG(1),
"adb reached %s water mark", overmem ? "high" : "low");
- adb->overmem = overmem;
+ LOCK(&adb->overmemlock);
+ if (adb->overmem != overmem) {
+ adb->overmem = overmem;
#if 0 /* we don't need this timer for the new cleaning policy. */
- if (overmem) {
- isc_interval_t interval;
+ if (overmem) {
+ isc_interval_t interval;
- isc_interval_set(&interval, 0, 1);
- (void)isc_timer_reset(adb->timer, isc_timertype_once, NULL,
- &interval, ISC_TRUE);
- }
-#endif
+ isc_interval_set(&interval, 0, 1);
+ (void)isc_timer_reset(adb->timer, isc_timertype_once,
+ NULL, &interval, ISC_TRUE);
+ }
+#endif
+ isc_mem_water(adb->mctx, mark);
+ }
+ UNLOCK(&adb->overmemlock);
}
void
Index: lib/dns/cache.c
===================================================================
RCS file: /proj/cvs/prod/bind9/lib/dns/cache.c,v
retrieving revision 1.76
diff -u -r1.76 cache.c
--- lib/dns/cache.c 19 Oct 2007 17:15:53 -0000 1.76
+++ lib/dns/cache.c 4 Feb 2008 00:29:51 -0000
@@ -708,8 +708,11 @@
LOCK(&cache->cleaner.lock);
- dns_db_overmem(cache->db, overmem);
- cache->cleaner.overmem = overmem;
+ if (overmem != cache->cleaner.overmem) {
+ dns_db_overmem(cache->db, overmem);
+ cache->cleaner.overmem = overmem;
+ isc_mem_water(cache->mctx, mark);
+ }
UNLOCK(&cache->cleaner.lock);
}