Date: Wed, 13 Feb 2008 12:44:01 -0800 From: JINMEI Tatuya / =?ISO-2022-JP?B?GyRCP0BMQEMjOkgbKEI=?= <Jinmei_Tatuya@isc.org> To: Attila Nagy <bra@fsn.hu> Cc: freebsd-performance@freebsd.org, bind-users@isc.org Subject: Re: max-cache-size doesn't work with 9.5.0b1 Message-ID: <m2abm4y4by.wl%Jinmei_Tatuya@isc.org> In-Reply-To: <47B2DD62.6020507@fsn.hu> References: <475B0F3E.5070100@fsn.hu> <m2lk6g71bc.wl%Jinmei_Tatuya@isc.org> <479DFE74.8030004@fsn.hu> <m2k5ltke09.wl%Jinmei_Tatuya@isc.org> <479F02A7.9020607@fsn.hu> <m24pcwt5b7.wl%Jinmei_Tatuya@isc.org> <47A614E9.4030501@fsn.hu> <m2wspkpl7r.wl%Jinmei_Tatuya@isc.org> <47A77A13.6010802@fsn.hu> <m2zlueohxk.wl%Jinmei_Tatuya@isc.org> <47B1D2F4.5070304@fsn.hu> <m2tzkexdo7.wl%Jinmei_Tatuya@isc.org> <47B2DD62.6020507@fsn.hu>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
At Wed, 13 Feb 2008 13:06:58 +0100,
Attila Nagy <bra@fsn.hu> wrote:
> Of course. See the bindn1 files at the same location. (only the memory
> section included)
> The effect is pretty much the same.
Okay, then please try this patch with '-n 1' (note: this patch doesn't
contain the memory statistics hack via the HTTP interface, but I don't
we don't need it for this test).
---
JINMEI, Tatuya
Internet Systems Consortium, Inc.
[-- Attachment #2 --]
? lib/bind/include/isc/platform.h
? lib/dns/gen.dSYM
? lib/dns/rbtdb.c-test
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 13 Feb 2008 20:39:57 -0000
@@ -56,6 +56,10 @@
#include <dns/resolver.h>
#include <dns/result.h>
+#ifndef LRU_DEBUG2
+#define LRU_DEBUG2 0
+#endif
+
#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
@@ -133,7 +137,7 @@
isc_timermgr_t *timermgr;
isc_timer_t *timer;
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
isc_timer_t *dump_timer; /* for test */
isc_time_t dump_time; /* for test */
#define DUMP_INTERVAL 30 /* seconds */
@@ -355,7 +359,7 @@
static void water(void *, int);
static void dump_entry(FILE *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t);
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
static void timer_dump(isc_task_t *, isc_event_t *);
#endif
@@ -816,9 +820,9 @@
static inline void
violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
- UNLOCK(have);
+ /*UNLOCK(have);*/
LOCK(want);
- LOCK(have);
+ /*LOCK(have);*/
}
}
@@ -1069,10 +1073,10 @@
find = event->ev_destroy_arg;
INSIST(DNS_ADBFIND_VALID(find));
- LOCK(&find->lock);
+ /*LOCK(&find->lock);*/
find->flags |= FIND_EVENT_FREED;
event->ev_destroy_arg = NULL;
- UNLOCK(&find->lock);
+ /*UNLOCK(&find->lock);*/
}
/*
@@ -1095,7 +1099,7 @@
find = ISC_LIST_HEAD(name->finds);
while (find != NULL) {
- LOCK(&find->lock);
+ /*LOCK(&find->lock);*/
next_find = ISC_LIST_NEXT(find, plink);
process = ISC_FALSE;
@@ -1153,7 +1157,7 @@
DP(DEF_LEVEL, "cfan: skipping find %p", find);
}
- UNLOCK(&find->lock);
+ /*UNLOCK(&find->lock);*/
find = next_find;
}
@@ -1486,11 +1490,13 @@
/*
* private members
*/
+#if 0 /* disable for diagnose */
result = isc_mutex_init(&h->lock);
if (result != ISC_R_SUCCESS) {
isc_mempool_put(adb->ahmp, h);
return (NULL);
}
+#endif
ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
NULL, NULL, h);
@@ -1573,7 +1579,9 @@
find->magic = 0;
+#if 0 /* disable for diagnose */
DESTROYLOCK(&find->lock);
+#endif
isc_mempool_put(adb->ahmp, find);
return (dec_adb_irefcnt(adb));
}
@@ -1830,7 +1838,7 @@
*/
LOCK(&adb->lock);
isc_timer_detach(&adb->timer);
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
isc_timer_detach(&adb->dump_timer);
#endif
UNLOCK(&adb->lock);
@@ -2181,7 +2189,7 @@
adb->afmp = NULL;
adb->task = NULL;
adb->timer = NULL;
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
adb->dump_timer = NULL;
#endif
adb->mctx = NULL;
@@ -2288,7 +2296,7 @@
if (result != ISC_R_SUCCESS)
goto fail3;
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
{
isc_interval_t interval;
@@ -2811,7 +2819,7 @@
find = *findp;
*findp = NULL;
- LOCK(&find->lock);
+ /*LOCK(&find->lock);*/
DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
@@ -2823,7 +2831,7 @@
bucket = find->name_bucket;
INSIST(bucket == DNS_ADB_INVALIDBUCKET);
- UNLOCK(&find->lock);
+ /*UNLOCK(&find->lock);*/
/*
* The find doesn't exist on any list, and nothing is locked.
@@ -2863,7 +2871,7 @@
int bucket;
int unlock_bucket;
- LOCK(&find->lock);
+ /*LOCK(&find->lock);*/
DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
@@ -2909,7 +2917,7 @@
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
}
- UNLOCK(&find->lock);
+ /*UNLOCK(&find->lock);*/
}
void
@@ -3071,7 +3079,7 @@
* want to dump out the name and/or entries too.
*/
- LOCK(&find->lock);
+ /*LOCK(&find->lock);*/
fprintf(f, ";Find %p\n", find);
fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
@@ -3108,7 +3116,7 @@
ai = ISC_LIST_NEXT(ai, publink);
}
- UNLOCK(&find->lock);
+ /*UNLOCK(&find->lock);*/
}
static void
@@ -3779,6 +3787,13 @@
REQUIRE(DNS_ADB_VALID(adb));
+#if LRU_DEBUG2 > 1
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE, ISC_LOG_INFO,
+ "ADB %p: overmem switch to %s, mem inuse %lu",
+ adb, overmem ? "TRUE" : "FALSE",
+ (unsigned long)isc_mem_inuse(adb->mctx));
+#endif
DP(ISC_LOG_DEBUG(1),
"adb reached %s water mark", overmem ? "high" : "low");
@@ -3813,7 +3828,7 @@
isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
}
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
/*
* Periodic dumping of the internal state of the statistics.
* This will dump the cache contents, uses, record types, etc.
@@ -3830,18 +3845,11 @@
INSIST(DNS_ADB_VALID(adb));
LOCK(&adb->lock);
- if (adb->nname > 0 || adb->nentry > 0) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ADB, ISC_LOG_INFO,
- "ADB memory usage %p: mem inuse %lu, "
- "%u/%u names, %u/%u entries, "
- "purge/scan=%u(%u,%u)/%u, overmem=%d",
- adb, (unsigned long)isc_mem_inuse(adb->mctx),
- adb->nname, adb->nname_total,
- adb->nentry, adb->nentry_total,
- adb->stale_purge, adb->stale_expire,
- adb->stale_lru, adb->stale_scan, adb->overmem);
- }
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_ADB, ISC_LOG_INFO,
+ "ADB memory usage %p: mem inuse %lu, overmem=%d",
+ adb, (unsigned long)isc_mem_inuse(adb->mctx),
+ adb->overmem);
interval.seconds = DUMP_INTERVAL;
interval.nanoseconds = 0;
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 13 Feb 2008 20:39:57 -0000
@@ -55,6 +55,10 @@
*/
#define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */
+#ifndef LRU_DEBUG2
+#define LRU_DEBUG2 0
+#endif
+
/***
*** Types
***/
@@ -128,7 +132,7 @@
char * filename;
/* Access to the on-disk cache file is also locked by 'filelock'. */
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
#define DUMP_INTERVAL 30 /* seconds */
isc_timer_t *dump_timer; /* for test */
isc_time_t dump_time; /* for test */
@@ -149,7 +153,7 @@
static void
cleaner_shutdown_action(isc_task_t *task, isc_event_t *event);
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
static void
timer_dump(isc_task_t *task, isc_event_t *event);
#endif
@@ -548,7 +552,7 @@
isc_timermgr_t *timermgr, cache_cleaner_t *cleaner)
{
isc_result_t result;
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
isc_interval_t interval;
#endif
@@ -600,7 +604,7 @@
goto cleanup;
}
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
interval.seconds = DUMP_INTERVAL;
interval.nanoseconds = 0;
RUNTIME_CHECK(isc_time_nowplusinterval(&cache->dump_time,
@@ -780,7 +784,7 @@
if (cache->cleaner.cleaning_timer != NULL)
isc_timer_detach(&cache->cleaner.cleaning_timer);
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
isc_timer_detach(&cache->dump_timer);
#endif
@@ -872,7 +876,7 @@
return (result);
}
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
static void
timer_dump(isc_task_t *task, isc_event_t *event) {
dns_cache_t *cache;
@@ -884,7 +888,7 @@
cache = event->ev_arg;
INSIST(VALID_CACHE(cache));
-#ifdef LRU_DEBUG
+#if LRU_DEBUG2
/* XXX: abuse existing overmem method */
dns_db_overmem(cache->db, (isc_boolean_t)-1);
#endif
Index: lib/dns/rbtdb.c
===================================================================
RCS file: /proj/cvs/prod/bind9/lib/dns/rbtdb.c,v
retrieving revision 1.248
diff -u -r1.248 rbtdb.c
--- lib/dns/rbtdb.c 2 Dec 2007 20:27:35 -0000 1.248
+++ lib/dns/rbtdb.c 13 Feb 2008 20:39:57 -0000
@@ -1633,7 +1633,8 @@
"decrement_reference: "
"dns_rbt_deletenode: %s",
isc_result_totext(result));
- } else if (dns_rbtnode_refcurrent(node) == 0) {
+ } else if (dns_rbtnode_refcurrent(node) == 0 &&
+ rbtdb->deadnodes != NULL) {
INSIST(!ISC_LINK_LINKED(node, deadlink));
ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink);
}
@@ -1914,6 +1915,15 @@
}
if (!EMPTY(cleanup_list)) {
+ /*
+ * We acquire a tree write lock here in order to make sure
+ * that stale nodes will be removed in decrement_reference().
+ * If we didn't have the lock, those nodes could miss the
+ * chance to be removed until the server stops. The write lock
+ * is expensive, but this event should be rare enough to justify
+ * the cost.
+ */
+ RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
for (changed = HEAD(cleanup_list);
changed != NULL;
changed = next_changed) {
@@ -1928,12 +1938,13 @@
rollback_node(rbtnode, serial);
decrement_reference(rbtdb, rbtnode, least_serial,
isc_rwlocktype_write,
- isc_rwlocktype_none);
+ isc_rwlocktype_write);
NODE_UNLOCK(lock, isc_rwlocktype_write);
isc_mem_put(rbtdb->common.mctx, changed,
sizeof(*changed));
}
+ RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
}
end:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m2abm4y4by.wl%Jinmei_Tatuya>
