Browse Source

Rework node slab garbage collection to limit blocking work threads

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

92
libfuse/lib/fmp.h

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

79
libfuse/lib/fuse.c

@ -62,6 +62,7 @@ struct fuse_config
unsigned int umask; unsigned int umask;
int remember; int remember;
int debug; int debug;
int nogc;
int use_ino; int use_ino;
int set_mode; int set_mode;
int set_uid; int set_uid;
@ -3903,6 +3904,7 @@ static const struct fuse_opt fuse_lib_opts[] =
FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP), FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
FUSE_LIB_OPT("debug", debug,1), FUSE_LIB_OPT("debug", debug,1),
FUSE_LIB_OPT("-d", 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=", set_mode,1),
FUSE_LIB_OPT("umask=%o", umask,0), FUSE_LIB_OPT("umask=%o", umask,0),
FUSE_LIB_OPT("uid=", set_uid,1), FUSE_LIB_OPT("uid=", set_uid,1),
@ -4002,38 +4004,40 @@ void
metrics_log_nodes_info(struct fuse *f_, metrics_log_nodes_info(struct fuse *f_,
FILE *file_) FILE *file_)
{ {
pthread_mutex_lock(&f_->lock);
fprintf(file_,
"time: %zu\n"
"sizeof(node): %zu\n"
"node id_table size: %zu\n"
"node id_table usage: %zu\n"
"node id_table total allocated memory: %zu\n"
"node name_table size: %zu\n"
"node name_table usage: %zu\n"
"node name_table total allocated memory: %zu\n"
"node memory pool slab count: %zu\n"
"node memory pool usage ratio: %f\n"
"node memory pool avail objs: %zu\n"
"node memory pool total allocated memory: %zu\n"
"\n"
,
time(NULL),
sizeof(struct node),
f_->id_table.size,
f_->id_table.use,
(f_->id_table.size * sizeof(struct node*)),
f_->name_table.size,
f_->name_table.use,
(f_->name_table.size * sizeof(struct node*)),
lfmp_slab_count(&f_->node_fmp),
lfmp_slab_usage_ratio(&f_->node_fmp),
lfmp_avail_objs(&f_->node_fmp),
lfmp_total_allocated_memory(&f_->node_fmp)
);
char buf[1024];
pthread_mutex_lock(&f_->lock);
snprintf(buf,sizeof(buf),
"time: %zu\n"
"sizeof(node): %zu\n"
"node id_table size: %zu\n"
"node id_table usage: %zu\n"
"node id_table total allocated memory: %zu\n"
"node name_table size: %zu\n"
"node name_table usage: %zu\n"
"node name_table total allocated memory: %zu\n"
"node memory pool slab count: %zu\n"
"node memory pool usage ratio: %f\n"
"node memory pool avail objs: %zu\n"
"node memory pool total allocated memory: %zu\n"
"\n"
,
time(NULL),
sizeof(struct node),
f_->id_table.size,
f_->id_table.use,
(f_->id_table.size * sizeof(struct node*)),
f_->name_table.size,
f_->name_table.use,
(f_->name_table.size * sizeof(struct node*)),
lfmp_slab_count(&f_->node_fmp),
lfmp_slab_usage_ratio(&f_->node_fmp),
lfmp_avail_objs(&f_->node_fmp),
lfmp_total_allocated_memory(&f_->node_fmp)
);
pthread_mutex_unlock(&f_->lock); pthread_mutex_unlock(&f_->lock);
fputs(buf,file_);
} }
static static
@ -4068,11 +4072,13 @@ static
void* void*
fuse_maintenance_loop(void *fuse_) fuse_maintenance_loop(void *fuse_)
{ {
int gc;
int loops; int loops;
int sleep_time; int sleep_time;
double slab_usage_ratio; double slab_usage_ratio;
struct fuse *f = (struct fuse*)fuse_; struct fuse *f = (struct fuse*)fuse_;
gc = 0;
loops = 0; loops = 0;
sleep_time = 60; sleep_time = 60;
while(1) while(1)
@ -4080,12 +4086,15 @@ fuse_maintenance_loop(void *fuse_)
if(remember_nodes(f)) if(remember_nodes(f))
fuse_prune_remembered_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) == 0)
{
fuse_malloc_trim();
gc = 1;
}
if(loops % 15)
fuse_malloc_trim();
// Trigger a followup gc if this gc succeeds
if(!f->conf.nogc && gc)
gc = lfmp_gc(&f->node_fmp);
if(g_LOG_METRICS) if(g_LOG_METRICS)
metrics_log_nodes_info_to_tmp_dir(f); metrics_log_nodes_info_to_tmp_dir(f);

2
libfuse/lib/helper.c

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

Loading…
Cancel
Save