Multipage allocation
We can also quite simply allocate bigger blocks. Anyway, we need these blocks to be aligned to their size which needs one mmap() two times bigger and then two munmap()s returning the unaligned parts. The user can specify -B <N> on startup when <N> is the exponent of 2, setting the block size to 2^N. On most systems, N is 12, anyway if you know that your configuration is going to eat gigabytes of RAM, you are almost forced to raise your block size as you may easily get into memory fragmentation issues or you have to raise your maximum mapping count, e.g. "sysctl vm.max_map_count=(number)".
This commit is contained in:
parent
3a31c3aad6
commit
6cd3771378
5 changed files with 62 additions and 4 deletions
|
@ -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:
|
<p>You can pass several command-line options to bird:
|
||||||
|
|
||||||
<descrip>
|
<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>
|
<tag><label id="argv-config">-c <m/config name/</tag>
|
||||||
use given configuration file instead of <it/prefix/<file>/etc/bird.conf</file>.
|
use given configuration file instead of <it/prefix/<file>/etc/bird.conf</file>.
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ pool root_pool;
|
||||||
|
|
||||||
void *alloc_sys_page(void);
|
void *alloc_sys_page(void);
|
||||||
void free_sys_page(void *);
|
void free_sys_page(void *);
|
||||||
void resource_sys_init(void);
|
|
||||||
|
|
||||||
static int indent;
|
static int indent;
|
||||||
|
|
||||||
|
@ -283,7 +282,6 @@ rlookup(unsigned long a)
|
||||||
void
|
void
|
||||||
resource_init(void)
|
resource_init(void)
|
||||||
{
|
{
|
||||||
resource_sys_init();
|
|
||||||
root_pool.r.class = &pool_class;
|
root_pool.r.class = &pool_class;
|
||||||
root_pool.name = "Root";
|
root_pool.name = "Root";
|
||||||
init_list(&root_pool.inside);
|
init_list(&root_pool.inside);
|
||||||
|
|
|
@ -178,7 +178,7 @@ struct sl_alignment { /* Magic structure for testing of alignment */
|
||||||
int x[0];
|
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
|
* sl_new - create a new Slab
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long page_size = 0;
|
long page_size = 0;
|
||||||
|
_Bool alloc_multipage = 0;
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
static _Bool use_fake = 0;
|
static _Bool use_fake = 0;
|
||||||
|
@ -45,9 +46,31 @@ alloc_sys_page(void)
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
if (!use_fake)
|
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);
|
void *ret = mmap(NULL, page_size, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
if (ret == MAP_FAILED)
|
if (ret == MAP_FAILED)
|
||||||
bug("mmap(%lu) failed: %m", page_size);
|
bug("mmap(%lu) failed: %m", page_size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -682,7 +682,7 @@ signal_init(void)
|
||||||
* Parsing of command-line arguments
|
* 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;
|
int parse_and_exit;
|
||||||
char *bird_name;
|
char *bird_name;
|
||||||
static char *use_user;
|
static char *use_user;
|
||||||
|
@ -703,6 +703,7 @@ display_help(void)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
"Options: \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"
|
" -c <config-file> Use given configuration file instead of\n"
|
||||||
" " PATH_CONFIG_FILE "\n"
|
" " PATH_CONFIG_FILE "\n"
|
||||||
" -d Enable debug messages and run bird in foreground\n"
|
" -d Enable debug messages and run bird in foreground\n"
|
||||||
|
@ -789,12 +790,15 @@ get_gid(const char *s)
|
||||||
return gr->gr_gid;
|
return gr->gr_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern _Bool alloc_multipage;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_args(int argc, char **argv)
|
parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int config_changed = 0;
|
int config_changed = 0;
|
||||||
int socket_changed = 0;
|
int socket_changed = 0;
|
||||||
int c;
|
int c;
|
||||||
|
int bp;
|
||||||
|
|
||||||
bird_name = get_bird_name(argv[0], "bird");
|
bird_name = get_bird_name(argv[0], "bird");
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
|
@ -807,6 +811,29 @@ parse_args(int argc, char **argv)
|
||||||
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
||||||
switch (c)
|
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':
|
case 'c':
|
||||||
config_name = optarg;
|
config_name = optarg;
|
||||||
config_changed = 1;
|
config_changed = 1;
|
||||||
|
@ -861,6 +888,8 @@ parse_args(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resource_sys_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hic Est main()
|
* Hic Est main()
|
||||||
*/
|
*/
|
||||||
|
@ -873,6 +902,7 @@ main(int argc, char **argv)
|
||||||
dmalloc_debug(0x2f03d00);
|
dmalloc_debug(0x2f03d00);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
resource_sys_init();
|
||||||
parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
log_switch(1, NULL, NULL);
|
log_switch(1, NULL, NULL);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue