Skip site navigation (1)Skip section navigation (2)
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>