diff options
-rw-r--r-- | doc/bird.sgml | 7 | ||||
-rw-r--r-- | lib/resource.c | 2 | ||||
-rw-r--r-- | lib/slab.c | 2 | ||||
-rw-r--r-- | sysdep/unix/alloc.c | 23 | ||||
-rw-r--r-- | sysdep/unix/main.c | 32 |
5 files changed, 62 insertions, 4 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 39dadaf2..ddad4d98 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -145,6 +145,13 @@ BIRD executable by configuring out routing protocols you don't use, and <p>You can pass several command-line options to bird: <descrip> + <tag><label id="argv-block">-B <m/exp/</tag> + allocate memory using 2^<cf/exp/ byte sized blocks; + if you're expecting high memory load, raise this to + reduce number of allocated memory pages. For a million routes + in one table, the recommended setting is 18. + Default is your system page size, typically 12 for 4096 bytes. + <tag><label id="argv-config">-c <m/config name/</tag> use given configuration file instead of <it/prefix/<file>/etc/bird.conf</file>. diff --git a/lib/resource.c b/lib/resource.c index 0ad886d9..e80b315b 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -61,7 +61,6 @@ pool root_pool; void *alloc_sys_page(void); void free_sys_page(void *); -void resource_sys_init(void); static int indent; @@ -283,7 +282,6 @@ rlookup(unsigned long a) void resource_init(void) { - resource_sys_init(); root_pool.r.class = &pool_class; root_pool.name = "Root"; init_list(&root_pool.inside); @@ -178,7 +178,7 @@ struct sl_alignment { /* Magic structure for testing of alignment */ int x[0]; }; -#define SL_GET_HEAD(x) ((struct sl_head *) (((uintptr_t) (x)) & ~(page_size-1))) +#define SL_GET_HEAD(x) ((struct sl_head *) PAGE_HEAD(x)) /** * sl_new - create a new Slab diff --git a/sysdep/unix/alloc.c b/sysdep/unix/alloc.c index f6296afe..4c9d5eb5 100644 --- a/sysdep/unix/alloc.c +++ b/sysdep/unix/alloc.c @@ -17,6 +17,7 @@ #endif long page_size = 0; +_Bool alloc_multipage = 0; #ifdef HAVE_MMAP static _Bool use_fake = 0; @@ -45,9 +46,31 @@ alloc_sys_page(void) #ifdef HAVE_MMAP if (!use_fake) { + if (alloc_multipage) + { + void *big = mmap(NULL, page_size * 2, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (big == MAP_FAILED) + bug("mmap(%lu) failed: %m", page_size); + + uintptr_t offset = ((uintptr_t) big) % page_size; + if (offset) + { + void *ret = big + page_size - offset; + munmap(big, page_size - offset); + munmap(ret + page_size, offset); + return ret; + } + else + { + munmap(big + page_size, page_size); + return big; + } + } + void *ret = mmap(NULL, page_size, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ret == MAP_FAILED) bug("mmap(%lu) failed: %m", page_size); + return ret; } else diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index cdf0a310..7e8ea0dc 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -682,7 +682,7 @@ signal_init(void) * Parsing of command-line arguments */ -static char *opt_list = "bc:dD:ps:P:u:g:flRh"; +static char *opt_list = "B:c:dD:ps:P:u:g:flRh"; int parse_and_exit; char *bird_name; static char *use_user; @@ -703,6 +703,7 @@ display_help(void) fprintf(stderr, "\n" "Options: \n" + " -B <block-size> Use 2^this number as memory allocation block size (default: 12)\n" " -c <config-file> Use given configuration file instead of\n" " " PATH_CONFIG_FILE "\n" " -d Enable debug messages and run bird in foreground\n" @@ -789,12 +790,15 @@ get_gid(const char *s) return gr->gr_gid; } +extern _Bool alloc_multipage; + static void parse_args(int argc, char **argv) { int config_changed = 0; int socket_changed = 0; int c; + int bp; bird_name = get_bird_name(argv[0], "bird"); if (argc == 2) @@ -807,6 +811,29 @@ parse_args(int argc, char **argv) while ((c = getopt(argc, argv, opt_list)) >= 0) switch (c) { + case 'B': + bp = atoi(optarg); + if (bp < 1) + { + fprintf(stderr, "Strange block size power %d\n\n", bp); + display_usage(); + exit(1); + } + + if ((1 << bp) < page_size) + { + fprintf(stderr, "Requested block size %ld is lesser than page size %ld\n\n", (1L<<bp), page_size); + display_usage(); + exit(1); + } + + if ((1L << bp) > page_size) + { + alloc_multipage = 1; + page_size = (1L << bp); + } + + break; case 'c': config_name = optarg; config_changed = 1; @@ -861,6 +888,8 @@ parse_args(int argc, char **argv) } } +void resource_sys_init(void); + /* * Hic Est main() */ @@ -873,6 +902,7 @@ main(int argc, char **argv) dmalloc_debug(0x2f03d00); #endif + resource_sys_init(); parse_args(argc, argv); log_switch(1, NULL, NULL); |