Browse Source

Rework node slab garbage collection to limit blocking work threads

Also remove debug mode from forcing foreground mode
pull/1020/head
Antonio SJ Musumeci 3 years ago
parent
commit
9ca10b2413
  1. 82
      libfuse/lib/fmp.h
  2. 25
      libfuse/lib/fuse.c
  3. 2
      libfuse/lib/helper.c

82
libfuse/lib/fmp.h

@ -249,6 +249,14 @@ fmp_avail_objs(fmp_t *fmp_)
return fmp_->avail_objs;
}
static
inline
uint64_t
fmp_objs_per_slab(fmp_t *fmp_)
{
return (fmp_->slab_size / fmp_->obj_size);
}
static
inline
uint64_t
@ -256,15 +264,19 @@ fmp_objs_in_slab(fmp_t *fmp_,
void *slab_)
{
char *slab;
uint64_t objs_per_slab;
uint64_t objs_in_slab;
objs_in_slab = 0;
slab = (char*)slab_;
objs_in_slab = 0;
objs_per_slab = fmp_objs_per_slab(fmp_);
for(mem_stack_t *stack = fmp_->objs; stack != NULL; stack = stack->next)
{
char *obj = (char*)stack;
if((obj >= slab) && (obj < (slab + fmp_->slab_size)))
objs_in_slab++;
if(objs_in_slab >= objs_per_slab)
break;
}
return objs_in_slab;
@ -276,17 +288,27 @@ void
fmp_remove_objs_in_slab(fmp_t *fmp_,
void *slab_)
{
char *slab = (char*)slab_;
mem_stack_t **p = &fmp_->objs;
char *slab;
uint64_t objs_per_slab;
uint64_t objs_in_slab;
mem_stack_t **p;
p = &fmp_->objs;
slab = (char*)slab_;
objs_in_slab = 0;
objs_per_slab = fmp_objs_per_slab(fmp_);
while((*p) != NULL)
{
char *obj = (char*)*p;
if((obj >= slab) && (obj < (slab + fmp_->slab_size)))
{
objs_in_slab++;
*p = (*p)->next;
fmp_->avail_objs--;
if(objs_in_slab >= objs_per_slab)
break;
continue;
}
@ -297,47 +319,40 @@ fmp_remove_objs_in_slab(fmp_t *fmp_,
static
inline
int
fmp_gc(fmp_t *fmp_)
{
int i;
int freed_slabs;
uint64_t objs_per_slab;
objs_per_slab = (fmp_->slab_size / fmp_->obj_size);
i = 0;
freed_slabs = 0;
while(i < kv_size(fmp_->slabs))
fmp_gc_slab(fmp_t *fmp_,
uint64_t slab_idx_)
{
char *slab;
uint64_t objs_in_slab;
uint64_t objs_per_slab;
slab = kv_A(fmp_->slabs,i);
slab_idx_ = (slab_idx_ % kv_size(fmp_->slabs));
slab = kv_A(fmp_->slabs,slab_idx_);
objs_per_slab = fmp_objs_per_slab(fmp_);
objs_in_slab = fmp_objs_in_slab(fmp_,slab);
if(objs_in_slab != objs_per_slab)
{
i++;
continue;
}
return 0;
fmp_remove_objs_in_slab(fmp_,slab);
kv_delete(fmp_->slabs,i);
kv_delete(fmp_->slabs,slab_idx_);
fmp_slab_free_mmap(fmp_,slab);
freed_slabs++;
}
return freed_slabs;
return 1;
}
static
inline
uint64_t
fmp_objs_per_slab(fmp_t *fmp_)
int
fmp_gc(fmp_t *fmp_)
{
return (fmp_->slab_size / fmp_->obj_size);
uint64_t slab_idx;
slab_idx = rand();
return fmp_gc_slab(fmp_,slab_idx);
}
static
@ -345,14 +360,15 @@ inline
double
fmp_slab_usage_ratio(fmp_t *fmp_)
{
double rv;
uint64_t objs_per_slab;
double avail_objs;
double objs_per_slab;
double nums_of_slabs;
avail_objs = fmp_->avail_objs;
objs_per_slab = fmp_objs_per_slab(fmp_);
nums_of_slabs = kv_size(fmp_->slabs);
rv = ((double)fmp_->avail_objs / (double)objs_per_slab);
return rv;
return (avail_objs / (objs_per_slab * nums_of_slabs));
}
static

25
libfuse/lib/fuse.c

@ -62,6 +62,7 @@ struct fuse_config
unsigned int umask;
int remember;
int debug;
int nogc;
int use_ino;
int set_mode;
int set_uid;
@ -3903,6 +3904,7 @@ static const struct fuse_opt fuse_lib_opts[] =
FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
FUSE_LIB_OPT("debug", debug,1),
FUSE_LIB_OPT("-d", debug,1),
FUSE_LIB_OPT("nogc", nogc,1),
FUSE_LIB_OPT("umask=", set_mode,1),
FUSE_LIB_OPT("umask=%o", umask,0),
FUSE_LIB_OPT("uid=", set_uid,1),
@ -4002,9 +4004,10 @@ void
metrics_log_nodes_info(struct fuse *f_,
FILE *file_)
{
pthread_mutex_lock(&f_->lock);
char buf[1024];
fprintf(file_,
pthread_mutex_lock(&f_->lock);
snprintf(buf,sizeof(buf),
"time: %zu\n"
"sizeof(node): %zu\n"
"node id_table size: %zu\n"
@ -4032,8 +4035,9 @@ metrics_log_nodes_info(struct fuse *f_,
lfmp_avail_objs(&f_->node_fmp),
lfmp_total_allocated_memory(&f_->node_fmp)
);
pthread_mutex_unlock(&f_->lock);
fputs(buf,file_);
}
static
@ -4068,11 +4072,13 @@ static
void*
fuse_maintenance_loop(void *fuse_)
{
int gc;
int loops;
int sleep_time;
double slab_usage_ratio;
struct fuse *f = (struct fuse*)fuse_;
gc = 0;
loops = 0;
sleep_time = 60;
while(1)
@ -4080,12 +4086,15 @@ fuse_maintenance_loop(void *fuse_)
if(remember_nodes(f))
fuse_prune_remembered_nodes(f);
slab_usage_ratio = lfmp_slab_usage_ratio(&f->node_fmp);
if(slab_usage_ratio > 3.0)
lfmp_gc(&f->node_fmp);
if(loops % 15)
if((loops % 15) == 0)
{
fuse_malloc_trim();
gc = 1;
}
// Trigger a followup gc if this gc succeeds
if(!f->conf.nogc && gc)
gc = lfmp_gc(&f->node_fmp);
if(g_LOG_METRICS)
metrics_log_nodes_info_to_tmp_dir(f);

2
libfuse/lib/helper.c

@ -40,8 +40,6 @@ static
const
struct fuse_opt fuse_helper_opts[] =
{
FUSE_HELPER_OPT("-d", foreground),
FUSE_HELPER_OPT("debug", foreground),
FUSE_HELPER_OPT("-f", foreground),
FUSE_HELPER_OPT("fsname=", nodefault_subtype),
FUSE_HELPER_OPT("subtype=", nodefault_subtype),

Loading…
Cancel
Save