diff options
-rw-r--r-- | memcached.c | 16 | ||||
-rw-r--r-- | slab_automove_extstore.c | 9 | ||||
-rw-r--r-- | slabs.c | 15 | ||||
-rw-r--r-- | slabs.h | 2 |
4 files changed, 39 insertions, 3 deletions
diff --git a/memcached.c b/memcached.c index 96b9bab..1f03f2f 100644 --- a/memcached.c +++ b/memcached.c @@ -6576,6 +6576,7 @@ int main (int argc, char **argv) { EXT_DROP_UNDER, EXT_MAX_FRAG, EXT_DROP_UNREAD, + SLAB_AUTOMOVE_FREERATIO, #endif }; char *const subopts_tokens[] = { @@ -6632,6 +6633,7 @@ int main (int argc, char **argv) { [EXT_DROP_UNDER] = "ext_drop_under", [EXT_MAX_FRAG] = "ext_max_frag", [EXT_DROP_UNREAD] = "ext_drop_unread", + [SLAB_AUTOMOVE_FREERATIO] = "slab_automove_freeratio", #endif NULL }; @@ -6656,7 +6658,7 @@ int main (int argc, char **argv) { settings.ext_wbuf_size = 1024 * 1024 * 4; settings.ext_compact_under = 0; settings.ext_drop_under = 0; - settings.slab_automove_freeratio = 0.005; + settings.slab_automove_freeratio = 0.01; ext_cf.page_size = 1024 * 1024 * 64; ext_cf.page_count = 64; ext_cf.wbuf_size = settings.ext_wbuf_size; @@ -7296,6 +7298,16 @@ int main (int argc, char **argv) { return 1; } break; + case SLAB_AUTOMOVE_FREERATIO: + if (subopts_value == NULL) { + fprintf(stderr, "Missing slab_automove_freeratio argument\n"); + return 1; + } + if (!safe_strtod(subopts_value, &settings.slab_automove_freeratio)) { + fprintf(stderr, "could not parse argument to slab_automove_freeratio\n"); + return 1; + } + break; case EXT_DROP_UNREAD: settings.ext_drop_unread = true; break; @@ -7578,6 +7590,8 @@ int main (int argc, char **argv) { exit(EXIT_FAILURE); } ext_storage = storage; + /* page mover algorithm for extstore needs memory prefilled */ + slabs_prefill_global(); } #endif /* diff --git a/slab_automove_extstore.c b/slab_automove_extstore.c index 5663da8..d9b62b9 100644 --- a/slab_automove_extstore.c +++ b/slab_automove_extstore.c @@ -37,6 +37,7 @@ typedef struct { rel_time_t last_memcheck_run; double max_age_ratio; double free_ratio; + bool pool_filled_once; unsigned int free_mem[MAX_NUMBER_OF_SLAB_CLASSES]; item_stats_automove iam_before[MAX_NUMBER_OF_SLAB_CLASSES]; item_stats_automove iam_after[MAX_NUMBER_OF_SLAB_CLASSES]; @@ -58,6 +59,7 @@ void *slab_automove_extstore_init(struct settings *settings) { a->item_size = settings->ext_item_size; a->last_memcheck_run = 0; a->settings = settings; + a->pool_filled_once = false; if (a->window_data == NULL || a->window_global == NULL) { if (a->window_data) free(a->window_data); @@ -111,8 +113,11 @@ static void global_pool_check(slab_automove *a) { return; if (count < free / 2) { wg->pool_low = 1; + a->pool_filled_once = true; } else if (count > free) { wg->pool_high = 1; + } else { + a->pool_filled_once = true; } } @@ -129,10 +134,12 @@ static void memcheck(slab_automove *a) { if (sam->chunks_per_page * MIN_PAGES_FREE > hold_free) hold_free = sam->chunks_per_page * MIN_PAGES_FREE; a->free_mem[n] = hold_free; - if (a->settings->ext_free_memchunks[n] != hold_free) { + if (a->settings->ext_free_memchunks[n] != hold_free && a->pool_filled_once) { a->settings->ext_free_memchunks[n] = hold_free; } } + // remember to add what remains in global pool. + total_pages += a->sam_after[0].total_pages; a->free_mem[0] = total_pages * a->free_ratio; } @@ -62,6 +62,7 @@ static pthread_mutex_t slabs_rebalance_lock = PTHREAD_MUTEX_INITIALIZER; /* * Forward Declarations */ +static int grow_slab_list (const unsigned int id); static int do_slabs_newslab(const unsigned int id); static void *memory_allocate(size_t size); static void do_slabs_free(void *ptr, const size_t size, unsigned int id); @@ -165,6 +166,19 @@ void slabs_init(const size_t limit, const double factor, const bool prealloc, co } } +void slabs_prefill_global(void) { + void *ptr; + slabclass_t *p = &slabclass[0]; + int len = settings.slab_page_size; + + while (mem_malloced < mem_limit + && (ptr = memory_allocate(len)) != NULL) { + grow_slab_list(0); + p->slab_list[p->slabs++] = ptr; + } + mem_limit_reached = true; +} + static void slabs_preallocate (const unsigned int maxslabs) { int i; unsigned int prealloc = 0; @@ -185,7 +199,6 @@ static void slabs_preallocate (const unsigned int maxslabs) { exit(1); } } - } static int grow_slab_list (const unsigned int id) { @@ -10,6 +10,8 @@ */ void slabs_init(const size_t limit, const double factor, const bool prealloc, const uint32_t *slab_sizes); +/** Call only during init. Pre-allocates all available memory */ +void slabs_prefill_global(void); /** * Given object size, return id to use when allocating/freeing memory for object |