summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--memcached.c16
-rw-r--r--slab_automove_extstore.c9
-rw-r--r--slabs.c15
-rw-r--r--slabs.h2
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;
}
diff --git a/slabs.c b/slabs.c
index c9a37aa..cedb1e8 100644
--- a/slabs.c
+++ b/slabs.c
@@ -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) {
diff --git a/slabs.h b/slabs.h
index 447033c..1516f86 100644
--- a/slabs.h
+++ b/slabs.h
@@ -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