]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
cleanups for LRU-caching code [RT #18018]
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 1 May 2008 18:32:32 +0000 (18:32 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 1 May 2008 18:32:32 +0000 (18:32 +0000)
bin/named/config.c
doc/arm/Bv9ARM-book.xml
lib/dns/adb.c
lib/dns/cache.c
lib/dns/rbtdb.c
lib/dns/resolver.c

index a5460a9263095226fa45422c59900b26b91fcc1c..ac1074b4c25171696ce017a4b9aac150a023239c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: config.c,v 1.82.38.3 2008/04/03 02:12:21 marka Exp $ */
+/* $Id: config.c,v 1.82.38.4 2008/05/01 18:32:31 jinmei Exp $ */
 
 /*! \file */
 
@@ -124,7 +124,7 @@ options {\n\
        query-source-v6 address *;\n\
        notify-source *;\n\
        notify-source-v6 *;\n\
-       cleaning-interval 60;\n\
+       cleaning-interval 0;  /* now meaningless */\n\
        min-roots 2;\n\
        lame-ttl 600;\n\
        max-ncache-ttl 10800; /* 3 hours */\n\
index 3a27785546bc34a88a1d3b17a1895cc0bd8cfb0f..e8d97a1efb01a20f0a3617fddddf85855b80652e 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.340.24.7 2008/04/09 22:53:50 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.340.24.8 2008/05/01 18:32:31 jinmei Exp $ -->
 <book xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>BIND 9 Administrator Reference Manual</title>
 
@@ -6858,11 +6858,14 @@ query-source-v6 address * port *;
               <term><command>cleaning-interval</command></term>
               <listitem>
                 <para>
-                  The server will remove expired resource records
+                 This interval is effectively obsolete.  Previously,
+                 the server would remove expired resource records
                   from the cache every <command>cleaning-interval</command> minutes.
-                  The default is 60 minutes.  The maximum value is 28 days
-                  (40320 minutes).
-                  If set to 0, no periodic cleaning will occur.
+                 <acronym>BIND</acronym> 9 now manages cache
+                 memory in a more sophisticated manner and does not
+                 rely on the periodic cleaning any more.
+                 Specifying this option therefore has no effect on
+                 the server's behavior.
                 </para>
               </listitem>
             </varlistentry>
index 00d199fe9a9816ca0708037ddb05fc47df4fc4e3..e4b117ff28bfb9ff375abccb42b6bc91fc76e016 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: adb.c,v 1.233.36.5 2008/04/03 06:20:34 tbox Exp $ */
+/* $Id: adb.c,v 1.233.36.6 2008/05/01 18:32:31 jinmei Exp $ */
 
 /*! \file
  *
  *
  */
 
-/*%
- * After we have cleaned all buckets, dump the database contents.
- */
-#if 0
-#define DUMP_ADB_AFTER_CLEANING
-#endif
-
 #include <config.h>
 
 #include <limits.h>
@@ -42,7 +35,6 @@
 #include <isc/random.h>
 #include <isc/string.h>         /* Required for HP/UX (and others?) */
 #include <isc/task.h>
-#include <isc/timer.h>
 #include <isc/util.h>
 
 #include <dns/adb.h>
 #define ADB_CACHE_MAXIMUM       86400   /*%< seconds (86400 = 24 hours) */
 #define ADB_ENTRY_WINDOW        1800    /*%< seconds */
 
-/*%
- * Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all
- * buckets are cleaned in CLEAN_PERIOD seconds.
- */
-#define CLEAN_PERIOD            3600
-/*% See #CLEAN_PERIOD */
-#define CLEAN_SECONDS           30
-/*% See #CLEAN_PERIOD */
-#define CLEAN_BUCKETS           ((NBUCKETS * CLEAN_SECONDS) / CLEAN_PERIOD)
-
 /*%
  * The period in seconds after which an ADB name entry is regarded as stale
  * and forced to be cleaned up.
@@ -132,14 +114,6 @@ struct dns_adb {
        isc_mutex_t                     overmemlock; /*%< Covers overmem */
        isc_mem_t                      *mctx;
        dns_view_t                     *view;
-       isc_timermgr_t                 *timermgr;
-       isc_timer_t                    *timer;
-
-#ifdef LRU_DEBUG
-       isc_timer_t                    *dump_timer; /* for test */
-       isc_time_t                      dump_time; /* for test */
-#define DUMP_INTERVAL 30        /* seconds */
-#endif
 
        isc_taskmgr_t                  *taskmgr;
        isc_task_t                     *task;
@@ -187,17 +161,6 @@ struct dns_adb {
        isc_boolean_t                   cevent_sent;
        isc_boolean_t                   shutting_down;
        isc_eventlist_t                 whenshutdown;
-
-#ifdef LRU_DEBUG
-       unsigned int                    stale_purge;
-       unsigned int                    stale_scan;
-       unsigned int                    stale_expire;
-       unsigned int                    stale_lru;
-
-       unsigned int                    nname, nname_total;
-       unsigned int                    nentry, nentry_total;
-       unsigned int                    nameuses, entryuses;
-#endif
 };
 
 /*
@@ -344,7 +307,6 @@ static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
 static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t,
                               dns_rdatatype_t);
 static inline void check_exit(dns_adb_t *);
-static void timer_cleanup(isc_task_t *, isc_event_t *);
 static void destroy(dns_adb_t *);
 static isc_boolean_t shutdown_names(dns_adb_t *);
 static isc_boolean_t shutdown_entries(dns_adb_t *);
@@ -357,10 +319,6 @@ static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t,
 static void water(void *, int);
 static void dump_entry(FILE *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t);
 
-#ifdef LRU_DEBUG
-static void timer_dump(isc_task_t *, isc_event_t *);
-#endif
-
 /*
  * MUST NOT overlap DNS_ADBFIND_* flags!
  */
@@ -1332,11 +1290,6 @@ free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
        INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
        INSIST(n->adb == adb);
 
-#ifdef LRU_DEBUG
-       adb->nname--;           /* XXX: omit ADB lock for brevity */
-       INSIST((int)adb->nname >= 0);
-#endif
-
        n->magic = 0;
        dns_name_free(&n->name, adb->mctx);
 
@@ -1430,11 +1383,6 @@ new_adbentry(dns_adb_t *adb) {
        ISC_LIST_INIT(e->lameinfo);
        ISC_LINK_INIT(e, plink);
 
-#ifdef LRU_DEBUG
-       adb->nentry++;  /* XXX: omit ADB lock for brevity */
-       adb->nentry_total++;
-#endif
-
        return (e);
 }
 
@@ -1460,11 +1408,6 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
                li = ISC_LIST_HEAD(e->lameinfo);
        }
 
-#ifdef LRU_DEBUG
-       adb->nentry--;  /* XXX: omit ADB lock for brevity */
-       INSIST((int)adb->nentry >= 0);
-#endif
-
        isc_mempool_put(adb->emp, e);
 }
 
@@ -1609,10 +1552,6 @@ new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
        ai->entry = entry;
        ISC_LINK_INIT(ai, publink);
 
-#ifdef LRU_DEBUG
-       adb->entryuses++;       /* for debug */
-#endif
-
        return (ai);
 }
 
@@ -1832,18 +1771,6 @@ shutdown_task(isc_task_t *task, isc_event_t *ev) {
        adb = ev->ev_arg;
        INSIST(DNS_ADB_VALID(adb));
 
-       /*
-        * Kill the timer, and then the ADB itself.  Note that this implies
-        * that this task was the one scheduled to get timer events.  If
-        * this is not true (and it is unfortunate there is no way to INSIST()
-        * this) badness will occur.
-        */
-       LOCK(&adb->lock);
-       isc_timer_detach(&adb->timer);
-#ifdef LRU_DEBUG
-       isc_timer_detach(&adb->dump_timer);
-#endif
-       UNLOCK(&adb->lock);
        isc_event_free(&ev);
        destroy(adb);
 }
@@ -1928,9 +1855,6 @@ check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
 
                result = check_expire_name(&victim, now);
                if (victim == NULL) {
-#ifdef LRU_DEBUG
-                       adb->stale_expire++;
-#endif
                        victims++;
                        goto next;
                }
@@ -1941,9 +1865,6 @@ check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
                                                DNS_EVENT_ADBCANCELED,
                                                ISC_TRUE) ==
                                      ISC_FALSE);
-#ifdef LRU_DEBUG
-                       adb->stale_lru++;
-#endif
                        victims++;
                }
 
@@ -1951,12 +1872,6 @@ check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
                if (!overmem)
                        break;
        }
-
-#ifdef LRU_DEBUG
-       /* XXX: omit lock for brevity */
-       adb->stale_scan += scans;
-       adb->stale_purge += victims;
-#endif
 }
 
 /*
@@ -2042,96 +1957,10 @@ cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
        return (result);
 }
 
-#if 1
-static void
-timer_cleanup(isc_task_t *task, isc_event_t *ev) {
-       UNUSED(task);
-
-       isc_event_free(&ev);
-}
-#else
-static void
-timer_cleanup(isc_task_t *task, isc_event_t *ev) {
-       dns_adb_t *adb;
-       isc_stdtime_t now;
-       unsigned int i;
-       isc_interval_t interval;
-
-       UNUSED(task);
-
-       adb = ev->ev_arg;
-       INSIST(DNS_ADB_VALID(adb));
-
-       LOCK(&adb->lock);
-
-       isc_stdtime_get(&now);
-
-       for (i = 0; i < CLEAN_BUCKETS; i++) {
-               /*
-                * Call our cleanup routines.
-                */
-               RUNTIME_CHECK(cleanup_names(adb, adb->next_cleanbucket, now) ==
-                             ISC_FALSE);
-               RUNTIME_CHECK(cleanup_entries(adb, adb->next_cleanbucket, now)
-                             == ISC_FALSE);
-
-               /*
-                * Set the next bucket to be cleaned.
-                */
-               adb->next_cleanbucket++;
-               if (adb->next_cleanbucket >= NBUCKETS) {
-                       adb->next_cleanbucket = 0;
-#ifdef DUMP_ADB_AFTER_CLEANING
-                       dump_adb(adb, stdout, ISC_TRUE, now);
-#endif
-               }
-       }
-
-       /*
-        * Reset the timer.
-        * XXXDCL isc_timer_reset might return ISC_R_UNEXPECTED or
-        * ISC_R_NOMEMORY, but it isn't clear what could be done here
-        * if either one of those things happened.
-        */
-       interval = adb->tick_interval;
-       if (adb->overmem)
-               isc_interval_set(&interval, 0, 1);
-       (void)isc_timer_reset(adb->timer, isc_timertype_once, NULL,
-                             &interval, ISC_FALSE);
-
-       UNLOCK(&adb->lock);
-
-       isc_event_free(&ev);
-}
-#endif
-
 static void
 destroy(dns_adb_t *adb) {
        adb->magic = 0;
 
-#ifdef LRU_DEBUG
-       /* for debug: print statistics */
-       if (adb->nname_total > 0) {
-               INSIST(adb->nname == 0 && adb->nentry == 0);
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_ADB, ISC_LOG_INFO,
-                             "ADB %p name hit %.2f, entry hit %.2f", adb,
-                             (double)adb->nameuses /
-                             (adb->nname_total + adb->nameuses),
-                             adb->entryuses > 0 ?
-                             (double)adb->entryuses /
-                             (adb->nentry_total + adb->entryuses) : 0);
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_ADB, ISC_LOG_INFO,
-                             "ADB %p stale name purges: %u(%u,%u)/%u",
-                             adb, adb->stale_purge, adb->stale_expire,
-                             adb->stale_lru, adb->stale_scan);
-       }
-#endif
-
-       /*
-        * The timer is already dead, from the task's shutdown callback.
-        */
        isc_task_detach(&adb->task);
 
        isc_mempool_destroy(&adb->nmp);
@@ -2168,10 +1997,12 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
 
        REQUIRE(mem != NULL);
        REQUIRE(view != NULL);
-       REQUIRE(timermgr != NULL);
+       REQUIRE(timermgr != NULL); /* this is actually unused */
        REQUIRE(taskmgr != NULL);
        REQUIRE(newadb != NULL && *newadb == NULL);
 
+       UNUSED(timermgr);
+
        adb = isc_mem_get(mem, sizeof(dns_adb_t));
        if (adb == NULL)
                return (ISC_R_NOMEMORY);
@@ -2191,13 +2022,8 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
        adb->aimp = NULL;
        adb->afmp = NULL;
        adb->task = NULL;
-       adb->timer = NULL;
-#ifdef LRU_DEBUG
-       adb->dump_timer = NULL;
-#endif
        adb->mctx = NULL;
        adb->view = view;
-       adb->timermgr = timermgr;
        adb->taskmgr = taskmgr;
        adb->next_cleanbucket = 0;
        ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
@@ -2208,20 +2034,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
        adb->overmem = ISC_FALSE;
        ISC_LIST_INIT(adb->whenshutdown);
 
-#ifdef LRU_DEBUG
-       /* for debug */
-       adb->nname = 0;
-       adb->nname_total = 0;
-       adb->nentry = 0;
-       adb->nentry_total = 0;
-       adb->stale_purge = 0;
-       adb->stale_scan = 0;
-       adb->stale_expire = 0;
-       adb->stale_lru = 0;
-       adb->nameuses = 0;
-       adb->entryuses = 0;
-#endif
-
        isc_mem_attach(mem, &adb->mctx);
 
        result = isc_mutex_init(&adb->lock);
@@ -2287,41 +2099,12 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
 #undef MPINIT
 
        /*
-        * Allocate a timer and a task for our periodic cleanup.
+        * Allocate an internal task.
         */
        result = isc_task_create(adb->taskmgr, 0, &adb->task);
        if (result != ISC_R_SUCCESS)
                goto fail3;
        isc_task_setname(adb->task, "ADB", adb);
-       /*
-        * XXXMLG When this is changed to be a config file option,
-        */
-       isc_interval_set(&adb->tick_interval, CLEAN_SECONDS, 0);
-       result = isc_timer_create(adb->timermgr, isc_timertype_once,
-                                 NULL, &adb->tick_interval, adb->task,
-                                 timer_cleanup, adb, &adb->timer);
-       if (result != ISC_R_SUCCESS)
-               goto fail3;
-
-#ifdef LRU_DEBUG
-       {
-               isc_interval_t interval;
-
-               interval.seconds = DUMP_INTERVAL;
-               interval.nanoseconds = 0;
-               RUNTIME_CHECK(isc_time_nowplusinterval(&adb->dump_time,
-                                                      &interval) ==
-                             ISC_R_SUCCESS);
-
-               result = isc_timer_create(adb->timermgr, isc_timertype_once,
-                                         &adb->dump_time, NULL, adb->task,
-                                         timer_dump, adb, &adb->dump_timer);
-       }
-#endif
-
-       DP(ISC_LOG_DEBUG(5), "cleaning interval for adb: "
-          "%u buckets every %u seconds, %u buckets in system, %u cl.interval",
-          CLEAN_BUCKETS, CLEAN_SECONDS, NBUCKETS, CLEAN_PERIOD);
 
        /*
         * Normal return.
@@ -2333,8 +2116,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
  fail3:
        if (adb->task != NULL)
                isc_task_detach(&adb->task);
-       if (adb->timer != NULL)
-               isc_timer_detach(&adb->timer);
 
        /* clean up entrylocks */
        DESTROYMUTEXBLOCK(adb->entrylocks, NBUCKETS);
@@ -2578,18 +2359,10 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
                        adbname->flags |= NAME_GLUE_OK;
                if (FIND_STARTATZONE(find))
                        adbname->flags |= NAME_STARTATZONE;
-
-#ifdef LRU_DEBUG
-               adb->nname++;   /* XXX: omit ADB lock for brevity */
-               adb->nname_total++;
-#endif
        } else {
                /* Move this name forward in the LRU list */
                ISC_LIST_UNLINK(adb->names[bucket], adbname, plink);
                ISC_LIST_PREPEND(adb->names[bucket], adbname, plink);
-#ifdef LRU_DEBUG
-               adb->nameuses++;
-#endif
        }
        adbname->last_used = now;
 
@@ -3813,15 +3586,6 @@ water(void *arg, int mark) {
        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;
-
-                       isc_interval_set(&interval, 0, 1);
-                       (void)isc_timer_reset(adb->timer, isc_timertype_once,
-                                             NULL, &interval, ISC_TRUE);
-               }
-#endif
                isc_mem_waterack(adb->mctx, mark);
        }
        UNLOCK(&adb->overmemlock);
@@ -3845,47 +3609,3 @@ dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) {
        else
                isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
 }
-
-#ifdef LRU_DEBUG
-/*
- * Periodic dumping of the internal state of the statistics.
- * This will dump the cache contents, uses, record types, etc.
- */
-static void
-timer_dump(isc_task_t *task, isc_event_t *ev) {
-       dns_adb_t *adb;
-       isc_interval_t interval;
-       isc_time_t nexttime;
-
-       UNUSED(task);
-
-       adb = ev->ev_arg;
-       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);
-       }
-
-       interval.seconds = DUMP_INTERVAL;
-       interval.nanoseconds = 0;
-
-       RUNTIME_CHECK(isc_time_add(&adb->dump_time, &interval, &nexttime) ==
-                     ISC_R_SUCCESS); /* XXX: this is not always true */
-       adb->dump_time = nexttime;
-       (void)isc_timer_reset(adb->dump_timer, isc_timertype_once,
-                             &adb->dump_time, NULL, ISC_FALSE);
-       UNLOCK(&adb->lock);
-
-       isc_event_free(&ev);
-}
-#endif
index 3176fe791b08df23b0cfa767b7fd7d2224cb5690..6f1e189b98d8e8b8a9d95bd9108c4ddd29ffb4f5 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: cache.c,v 1.76.36.2 2008/02/07 23:46:25 tbox Exp $ */
+/* $Id: cache.c,v 1.76.36.3 2008/05/01 18:32:31 jinmei Exp $ */
 
 /*! \file */
 
 #include <config.h>
 
 #include <isc/mem.h>
+#include <isc/string.h>
 #include <isc/task.h>
 #include <isc/time.h>
 #include <isc/timer.h>
 #include <dns/rdatasetiter.h>
 #include <dns/result.h>
 
-#define CACHE_MAGIC             ISC_MAGIC('$', '$', '$', '$')
-#define VALID_CACHE(cache)      ISC_MAGIC_VALID(cache, CACHE_MAGIC)
+#define CACHE_MAGIC            ISC_MAGIC('$', '$', '$', '$')
+#define VALID_CACHE(cache)     ISC_MAGIC_VALID(cache, CACHE_MAGIC)
 
 /*!
  * Control incremental cleaning.
  * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize().
  * See also DNS_CACHE_CLEANERINCREMENT
  */
-#define DNS_CACHE_MINSIZE               2097152 /*%< Bytes.  2097152 = 2 MB */
+#define DNS_CACHE_MINSIZE      2097152 /*%< Bytes.  2097152 = 2 MB */
 /*!
  * Control incremental cleaning.
  * CLEANERINCREMENT is how many nodes are examined in one pass.
  * See also DNS_CACHE_MINSIZE
  */
-#define DNS_CACHE_CLEANERINCREMENT      1000U   /*%< Number of nodes. */
+#define DNS_CACHE_CLEANERINCREMENT     1000U   /*%< Number of nodes. */
 
 /***
- ***    Types
+ ***   Types
  ***/
 
 /*
 typedef struct cache_cleaner cache_cleaner_t;
 
 typedef enum {
-       cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */
-       cleaner_s_busy, /*%< Currently cleaning. */
-       cleaner_s_done  /*%< Freed enough memory after being overmem. */
+       cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */
+       cleaner_s_busy, /*%< Currently cleaning. */
+       cleaner_s_done  /*%< Freed enough memory after being overmem. */
 } cleaner_state_t;
 
 /*
  * Convenience macros for comprehensive assertion checking.
  */
-#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle)
-#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy)
+#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \
+                        (c)->resched_event != NULL)
+#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \
+                        (c)->iterator != NULL && \
+                        (c)->resched_event == NULL)
 
 /*%
  * Accesses to a cache cleaner object are synchronized through
  * task/event serialization, or locked from the cache object.
  */
 struct cache_cleaner {
-       isc_mutex_t     lock;
+       isc_mutex_t     lock;
        /*%<
-        * Locks overmem.  Note: never allocate memory
+        * Locks overmem_event, overmem.  Note: never allocate memory
         * while holding this lock - that could lead to deadlock since
         * the lock is take by water() which is called from the memory
         * allocator.
         */
 
-       dns_cache_t     *cache;
-       isc_task_t      *task;
-       unsigned int    cleaning_interval; /*% The cleaning-interval from
+       dns_cache_t     *cache;
+       isc_task_t      *task;
+       unsigned int    cleaning_interval; /*% The cleaning-interval from
                                              named.conf, in seconds. */
-       isc_timer_t     *cleaning_timer;
+       isc_timer_t     *cleaning_timer;
+       isc_event_t     *resched_event; /*% Sent by cleaner task to
+                                          itself to reschedule */
+       isc_event_t     *overmem_event;
 
-       unsigned int     increment;     /*% Number of names to
+       dns_dbiterator_t *iterator;
+       unsigned int    increment;      /*% Number of names to
                                           clean in one increment */
-       cleaner_state_t  state;         /*% Idle/Busy. */
-       isc_boolean_t    overmem;       /*% The cache is in an overmem state. */
+       cleaner_state_t state;          /*% Idle/Busy. */
+       isc_boolean_t   overmem;        /*% The cache is in an overmem state. */
+       isc_boolean_t    replaceiterator;
 };
 
 /*%
@@ -109,34 +118,28 @@ struct cache_cleaner {
 
 struct dns_cache {
        /* Unlocked. */
-       unsigned int            magic;
-       isc_mutex_t             lock;
-       isc_mutex_t             filelock;
-       isc_mem_t               *mctx;
+       unsigned int            magic;
+       isc_mutex_t             lock;
+       isc_mutex_t             filelock;
+       isc_mem_t               *mctx;
 
        /* Locked by 'lock'. */
-       int                     references;
-       int                     live_tasks;
-       dns_rdataclass_t        rdclass;
-       dns_db_t                *db;
-       cache_cleaner_t         cleaner;
-       char                    *db_type;
-       int                     db_argc;
-       char                    **db_argv;
+       int                     references;
+       int                     live_tasks;
+       dns_rdataclass_t        rdclass;
+       dns_db_t                *db;
+       cache_cleaner_t         cleaner;
+       char                    *db_type;
+       int                     db_argc;
+       char                    **db_argv;
 
        /* Locked by 'filelock'. */
-       char *                  filename;
+       char                    *filename;
        /* Access to the on-disk cache file is also locked by 'filelock'. */
-
-#ifdef LRU_DEBUG
-#define DUMP_INTERVAL 30        /* seconds */
-       isc_timer_t                    *dump_timer; /* for test */
-       isc_time_t                      dump_time; /* for test */
-#endif
 };
 
 /***
- ***    Functions
+ ***   Functions
  ***/
 
 static isc_result_t
@@ -147,88 +150,13 @@ static void
 cleaning_timer_action(isc_task_t *task, isc_event_t *event);
 
 static void
-cleaner_shutdown_action(isc_task_t *task, isc_event_t *event);
+incremental_cleaning_action(isc_task_t *task, isc_event_t *event);
 
-#ifdef LRU_DEBUG
 static void
-timer_dump(isc_task_t *task, isc_event_t *event);
-#endif
+cleaner_shutdown_action(isc_task_t *task, isc_event_t *event);
 
-#if 0 /* This is no longer needed.  When LRU_TEST is cleaned up,
-       * this should be as well.  XXXMLG */
-/*%
- * Work out how many nodes can be cleaned in the time between two
- * requests to the nameserver.  Smooth the resulting number and use
- * it as a estimate for the number of nodes to be cleaned in the next
- * iteration.
- */
 static void
-adjust_increment(cache_cleaner_t *cleaner, unsigned int remaining,
-                isc_time_t *start)
-{
-       isc_time_t end;
-       isc_uint64_t usecs;
-       isc_uint64_t new;
-       unsigned int pps = dns_pps;
-       unsigned int interval;
-       unsigned int names;
-
-       /*
-        * Tune for minumum of 100 packets per second (pps).
-        */
-       if (pps < 100)
-               pps = 100;
-
-       isc_time_now(&end);
-
-       interval = 1000000 / pps; /* Interval between packets in usecs. */
-       if (interval == 0)
-               interval = 1;
-
-       INSIST(cleaner->increment >= remaining);
-       names = cleaner->increment - remaining;
-       usecs = isc_time_microdiff(&end, start);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
-                     ISC_LOG_DEBUG(1), "adjust_increment interval=%u "
-                     "names=%u usec=%" ISC_PLATFORM_QUADFORMAT "u",
-                     interval, names, usecs);
-
-       if (usecs == 0) {
-               /*
-                * If we cleaned all the nodes in unmeasurable time
-                * double the number of nodes to be cleaned next time.
-                */
-               if (names == cleaner->increment) {
-                       cleaner->increment *= 2;
-                       if (cleaner->increment > DNS_CACHE_CLEANERINCREMENT)
-                               cleaner->increment = DNS_CACHE_CLEANERINCREMENT;
-                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                                     DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
-                                     "%p:new cleaner->increment = %u\n",
-                                     cleaner, cleaner->increment);
-               }
-               return;
-       }
-
-       new = (names * interval);
-       new /= (usecs * 2);
-       if (new == 0)
-               new = 1;
-
-       /* Smooth */
-       new = (new + cleaner->increment * 7) / 8;
-
-       if (new > DNS_CACHE_CLEANERINCREMENT)
-               new = DNS_CACHE_CLEANERINCREMENT;
-
-       cleaner->increment = (unsigned int)new;
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
-                     ISC_LOG_DEBUG(1), "%p:new cleaner->increment = %u\n",
-                     cleaner, cleaner->increment);
-}
-#endif
+overmem_cleaning_action(isc_task_t *task, isc_event_t *event);
 
 static inline isc_result_t
 cache_create_db(dns_cache_t *cache, dns_db_t **db) {
@@ -306,7 +234,16 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
 
        cache->magic = CACHE_MAGIC;
 
-       result = cache_cleaner_init(cache, taskmgr, timermgr, &cache->cleaner);
+       /*
+        * RBT-type cache DB has its own mechanism of cache cleaning and doesn't
+        * need the control of the generic cleaner.
+        */
+       if (strcmp(db_type, "rbt") == 0)
+               result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner);
+       else {
+               result = cache_cleaner_init(cache, taskmgr, timermgr,
+                                           &cache->cleaner);
+       }
        if (result != ISC_R_SUCCESS)
                goto cleanup_db;
 
@@ -347,6 +284,15 @@ cache_free(dns_cache_t *cache) {
        if (cache->cleaner.task != NULL)
                isc_task_detach(&cache->cleaner.task);
 
+       if (cache->cleaner.overmem_event != NULL)
+               isc_event_free(&cache->cleaner.overmem_event);
+
+       if (cache->cleaner.resched_event != NULL)
+               isc_event_free(&cache->cleaner.resched_event);
+
+       if (cache->cleaner.iterator != NULL)
+               dns_dbiterator_destroy(&cache->cleaner.iterator);
+
        DESTROYLOCK(&cache->cleaner.lock);
 
        if (cache->filename) {
@@ -548,9 +494,6 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
                   isc_timermgr_t *timermgr, cache_cleaner_t *cleaner)
 {
        isc_result_t result;
-#ifdef LRU_DEBUG
-       isc_interval_t interval;
-#endif
 
        result = isc_mutex_init(&cleaner->lock);
        if (result != ISC_R_SUCCESS)
@@ -559,10 +502,19 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
        cleaner->increment = DNS_CACHE_CLEANERINCREMENT;
        cleaner->state = cleaner_s_idle;
        cleaner->cache = cache;
+       cleaner->iterator = NULL;
        cleaner->overmem = ISC_FALSE;
+       cleaner->replaceiterator = ISC_FALSE;
 
        cleaner->task = NULL;
        cleaner->cleaning_timer = NULL;
+       cleaner->resched_event = NULL;
+       cleaner->overmem_event = NULL;
+
+       result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE,
+                                      &cleaner->iterator);
+       if (result != ISC_R_SUCCESS)
+               goto cleanup;
 
        if (taskmgr != NULL && timermgr != NULL) {
                result = isc_task_create(taskmgr, 1, &cleaner->task);
@@ -588,8 +540,7 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
 
                cleaner->cleaning_interval = 0; /* Initially turned off. */
                result = isc_timer_create(timermgr, isc_timertype_inactive,
-                                          NULL, NULL,
-                                          cleaner->task,
+                                          NULL, NULL, cleaner->task,
                                           cleaning_timer_action, cleaner,
                                           &cleaner->cleaning_timer);
                if (result != ISC_R_SUCCESS) {
@@ -600,33 +551,122 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
                        goto cleanup;
                }
 
-#ifdef LRU_DEBUG
-               interval.seconds = DUMP_INTERVAL;
-               interval.nanoseconds = 0;
-               RUNTIME_CHECK(isc_time_nowplusinterval(&cache->dump_time,
-                                                      &interval) ==
-                             ISC_R_SUCCESS);
-               cache->dump_timer = NULL;
-               result = isc_timer_create(timermgr, isc_timertype_once,
-                                         &cache->dump_time, NULL,
-                                         cleaner->task, timer_dump,
-                                         cache, &cache->dump_timer);
-               RUNTIME_CHECK(result == ISC_R_SUCCESS); /* for brevity */
-#endif
+               cleaner->resched_event =
+                       isc_event_allocate(cache->mctx, cleaner,
+                                          DNS_EVENT_CACHECLEAN,
+                                          incremental_cleaning_action,
+                                          cleaner, sizeof(isc_event_t));
+               if (cleaner->resched_event == NULL) {
+                       result = ISC_R_NOMEMORY;
+                       goto cleanup;
+               }
+
+               cleaner->overmem_event =
+                       isc_event_allocate(cache->mctx, cleaner,
+                                          DNS_EVENT_CACHEOVERMEM,
+                                          overmem_cleaning_action,
+                                          cleaner, sizeof(isc_event_t));
+               if (cleaner->overmem_event == NULL) {
+                       result = ISC_R_NOMEMORY;
+                       goto cleanup;
+               }
        }
 
        return (ISC_R_SUCCESS);
 
  cleanup:
+       if (cleaner->overmem_event != NULL)
+               isc_event_free(&cleaner->overmem_event);
+       if (cleaner->resched_event != NULL)
+               isc_event_free(&cleaner->resched_event);
        if (cleaner->cleaning_timer != NULL)
                isc_timer_detach(&cleaner->cleaning_timer);
        if (cleaner->task != NULL)
                isc_task_detach(&cleaner->task);
+       if (cleaner->iterator != NULL)
+               dns_dbiterator_destroy(&cleaner->iterator);
        DESTROYLOCK(&cleaner->lock);
  fail:
        return (result);
 }
 
+static void
+begin_cleaning(cache_cleaner_t *cleaner) {
+       isc_result_t result = ISC_R_SUCCESS;
+
+       REQUIRE(CLEANER_IDLE(cleaner));
+
+       /*
+        * Create an iterator, if it does not already exist, and
+        * position it at the beginning of the cache.
+        */
+       if (cleaner->iterator == NULL)
+               result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE,
+                                              &cleaner->iterator);
+       if (result != ISC_R_SUCCESS)
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                             DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
+                             "cache cleaner could not create "
+                             "iterator: %s", isc_result_totext(result));
+       else {
+               dns_dbiterator_setcleanmode(cleaner->iterator, ISC_TRUE);
+               result = dns_dbiterator_first(cleaner->iterator);
+       }
+       if (result != ISC_R_SUCCESS) {
+               /*
+                * If the result is ISC_R_NOMORE, the database is empty,
+                * so there is nothing to be cleaned.
+                */
+               if (result != ISC_R_NOMORE && cleaner->iterator != NULL) {
+                       UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                        "cache cleaner: "
+                                        "dns_dbiterator_first() failed: %s",
+                                        dns_result_totext(result));
+                       dns_dbiterator_destroy(&cleaner->iterator);
+               } else if (cleaner->iterator != NULL) {
+                       result = dns_dbiterator_pause(cleaner->iterator);
+                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+               }
+       } else {
+               /*
+                * Pause the iterator to free its lock.
+                */
+               result = dns_dbiterator_pause(cleaner->iterator);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                             DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
+                             "begin cache cleaning, mem inuse %lu",
+                           (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
+               cleaner->state = cleaner_s_busy;
+               isc_task_send(cleaner->task, &cleaner->resched_event);
+       }
+
+       return;
+}
+
+static void
+end_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) {
+       isc_result_t result;
+
+       REQUIRE(CLEANER_BUSY(cleaner));
+       REQUIRE(event != NULL);
+
+       result = dns_dbiterator_pause(cleaner->iterator);
+       if (result != ISC_R_SUCCESS)
+               dns_dbiterator_destroy(&cleaner->iterator);
+
+       dns_cache_setcleaninginterval(cleaner->cache,
+                                     cleaner->cleaning_interval);
+
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
+                     ISC_LOG_DEBUG(1), "end cache cleaning, mem inuse %lu",
+                     (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
+
+       cleaner->state = cleaner_s_idle;
+       cleaner->resched_event = event;
+}
+
 /*
  * This is run once for every cache-cleaning-interval as defined in named.conf.
  */
@@ -643,9 +683,174 @@ cleaning_timer_action(isc_task_t *task, isc_event_t *event) {
                      ISC_LOG_DEBUG(1), "cache cleaning timer fired, "
                      "cleaner state = %d", cleaner->state);
 
+       if (cleaner->state == cleaner_s_idle)
+               begin_cleaning(cleaner);
+
        isc_event_free(&event);
 }
 
+/*
+ * This is called when the cache either surpasses its upper limit
+ * or shrinks beyond its lower limit.
+ */
+static void
+overmem_cleaning_action(isc_task_t *task, isc_event_t *event) {
+       cache_cleaner_t *cleaner = event->ev_arg;
+       isc_boolean_t want_cleaning = ISC_FALSE;
+
+       UNUSED(task);
+
+       INSIST(task == cleaner->task);
+       INSIST(event->ev_type == DNS_EVENT_CACHEOVERMEM);
+       INSIST(cleaner->overmem_event == NULL);
+
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
+                     ISC_LOG_DEBUG(1), "overmem_cleaning_action called, "
+                     "overmem = %d, state = %d", cleaner->overmem,
+                     cleaner->state);
+
+       LOCK(&cleaner->lock);
+
+       if (cleaner->overmem) {
+               if (cleaner->state == cleaner_s_idle)
+                       want_cleaning = ISC_TRUE;
+       } else {
+               if (cleaner->state == cleaner_s_busy)
+                       /*
+                        * end_cleaning() can't be called here because
+                        * then both cleaner->overmem_event and
+                        * cleaner->resched_event will point to this
+                        * event.  Set the state to done, and then
+                        * when the incremental_cleaning_action() event
+                        * is posted, it will handle the end_cleaning.
+                        */
+                       cleaner->state = cleaner_s_done;
+       }
+
+       cleaner->overmem_event = event;
+
+       UNLOCK(&cleaner->lock);
+
+       if (want_cleaning)
+               begin_cleaning(cleaner);
+}
+
+/*
+ * Do incremental cleaning.
+ */
+static void
+incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
+       cache_cleaner_t *cleaner = event->ev_arg;
+       isc_result_t result;
+       unsigned int n_names;
+       isc_time_t start;
+
+       UNUSED(task);
+
+       INSIST(task == cleaner->task);
+       INSIST(event->ev_type == DNS_EVENT_CACHECLEAN);
+
+       if (cleaner->state == cleaner_s_done) {
+               cleaner->state = cleaner_s_busy;
+               end_cleaning(cleaner, event);
+               LOCK(&cleaner->cache->lock);
+               LOCK(&cleaner->lock);
+               if (cleaner->replaceiterator) {
+                       dns_dbiterator_destroy(&cleaner->iterator);
+                       (void) dns_db_createiterator(cleaner->cache->db,
+                                                    ISC_FALSE,
+                                                    &cleaner->iterator);
+                       cleaner->replaceiterator = ISC_FALSE;
+               }
+               UNLOCK(&cleaner->lock);
+               UNLOCK(&cleaner->cache->lock);
+               return;
+       }
+
+       INSIST(CLEANER_BUSY(cleaner));
+
+       n_names = cleaner->increment;
+
+       REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator));
+
+       isc_time_now(&start);
+       while (n_names-- > 0) {
+               dns_dbnode_t *node = NULL;
+
+               result = dns_dbiterator_current(cleaner->iterator, &node,
+                                               NULL);
+               if (result != ISC_R_SUCCESS) {
+                       UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                "cache cleaner: dns_dbiterator_current() "
+                                "failed: %s", dns_result_totext(result));
+
+                       end_cleaning(cleaner, event);
+                       return;
+               }
+
+               /*
+                * The node was not needed, but was required by
+                * dns_dbiterator_current().  Give up its reference.
+                */
+               dns_db_detachnode(cleaner->cache->db, &node);
+
+               /*
+                * Step to the next node.
+                */
+               result = dns_dbiterator_next(cleaner->iterator);
+
+               if (result != ISC_R_SUCCESS) {
+                       /*
+                        * Either the end was reached (ISC_R_NOMORE) or
+                        * some error was signaled.  If the cache is still
+                        * overmem and no error was encountered,
+                        * keep trying to clean it, otherwise stop cleaning.
+                        */
+                       if (result != ISC_R_NOMORE)
+                               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                                "cache cleaner: "
+                                                "dns_dbiterator_next() "
+                                                "failed: %s",
+                                                dns_result_totext(result));
+                       else if (cleaner->overmem) {
+                               result = dns_dbiterator_first(cleaner->
+                                                             iterator);
+                               if (result == ISC_R_SUCCESS) {
+                                       isc_log_write(dns_lctx,
+                                                     DNS_LOGCATEGORY_DATABASE,
+                                                     DNS_LOGMODULE_CACHE,
+                                                     ISC_LOG_DEBUG(1),
+                                                     "cache cleaner: "
+                                                     "still overmem, "
+                                                     "reset and try again");
+                                       continue;
+                               }
+                       }
+
+                       end_cleaning(cleaner, event);
+                       return;
+               }
+       }
+
+       /*
+        * We have successfully performed a cleaning increment but have
+        * not gone through the entire cache.  Free the iterator locks
+        * and reschedule another batch.  If it fails, just try to continue
+        * anyway.
+        */
+       result = dns_dbiterator_pause(cleaner->iterator);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
+                     ISC_LOG_DEBUG(1), "cache cleaner: checked %u nodes, "
+                     "mem inuse %lu, sleeping", cleaner->increment,
+                     (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
+
+       isc_task_send(task, &event);
+       INSIST(CLEANER_BUSY(cleaner));
+       return;
+}
+
 /*
  * Do immediate cleaning.
  */
@@ -714,6 +919,10 @@ water(void *arg, int mark) {
                isc_mem_waterack(cache->mctx, mark);
        }
 
+       if (cache->cleaner.overmem_event != NULL)
+               isc_task_send(cache->cleaner.task,
+                             &cache->cleaner.overmem_event);
+
        UNLOCK(&cache->cleaner.lock);
 }
 
@@ -731,8 +940,8 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {
        if (size != 0 && size < DNS_CACHE_MINSIZE)
                size = DNS_CACHE_MINSIZE;
 
-       hiwater = size - (size >> 3);   /* Approximately 7/8ths. */
-       lowater = size - (size >> 2);   /* Approximately 3/4ths. */
+       hiwater = size - (size >> 3);   /* Approximately 7/8ths. */
+       lowater = size - (size >> 2);   /* Approximately 3/4ths. */
 
        /*
         * If the cache was overmem and cleaning, but now with the new limits
@@ -767,6 +976,11 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
        INSIST(task == cache->cleaner.task);
        INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
 
+       if (CLEANER_BUSY(&cache->cleaner))
+               end_cleaning(&cache->cleaner, event);
+       else
+               isc_event_free(&event);
+
        LOCK(&cache->lock);
 
        cache->live_tasks--;
@@ -783,10 +997,6 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
        if (cache->cleaner.cleaning_timer != NULL)
                isc_timer_detach(&cache->cleaner.cleaning_timer);
 
-#ifdef LRU_DEBUG
-       isc_timer_detach(&cache->dump_timer);
-#endif
-
        /* Make sure we don't reschedule anymore. */
        (void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL);
 
@@ -794,8 +1004,6 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
 
        if (should_free)
                cache_free(cache);
-
-       isc_event_free(&event);
 }
 
 isc_result_t
@@ -810,9 +1018,14 @@ dns_cache_flush(dns_cache_t *cache) {
        LOCK(&cache->lock);
        LOCK(&cache->cleaner.lock);
        if (cache->cleaner.state == cleaner_s_idle) {
-               /* XXXMLG do something */
-       } else if (cache->cleaner.state == cleaner_s_busy) {
-               /* XXXMLG do something else */
+               if (cache->cleaner.iterator != NULL)
+                       dns_dbiterator_destroy(&cache->cleaner.iterator);
+               (void) dns_db_createiterator(db, ISC_FALSE,
+                                            &cache->cleaner.iterator);
+       } else {
+               if (cache->cleaner.state == cleaner_s_busy)
+                       cache->cleaner.state = cleaner_s_done;
+               cache->cleaner.replaceiterator = ISC_TRUE;
        }
        dns_db_detach(&cache->db);
        cache->db = db;
@@ -874,33 +1087,3 @@ dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) {
        dns_db_detach(&db);
        return (result);
 }
-
-#ifdef LRU_DEBUG
-static void
-timer_dump(isc_task_t *task, isc_event_t *event) {
-       dns_cache_t *cache;
-       isc_interval_t interval;
-       isc_time_t nexttime;
-
-       UNUSED(task);
-
-       cache = event->ev_arg;
-       INSIST(VALID_CACHE(cache));
-
-#ifdef LRU_DEBUG
-       /* XXX: abuse existing overmem method */
-       dns_db_overmem(cache->db, (isc_boolean_t)-1);
-#endif
-
-       interval.seconds = DUMP_INTERVAL;
-       interval.nanoseconds = 0;
-
-       RUNTIME_CHECK(isc_time_add(&cache->dump_time, &interval, &nexttime) ==
-                     ISC_R_SUCCESS); /* XXX: this is not always true */
-       cache->dump_time = nexttime;
-       (void)isc_timer_reset(cache->dump_timer, isc_timertype_once,
-                             &cache->dump_time, NULL, ISC_FALSE);
-
-       isc_event_free(&event);
-}
-#endif
index f6196142c7c3972ed7c9aaddd1f4d0d5621365ca..d2d3630f2de56df08ddf2ba6f77a50b090971f64 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.248.12.7 2008/04/23 21:43:58 each Exp $ */
+/* $Id: rbtdb.c,v 1.248.12.8 2008/05/01 18:32:31 jinmei Exp $ */
 
 /*! \file */
 
@@ -270,8 +270,6 @@ typedef ISC_LIST(dns_rbtnode_t)         rbtnodelist_t;
 #define RDATASET_ATTR_NXDOMAIN          0x0010
 #define RDATASET_ATTR_RESIGN            0x0020
 #define RDATASET_ATTR_STATCOUNT         0x0040
-#define RDATASET_ATTR_CACHE             0x1000 /* for debug */
-#define RDATASET_ATTR_CANCELED          0x2000 /* for debug */
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -344,33 +342,6 @@ typedef struct rbtdb_version {
 
 typedef ISC_LIST(rbtdb_version_t)       rbtdb_versionlist_t;
 
-#ifdef LRU_DEBUG
-/* statistics info for testing */
-struct cachestat {
-       unsigned int    cache_total;
-       int             cache_current;
-       unsigned int    ncache_total;
-       int             ncache_current;
-       unsigned int    a_total;
-       int             a_current;
-       unsigned int    aaaa_total;
-       int             aaaa_current;
-       unsigned int    ns_total;
-       int             ns_current;
-       unsigned int    ptr_total;
-       int             ptr_current;
-       unsigned int    glue_total;
-       int             glue_current;
-       unsigned int    additional_total;
-       int             additional_current;
-
-       unsigned int    stale_purge;
-       unsigned int    stale_scan;
-       unsigned int    stale_expire;
-       unsigned int    stale_lru;
-};
-#endif
-
 typedef struct {
        /* Unlocked. */
        dns_db_t                        common;
@@ -423,9 +394,6 @@ typedef struct {
 
        /* Unlocked */
        unsigned int                    quantum;
-#ifdef LRU_DEBUG
-       struct cachestat                cachestat;
-#endif
 } dns_rbtdb_t;
 
 #define RBTDB_ATTR_LOADED               0x01
@@ -893,41 +861,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
        if (rbtdb->task != NULL)
                isc_task_detach(&rbtdb->task);
 
-#ifdef LRU_DEBUG
-       /* Experimental logging about memory usage */
-       if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) {
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_CACHE, ISC_LOG_INFO,
-                             "cache DB %p: mem inuse %lu, XXX node, "
-                             "%d/%u current/total cache, %d/%u neg, %d/%u A, %d/%u AAAA, "
-                             "%d/%u NS, %d/%u PTR, %d/%u glue, "
-                             "%d/%u  additional, purge/scan=%u(%u expiry, %u lru)/%u, "
-                             "overmem=%d",
-                             rbtdb,
-                             (unsigned long)isc_mem_inuse(rbtdb->common.mctx),
-                             rbtdb->cachestat.cache_current, rbtdb->cachestat.cache_total,
-                             rbtdb->cachestat.ncache_current, rbtdb->cachestat.ncache_total,
-                             rbtdb->cachestat.a_current, rbtdb->cachestat.a_total,
-                             rbtdb->cachestat.aaaa_current, rbtdb->cachestat.aaaa_total,
-                             rbtdb->cachestat.ns_current, rbtdb->cachestat.ns_total,
-                             rbtdb->cachestat.ptr_current, rbtdb->cachestat.ptr_total,
-                             rbtdb->cachestat.glue_current, rbtdb->cachestat.glue_total,
-                             rbtdb->cachestat.additional_current,
-                             rbtdb->cachestat.additional_total,
-                             rbtdb->cachestat.stale_purge, rbtdb->cachestat.stale_expire,
-                             rbtdb->cachestat.stale_lru, rbtdb->cachestat.stale_scan,
-                             rbtdb->overmem);
-               INSIST(rbtdb->cachestat.cache_current == 0);
-               INSIST(rbtdb->cachestat.ncache_current == 0);
-               INSIST(rbtdb->cachestat.a_current == 0);
-               INSIST(rbtdb->cachestat.aaaa_current == 0);
-               INSIST(rbtdb->cachestat.ns_current == 0);
-               INSIST(rbtdb->cachestat.ptr_current == 0);
-               INSIST(rbtdb->cachestat.glue_current == 0);
-               INSIST(rbtdb->cachestat.additional_current == 0);
-       }
-#endif
-
        RBTDB_DESTROYLOCK(&rbtdb->lock);
        rbtdb->common.magic = 0;
        rbtdb->common.impmagic = 0;
@@ -1200,69 +1133,6 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
                update_rrsetstats(rbtdb, rdataset, ISC_FALSE);
        }
 
-#ifdef LRU_DEBUG
-       /*
-        * for debug: statistics update.
-        * Nothing in this block should have any side-effects.
-        */
-       if (EXISTS(rdataset) &&
-           (rdataset->attributes & RDATASET_ATTR_CACHE) != 0) {
-               rbtdb->cachestat.cache_current--;
-               if ((rdataset->attributes & RDATASET_ATTR_CANCELED) != 0)
-                       rbtdb->cachestat.cache_total--;
-               if (RBTDB_RDATATYPE_BASE(rdataset->type) == 0) {
-                       rbtdb->cachestat.ncache_current--;
-                       INSIST(rbtdb->cachestat.ncache_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.ncache_total--;
-               }
-               if (rdataset->type == dns_rdatatype_a) {
-                       rbtdb->cachestat.a_current--;
-                       INSIST(rbtdb->cachestat.a_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.a_total--;
-               } else if (rdataset->type == dns_rdatatype_aaaa) {
-                       rbtdb->cachestat.aaaa_current--;
-                       INSIST(rbtdb->cachestat.aaaa_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.aaaa_total--;
-               } else if (rdataset->type == dns_rdatatype_ptr) {
-                       rbtdb->cachestat.ptr_current--;
-                       INSIST(rbtdb->cachestat.ptr_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.ptr_total--;
-               } else if (rdataset->type == dns_rdatatype_ns) {
-                       rbtdb->cachestat.ns_current--;
-                       INSIST(rbtdb->cachestat.ns_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.ns_total--;
-               }
-               if (rdataset->trust == dns_trust_glue &&
-                   (rdataset->type == dns_rdatatype_a ||
-                    rdataset->type == dns_rdatatype_aaaa)) {
-                       rbtdb->cachestat.glue_current--;
-                       INSIST(rbtdb->cachestat.glue_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.glue_total--;
-               }
-               if (rdataset->trust == dns_trust_additional &&
-                   (rdataset->type == dns_rdatatype_a ||
-                    rdataset->type == dns_rdatatype_aaaa)) {
-                       rbtdb->cachestat.additional_current--;
-                       INSIST(rbtdb->cachestat.additional_current >= 0);
-                       if ((rdataset->attributes & RDATASET_ATTR_CANCELED)
-                           != 0)
-                               rbtdb->cachestat.additional_total--;
-               }
-       }
-#endif
-
        if (IS_CACHE(rbtdb) && ISC_LINK_LINKED(rdataset, lru_link)) {
                int idx = rdataset->node->locknum;
                ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link);
@@ -3031,8 +2901,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                    (search.options & DNS_DBFIND_FORCENSEC) != 0)
                {
                        result = find_closest_nsec(&search, nodep, foundname,
-                                                 rdataset, sigrdataset,
-                                                 search.rbtdb->secure);
+                                                  rdataset, sigrdataset,
+                                                  search.rbtdb->secure);
                        if (result == ISC_R_SUCCESS)
                                result = active ? DNS_R_EMPTYNAME :
                                                  DNS_R_NXDOMAIN;
@@ -4515,40 +4385,8 @@ static void
 overmem(dns_db_t *db, isc_boolean_t overmem) {
        dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
 
-#ifdef LRU_DEBUG
-       /* XXX: see cache.c:timer_dump() */
-       if ((int)overmem == -1) {
-               if (!IS_CACHE(rbtdb) || db->rdclass != dns_rdataclass_in)
-                       return; /* for brevity */
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_CACHE, ISC_LOG_INFO,
-                             "cache DB %p: mem inuse %lu, %u node, "
-                             "%d/%u current/total cache, %d/%u neg, %d/%u A, %d/%u AAAA, "
-                             "%d/%u NS, %d/%u PTR, %d/%u glue, "
-                             "%d/%u  additional, purge/scan=%u(%u expiry, %u lru)/%u, "
-                             "overmem=%d",
-                             rbtdb,
-                             (unsigned long)isc_mem_inuse(rbtdb->common.mctx),
-                             dns_rbt_nodecount(rbtdb->tree),
-                             rbtdb->cachestat.cache_current, rbtdb->cachestat.cache_total,
-                             rbtdb->cachestat.ncache_current, rbtdb->cachestat.ncache_total,
-                             rbtdb->cachestat.a_current, rbtdb->cachestat.a_total,
-                             rbtdb->cachestat.aaaa_current, rbtdb->cachestat.aaaa_total,
-                             rbtdb->cachestat.ns_current, rbtdb->cachestat.ns_total,
-                             rbtdb->cachestat.ptr_current, rbtdb->cachestat.ptr_total,
-                             rbtdb->cachestat.glue_current, rbtdb->cachestat.glue_total,
-                             rbtdb->cachestat.additional_current,
-                             rbtdb->cachestat.additional_total,
-                             rbtdb->cachestat.stale_purge, rbtdb->cachestat.stale_expire,
-                             rbtdb->cachestat.stale_lru, rbtdb->cachestat.stale_scan,
-                             rbtdb->overmem);
-               return;
-       }
-#endif
-
-       if (IS_CACHE(rbtdb)) {
+       if (IS_CACHE(rbtdb))
                rbtdb->overmem = overmem;
-       }
 }
 
 static void
@@ -4943,38 +4781,6 @@ cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) {
        return (ISC_FALSE);
 }
 
-#ifdef LRU_DEBUG
-static void
-cachestat_update(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) {
-       if ((header->attributes & RDATASET_ATTR_CACHE) == 0)
-               return;
-
-       /* XXX: don't use lock for brevity */
-       rbtdb->cachestat.cache_total++;
-       if (RBTDB_RDATATYPE_BASE(header->type) == 0)
-                       rbtdb->cachestat.ncache_total++;
-       if (header->type == dns_rdatatype_a)
-                       rbtdb->cachestat.a_total++;
-       else if (header->type == dns_rdatatype_aaaa)
-               rbtdb->cachestat.aaaa_total++;
-       else if (header->type == dns_rdatatype_ns)
-               rbtdb->cachestat.ns_total++;
-       else if (header->type == dns_rdatatype_ptr)
-               rbtdb->cachestat.ptr_total++;
-
-       if (header->trust == dns_trust_glue &&
-           (header->type == dns_rdatatype_a ||
-            header->type == dns_rdatatype_aaaa)) {
-               rbtdb->cachestat.glue_total++;
-       }
-       if (header->trust == dns_trust_additional &&
-           (header->type == dns_rdatatype_a ||
-            header->type == dns_rdatatype_aaaa)) {
-               rbtdb->cachestat.additional_total++;
-       }
-}
-#endif
-
 static isc_result_t
 add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
     rdatasetheader_t *newheader, unsigned int options, isc_boolean_t loading,
@@ -5079,9 +4885,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                         * The NXDOMAIN/NODATA(QTYPE=ANY)
                                         * is more trusted.
                                         */
-                                       /* set the flag for debug */
-                                       newheader->attributes |=
-                                               RDATASET_ATTR_CANCELED;
                                        free_rdataset(rbtdb,
                                                      rbtdb->common.mctx,
                                                      newheader);
@@ -5140,7 +4943,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                 */
                if (rbtversion == NULL && trust < header->trust &&
                    (header->rdh_ttl > now || header_nx)) {
-                       newheader->attributes |= RDATASET_ATTR_CANCELED;
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
@@ -5225,7 +5027,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                header->noqname = newheader->noqname;
                                newheader->noqname = NULL;
                        }
-                       newheader->attributes |= RDATASET_ATTR_CANCELED;
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
@@ -5251,7 +5052,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                header->noqname = newheader->noqname;
                                newheader->noqname = NULL;
                        }
-                       newheader->attributes |= RDATASET_ATTR_CANCELED;
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
@@ -5299,9 +5099,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                 */
                                isc_heap_insert(rbtdb->heaps[idx], newheader);
                        }
-#ifdef LRU_DEBUG
-                       cachestat_update(rbtdb, newheader);
-#endif
                }
        } else {
                /*
@@ -5353,9 +5150,6 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                         newheader, lru_link);
                        isc_heap_insert(rbtdb->heaps[idx], newheader);
                }
-#ifdef LRU_DEBUG
-               cachestat_update(rbtdb, newheader);
-#endif
        }
 
        /*
@@ -5523,45 +5317,6 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                update_rrsetstats(rbtdb, newheader, ISC_TRUE);
        }
 
-#ifdef LRU_DEBUG
-       /* for debug: statistics update */
-       if (IS_CACHE(rbtdb) && rdataset->rdclass == dns_rdataclass_in) {
-               /* XXX: don't use lock for brevity */
-               newheader->attributes |= RDATASET_ATTR_CACHE;
-               rbtdb->cachestat.cache_total++;
-               rbtdb->cachestat.cache_current++;
-               if (rdataset->type == 0) {
-                       rbtdb->cachestat.ncache_total++;
-                       rbtdb->cachestat.ncache_current++;
-               }
-               if (rdataset->type == dns_rdatatype_a) {
-                       rbtdb->cachestat.a_total++;
-                       rbtdb->cachestat.a_current++;
-               } else if (rdataset->type == dns_rdatatype_aaaa) {
-                       rbtdb->cachestat.aaaa_total++;
-                       rbtdb->cachestat.aaaa_current++;
-               } else if (rdataset->type == dns_rdatatype_ns) {
-                       rbtdb->cachestat.ns_total++;
-                       rbtdb->cachestat.ns_current++;
-               } else if (rdataset->type == dns_rdatatype_ptr) {
-                       rbtdb->cachestat.ptr_total++;
-                       rbtdb->cachestat.ptr_current++;
-               }
-               if (rdataset->trust == dns_trust_glue &&
-                   (rdataset->type == dns_rdatatype_a ||
-                    rdataset->type == dns_rdatatype_aaaa)) {
-                       rbtdb->cachestat.glue_total++;
-                       rbtdb->cachestat.glue_current++;
-               }
-               if (rdataset->trust == dns_trust_additional &&
-                   (rdataset->type == dns_rdatatype_a ||
-                    rdataset->type == dns_rdatatype_aaaa)) {
-                       rbtdb->cachestat.additional_total++;
-                       rbtdb->cachestat.additional_current++;
-               }
-       }
-#endif
-
        if (IS_CACHE(rbtdb)) {
                if (tree_locked)
                        cleanup_dead_nodes(rbtdb, rbtnode->locknum);
@@ -7628,7 +7383,6 @@ check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
 {
        rdatasetheader_t *victim;
        isc_boolean_t overmem = rbtdb->overmem;
-       int scans = 0;          /* for debug */
        int victims = 0;
 
        /*
@@ -7637,11 +7391,6 @@ check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
        victim = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
        if (victim != NULL && victim->rdh_ttl <= now - RBTDB_VIRTUAL) {
                INSIST(victim->node->locknum == rbtnode->locknum);
-
-#ifdef LRU_DEBUG
-               /* for debug */
-               rbtdb->cachestat.stale_expire++;
-#endif
                victims++;
 
                set_ttl(rbtdb, victim, 0);
@@ -7670,13 +7419,7 @@ check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
        victim = ISC_LIST_TAIL(rbtdb->rdatasets[rbtnode->locknum]);
        if (victim != NULL && overmem) {
                INSIST(victim->node->locknum == rbtnode->locknum);
-
-#ifdef LRU_DEBUG
-               /* for debug */
-               rbtdb->cachestat.stale_lru++;
-#endif
                victims++;
-               scans++;
 
                set_ttl(rbtdb, victim, 0);
                victim->attributes |= RDATASET_ATTR_STALE;
@@ -7697,10 +7440,4 @@ check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
                                            isc_rwlocktype_none);
                }
        }
-
-#ifdef LRU_DEBUG
-       /* update statistics for debug (no lock for brevity) */
-       rbtdb->cachestat.stale_scan += scans;
-       rbtdb->cachestat.stale_purge += victims;
-#endif
 }
index c5f061451686bdfa063ca56b835c402ac3729466..30a6894d4943170d0bd6e2f8f3c48b45d6ebebf8 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.355.12.13 2008/04/10 07:20:27 marka Exp $ */
+/* $Id: resolver.c,v 1.355.12.14 2008/05/01 18:32:32 jinmei Exp $ */
 
 /*! \file */
 
@@ -353,11 +353,7 @@ struct dns_resolver {
        isc_timer_t *                   spillattimer;
        isc_boolean_t                   zero_no_soa_ttl;
        isc_timer_t *                   disppooltimer;
-#ifdef LRU_DEBUG
-#define DUMP_INTERVAL 30        /* seconds */
-       isc_timer_t *                   dumptimer;
-       isc_time_t                      dump_time;
-#endif
+
        /* Locked by lock. */
        unsigned int                    references;
        isc_boolean_t                   exiting;
@@ -373,15 +369,6 @@ struct dns_resolver {
        /* Locked by poollock. */
        dns_dispatch_t **               dispatchv4pool;
        dns_dispatch_t **               dispatchv6pool;
-
-#ifdef LRU_DEBUG
-       /* Unlocked: just for debug */
-       unsigned int                    extqueries;
-       unsigned int                    extqueries_ns;
-       unsigned int                    extqueries_soa;
-       unsigned int                    extqueries_a;
-       unsigned int                    extqueries_aaaa;
-#endif
 };
 
 #define RES_MAGIC                      ISC_MAGIC('R', 'e', 's', '!')
@@ -416,10 +403,6 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
 static void validated(isc_task_t *task, isc_event_t *event);
 static void maybe_destroy(fetchctx_t *fctx);
 
-#ifdef LRU_DEBUG
-static void timer_dump(isc_task_t *task, isc_event_t *ev);
-#endif
-
 /*%
  * Increment resolver-related statistics counters.
  */
@@ -1706,23 +1689,6 @@ resquery_send(resquery_t *query) {
        if (result != ISC_R_SUCCESS)
                goto cleanup_message;
 
-#ifdef LRU_DEBUG
-       res->extqueries++;
-       switch (fctx->type) {
-       case dns_rdatatype_ns:
-               res->extqueries_ns++;
-               break;
-       case dns_rdatatype_soa:
-               res->extqueries_soa++;
-               break;
-       case dns_rdatatype_a:
-               res->extqueries_a++;
-               break;
-       case dns_rdatatype_aaaa:
-               res->extqueries_aaaa++;
-               break;
-       }
-#endif
        query->sends++;
 
        QTRACE("sent");
@@ -6291,16 +6257,6 @@ destroy(dns_resolver_t *res) {
 
        INSIST(res->nfctx == 0);
 
-#ifdef LRU_DEBUG
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
-                     DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
-                     "destroying resolver %p: external queries "
-                     "total/NS/SOA/A/AAAA=%u/%u/%u/%u/%u",
-                     res, res->extqueries, res->extqueries_ns,
-                     res->extqueries_soa, res->extqueries_a,
-                     res->extqueries_aaaa);
-#endif
-
        RES_DESTROYLOCK(&res->poollock);
        DESTROYLOCK(&res->primelock);
        DESTROYLOCK(&res->nlock);
@@ -6338,10 +6294,6 @@ destroy(dns_resolver_t *res) {
        }
        if (res->disppooltimer != NULL)
                isc_timer_detach(&res->disppooltimer);
-#ifdef LRU_DEBUG
-       if (res->dumptimer != NULL)
-               isc_timer_detach(&res->dumptimer);
-#endif
        dns_resolver_reset_algorithms(res);
        dns_resolver_resetmustbesecure(res);
 #if USE_ALGLOCK
@@ -6475,15 +6427,6 @@ dns_resolver_create(dns_view_t *view,
        res->dispatchv4pool = NULL;
        res->dispatchv6pool = NULL;
        res->disppooltimer = NULL;
-#ifdef LRU_DEBUG
-       res->dumptimer = NULL;
-       res->extqueries = 0;
-       res->extqueries_ns = 0;
-       res->extqueries_soa = 0;
-       res->extqueries_a = 0;
-       res->extqueries_aaaa = 0;
-#endif
-
        res->nbuckets = ntasks;
        res->activebuckets = ntasks;
        res->buckets = isc_mem_get(view->mctx,
@@ -6566,22 +6509,6 @@ dns_resolver_create(dns_view_t *view,
        result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
                                  task, spillattimer_countdown, res,
                                  &res->spillattimer);
-
-#ifdef LRU_DEBUG
-       {
-               isc_interval_t interval;
-
-               interval.seconds = DUMP_INTERVAL;
-               interval.nanoseconds = 0;
-               RUNTIME_CHECK(isc_time_nowplusinterval(&res->dump_time,
-                                                      &interval) ==
-                             ISC_R_SUCCESS);
-
-               result = isc_timer_create(timermgr, isc_timertype_once,
-                                         &res->dump_time, NULL, task,
-                                         timer_dump, res, &res->dumptimer);
-       }
-#endif
        isc_task_detach(&task);
        if (result != ISC_R_SUCCESS)
                goto cleanup_poollock;
@@ -7769,38 +7696,3 @@ dns_resolver_createdispatchpool(dns_resolver_t *res, unsigned int ndisps,
 
        return (result);
 }
-
-#ifdef LRU_DEBUG
-static void
-timer_dump(isc_task_t *task, isc_event_t *ev) {
-       dns_resolver_t *res;
-       isc_interval_t interval;
-       isc_time_t nexttime;
-
-       UNUSED(task);
-
-       res = ev->ev_arg;
-       INSIST(VALID_RESOLVER(res));
-
-       if (res->extqueries > 0) {
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
-                             DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
-                             "resolver dump %p: external queries "
-                             "total/NS/SOA/A/AAAA=%u/%u/%u/%u/%u",
-                             res, res->extqueries, res->extqueries_ns,
-                             res->extqueries_soa, res->extqueries_a,
-                             res->extqueries_aaaa);
-       }
-
-       interval.seconds = DUMP_INTERVAL;
-       interval.nanoseconds = 0;
-
-       RUNTIME_CHECK(isc_time_add(&res->dump_time, &interval, &nexttime) ==
-                     ISC_R_SUCCESS); /* XXX: this is not always true */
-       res->dump_time = nexttime;
-       (void)isc_timer_reset(res->dumptimer, isc_timertype_once,
-                             &res->dump_time, NULL, ISC_FALSE);
-
-       isc_event_free(&ev);
-}
-#endif