]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
config file settings for message cache.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 26 Mar 2007 10:33:41 +0000 (10:33 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 26 Mar 2007 10:33:41 +0000 (10:33 +0000)
git-svn-id: file:///svn/unbound/trunk@196 be551aaa-1e26-0410-a405-d3ace91eadb9

16 files changed:
daemon/daemon.c
daemon/daemon.h
daemon/unbound.c
daemon/worker.c
doc/Changelog
doc/example.conf
doc/unbound.conf.5
testcode/unitmain.c
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/net_help.c
util/net_help.h
util/storage/slabhash.c
util/storage/slabhash.h

index 53722540d9a01d08333a39949dab0ebf2091abfc..5cfea217b103bcfec2c2377ea8ab33969db5f8d9 100644 (file)
@@ -48,6 +48,7 @@
 #include "util/log.h"
 #include "util/config_file.h"
 #include "util/data/msgreply.h"
+#include "util/storage/slabhash.h"
 #include "services/listen_dnsport.h"
 #include <signal.h>
 
@@ -117,7 +118,7 @@ daemon_init()
        signal_handling_record();
        checklock_start();
        daemon->need_to_exit = 0;
-       daemon->msg_cache = lruhash_create(HASH_DEFAULT_STARTARRAY,
+       daemon->msg_cache = slabhash_create(4, HASH_DEFAULT_STARTARRAY,
                HASH_DEFAULT_MAXMEM, msgreply_sizefunc, query_info_compare,
                query_entry_delete, reply_info_delete, NULL);
        if(!daemon->msg_cache) {
@@ -311,7 +312,7 @@ daemon_delete(struct daemon* daemon)
        if(!daemon)
                return;
        listening_ports_free(daemon->ports);
-       lruhash_delete(daemon->msg_cache);
+       slabhash_delete(daemon->msg_cache);
        alloc_clear(&daemon->superalloc);
        free(daemon->cwd);
        free(daemon->pidfile);
index a52fbe739372b97d5ba6d52f81af4016a4ee85f4..022623f87611d01e12345bd31db8181413ad0c09 100644 (file)
@@ -47,7 +47,7 @@
 struct config_file;
 struct worker;
 struct listen_port;
-struct lruhash;
+struct slabhash;
 
 /**
  * Structure holding worker list.
@@ -73,7 +73,7 @@ struct daemon {
        /** master allocation cache */
        struct alloc_cache superalloc;
        /** the message cache, content is struct msgreply_entry* */
-       struct lruhash* msg_cache;
+       struct slabhash* msg_cache;
 };
 
 /**
index 6ab21609e9e57e0613f089962c14c216d42bb794..197e5d07479089b1470f4cc5f547d40e2b6fc39d 100644 (file)
@@ -44,6 +44,8 @@
 #include "util/log.h"
 #include "daemon/daemon.h"
 #include "util/config_file.h"
+#include "util/storage/slabhash.h"
+#include "util/data/msgreply.h"
 #include <signal.h>
 #include <fcntl.h>
 #include <pwd.h>
@@ -80,6 +82,17 @@ apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose)
                                fatal_exit("malloc failed");
                }
        }
+       if(cfg->msg_cache_size != slabhash_get_size(daemon->msg_cache) ||
+               cfg->msg_cache_slabs != daemon->msg_cache->size) {
+               slabhash_delete(daemon->msg_cache);
+               daemon->msg_cache = slabhash_create(cfg->msg_cache_slabs, 
+                       HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size, 
+                       msgreply_sizefunc, query_info_compare,
+                       query_entry_delete, reply_info_delete, NULL);
+               if(!daemon->msg_cache) {
+                       fatal_exit("malloc failure updating config settings");
+               }
+       }
 }
 
 /** Read existing pid from pidfile. */
index 03497f43361c1523d41417f51ebef35f645cfb86..0806b9bc671e480376ce649c6585c0d748fcdb2b 100644 (file)
@@ -47,6 +47,7 @@
 #include "daemon/daemon.h"
 #include "util/netevent.h"
 #include "util/config_file.h"
+#include "util/storage/slabhash.h"
 #include "services/listen_dnsport.h"
 #include "services/outside_network.h"
 
@@ -159,7 +160,7 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
                log_err("out of memory");
                return 0;
        }
-       lruhash_insert(worker->daemon->msg_cache, worker->query_hash, 
+       slabhash_insert(worker->daemon->msg_cache, worker->query_hash, 
                &e->entry, rep);
        return 0;
 }
@@ -290,7 +291,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
                return 1;
        }
        h = query_info_hash(&worker->qinfo);
-       if((e=lruhash_lookup(worker->daemon->msg_cache, h, &worker->qinfo, 
+       if((e=slabhash_lookup(worker->daemon->msg_cache, h, &worker->qinfo, 
                0))) {
                /* answer from cache */
                log_info("answer from the cache");
index f6727a0c1f6795e53074849949cf71b5e1762f5d..8ce4df11d8544555db656a195f1dc6dd1c197e9b 100644 (file)
@@ -1,3 +1,6 @@
+26 March 2007: Wouter
+       - config settings for slab hash message cache.
+
 23 March 2007: Wouter
        - review of yesterday's commits.
        - covered up memory leak of the entry locks.
index 81869f03d75f5715663057e41ce472488d097dc2..84d633d241abd8b346d99d2d16e59a1947823a0a 100644 (file)
@@ -36,6 +36,14 @@ server:
        # But also takes more system resources (for open sockets).
        # outgoing-range: 16
 
+       # the amount of memory to use for the message cache.
+       # in bytes. default is 4 Mb
+       # msg-cache-size: 4194304
+
+       # the number of slabs to use for the message cache.
+       # more slabs reduce lock contention, but fracture memory usage.
+       # msg-cache-slabs: 4
+
        # Enable IPv4, "yes" or "no".
        # do-ip4: yes
 
index bafc6f8a68428df4482f625c7a0254462b68debf..7fa0929e7f76a33b563c1501d4a77c6753e22332 100644 (file)
@@ -63,6 +63,12 @@ Number of ports to open. This number is opened per thread for every outgoing
 query interface. Must be at least 1. Default is 16.
 Larger numbers give more protection against spoofing attempts, but need
 extra resources from the operating system.
+.It \fBmsg-cache-size:\fR <number>
+Number of bytes size of the message cache. Default is 4 megabytes.
+.It \fBmsg-cache-slabs:\fR <number>
+Number of slabs in the message cache. Slabs reduce lock contention by threads.
+Must be set to a power of 2. Setting (close) to the number of cpus is a 
+reasonable guess.
 .It \fBdo-ip4:\fR <yes or no>
 Enable or disable whether ip4 queries are answered. Default is yes.
 .It \fBdo-ip6:\fR <yes or no>
index 4790235075ba0183c9b9adae37e7faa7d9e7be80..833af9265621d84f3ec5d3c2828a69df323da1ed 100644 (file)
@@ -97,6 +97,26 @@ net_test()
        unit_assert( !str_is_ip6("213.154.224.12") );
        unit_assert( !str_is_ip6("213.154.224.255") );
        unit_assert( !str_is_ip6("255.255.255.0") );
+       unit_assert( is_pow2(0) );
+       unit_assert( is_pow2(1) );
+       unit_assert( is_pow2(2) );
+       unit_assert( is_pow2(4) );
+       unit_assert( is_pow2(8) );
+       unit_assert( is_pow2(16) );
+       unit_assert( is_pow2(1024) );
+       unit_assert( is_pow2(1024*1024) );
+       unit_assert( is_pow2(1024*1024*1024) );
+       unit_assert( !is_pow2(3) );
+       unit_assert( !is_pow2(5) );
+       unit_assert( !is_pow2(6) );
+       unit_assert( !is_pow2(7) );
+       unit_assert( !is_pow2(9) );
+       unit_assert( !is_pow2(10) );
+       unit_assert( !is_pow2(11) );
+       unit_assert( !is_pow2(17) );
+       unit_assert( !is_pow2(23) );
+       unit_assert( !is_pow2(257) );
+       unit_assert( !is_pow2(259) );
 }
 
 /** put dname into buffer */
index 8e05e0da2dbef3164af009c7bf434058fb50531e..026c6eb6143305f42a035c124e09e78fd16506a5 100644 (file)
@@ -77,6 +77,8 @@ config_create()
        cfg->do_tcp = 1;
        cfg->outgoing_base_port = cfg->port + 1000;
        cfg->outgoing_num_ports = 16;
+       cfg->msg_cache_size = 4 * 1024 * 1024;
+       cfg->msg_cache_slabs = 4;
        if(!(cfg->fwd_address = strdup(""))) {config_delete(cfg); return NULL;}
        if(!(cfg->username = strdup(""))) {config_delete(cfg); return NULL;}
        if(!(cfg->chrootdir = strdup(""))) {config_delete(cfg); return NULL;}
index f755683318f3e8839e9d289bd33f6fa841a7e427..4b94e333f512d716f06a77ba6735964f0ae8649d 100644 (file)
@@ -69,6 +69,11 @@ struct config_file {
        /** outgoing port range number of ports (per thread, per if) */
        int outgoing_num_ports;
 
+       /** size of the message cache */
+       size_t msg_cache_size;
+       /** slabs in the message cache. */
+       size_t msg_cache_slabs;
+
        /** forwarder address. string. If not NULL fwder mode is enabled. */
        char* fwd_address;
        /** forwarder port */
index e104a0a593212f17452260911576dff4aa3e9468..73739efebbbbef15a4a1f3d42e55b1a90f5f35d2 100644 (file)
@@ -114,6 +114,8 @@ username{COLON}             { LEXOUT(("v(%s) ", yytext)); return VAR_USERNAME;}
 directory{COLON}       { LEXOUT(("v(%s) ", yytext)); return VAR_DIRECTORY;}
 logfile{COLON}         { LEXOUT(("v(%s) ", yytext)); return VAR_LOGFILE;}
 pidfile{COLON}         { LEXOUT(("v(%s) ", yytext)); return VAR_PIDFILE;}
+msg-cache-size{COLON}  { LEXOUT(("v(%s) ", yytext)); return VAR_MSG_CACHE_SIZE;}
+msg-cache-slabs{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MSG_CACHE_SLABS;}
 {NEWLINE}              { LEXOUT(("NL\n")); cfg_parser->line++;}
 
        /* Quoted strings. Strip leading and ending quotes */
index 6d375975050e71dfb4132d9c12a42783af7cde0f..4ddcce2b155e9065ae425874d57128da3c7b5d64 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "util/configyyrename.h"
 #include "util/config_file.h"
+#include "util/net_help.h"
 
 int ub_c_lex(void);
 void ub_c_error(const char *message);
@@ -71,6 +72,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
 %token VAR_FORWARD_TO VAR_FORWARD_TO_PORT VAR_CHROOT
 %token VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
+%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -90,7 +92,8 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_outgoing_port | server_outgoing_range | server_do_ip4 |
        server_do_ip6 | server_do_udp | server_do_tcp | server_forward_to |
        server_forward_to_port | server_interface | server_chroot | 
-       server_username | server_directory | server_logfile | server_pidfile;
+       server_username | server_directory | server_logfile | server_pidfile |
+       server_msg_cache_size | server_msg_cache_slabs;
 server_num_threads: VAR_NUM_THREADS STRING 
        { 
                OUTYY(("P(server_num_threads:%s)\n", $2)); 
@@ -236,6 +239,28 @@ server_pidfile: VAR_PIDFILE STRING
                cfg_parser->cfg->pidfile = $2;
        }
        ;
+server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING
+       {
+               OUTYY(("P(server_msg_cache_size:%s)\n", $2));
+               if(atoi($2) == 0)
+                       yyerror("number expected");
+               else cfg_parser->cfg->msg_cache_size = atoi($2);
+               free($2);
+       }
+       ;
+server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING
+       {
+               OUTYY(("P(server_msg_cache_slabs:%s)\n", $2));
+               if(atoi($2) == 0)
+                       yyerror("number expected");
+               else {
+                       cfg_parser->cfg->msg_cache_slabs = atoi($2);
+                       if(!is_pow2(cfg_parser->cfg->msg_cache_slabs))
+                               yyerror("must be a power of 2");
+               }
+               free($2);
+       }
+       ;
 %%
 
 /* parse helper routines could be here */
index 2ffd41d3fedaff243ea75d78f40d9642b49fce78..a42f2af93bcef0e6b0f32a9993cef916e33a9b52 100644 (file)
@@ -87,3 +87,10 @@ fd_set_nonblock(int s)
        }
        return 1;
 }
+
+int 
+is_pow2(size_t num)
+{
+       if(num == 0) return 1;
+       return (num & (num-1)) == 0;
+}
index 78d432f76e8c16d75d4c2bf6caa1557af41f27c4..6ea82ba2a259b5578996550104aedd1762f79968 100644 (file)
@@ -66,4 +66,11 @@ write_socket(int s, const void *buf, size_t size);
  */
 int fd_set_nonblock(int s); 
 
+/**
+ * See if number is a power of 2.
+ * @param num: the value.
+ * @return: true if the number is a power of 2.
+ */
+int is_pow2(size_t num);
+
 #endif /* NET_HELP_H */
index d0d2e56267a43c8f7b51ee1465f671d79e2965b3..929e5e170837f62b352cb779c3e7de490735e8b7 100644 (file)
@@ -131,3 +131,14 @@ void slabhash_status(struct slabhash* sl, const char* id, int extended)
                lruhash_status(sl->array[i], num, extended);
        }
 }
+
+size_t slabhash_get_size(struct slabhash* sl)
+{
+       size_t i, total = 0;
+       for(i=0; i<sl->size; i++) {
+               lock_quick_lock(&sl->array[i]->lock);
+               total += sl->array[i]->space_max;
+               lock_quick_unlock(&sl->array[i]->lock);
+       }
+       return total;
+}
index 2e9a740291ae147f7152311b535ade4486b551fb..7fde7caf45b30db256a822bceaad8a7b70a5b058 100644 (file)
@@ -134,4 +134,10 @@ void slabhash_remove(struct slabhash* table, hashvalue_t hash, void* key);
  */
 void slabhash_status(struct slabhash* table, const char* id, int extended);
 
+/**
+ * Retrieve slab hash total size.
+ * @param table: hash table.
+ */
+size_t slabhash_get_size(struct slabhash* table);
+
 #endif /* UTIL_STORAGE_SLABHASH_H */