Skip to content
Snippets Groups Projects
Commit 644e9ca9 authored by Maria Matejka's avatar Maria Matejka Committed by Maria Matejka
Browse files

Directly mapped pages are kept for future use if temporarily not needed

parent 9f24fef5
No related branches found
No related tags found
No related merge requests found
Pipeline #91321 failed
......@@ -98,6 +98,7 @@ void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_siz
u64 get_page_size(void);
void *alloc_page(void);
void free_page(void *);
extern uint pages_kept;
#ifdef HAVE_LIBDMALLOC
/*
......
......@@ -91,7 +91,12 @@ cmd_show_memory(void)
print_size("Routing tables:", rmemsize(rt_table_pool));
print_size("Route attributes:", rmemsize(rta_pool));
print_size("Protocols:", rmemsize(proto_pool));
print_size("Total:", rmemsize(&root_pool));
size_t total = rmemsize(&root_pool);
#ifdef HAVE_MMAP
print_size("Standby memory:", get_page_size() * pages_kept);
total += get_page_size() * pages_kept;
#endif
print_size("Total:", total);
cli_msg(0, "");
}
......
......@@ -8,6 +8,8 @@
#include "nest/bird.h"
#include "lib/resource.h"
#include "lib/lists.h"
#include "lib/event.h"
#include <stdlib.h>
#include <unistd.h>
......@@ -17,8 +19,17 @@
#endif
#ifdef HAVE_MMAP
#define KEEP_PAGES 512
static u64 page_size = 0;
static _Bool use_fake = 0;
uint pages_kept = 0;
static list pages_list;
static void cleanup_pages(void *data);
static event page_cleanup_event = { .hook = cleanup_pages };
#else
static const u64 page_size = 4096; /* Fake page size */
#endif
......@@ -48,6 +59,15 @@ void *
alloc_page(void)
{
#ifdef HAVE_MMAP
if (pages_kept)
{
node *page = TAIL(pages_list);
rem_node(page);
pages_kept--;
memset(page, 0, get_page_size());
return page;
}
if (!use_fake)
{
void *ret = mmap(NULL, get_page_size(), PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
......@@ -71,10 +91,39 @@ free_page(void *ptr)
#ifdef HAVE_MMAP
if (!use_fake)
{
if (munmap(ptr, get_page_size()) < 0)
bug("munmap(%p) failed: %m", ptr);
if (!pages_kept)
init_list(&pages_list);
memset(ptr, 0, sizeof(node));
add_tail(&pages_list, ptr);
if (++pages_kept > KEEP_PAGES)
ev_schedule(&page_cleanup_event);
}
else
#endif
free(ptr);
}
#ifdef HAVE_MMAP
static void
cleanup_pages(void *data UNUSED)
{
for (uint seen = 0; (pages_kept > KEEP_PAGES) && (seen < KEEP_PAGES); seen++)
{
void *ptr = HEAD(pages_list);
rem_node(ptr);
if (munmap(ptr, get_page_size()) == 0)
pages_kept--;
#ifdef ENOMEM
else if (errno == ENOMEM)
add_tail(&pages_list, ptr);
#endif
else
bug("munmap(%p) failed: %m", ptr);
}
if (pages_kept > KEEP_PAGES)
ev_schedule(&page_cleanup_event);
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment