mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-22 14:54:38 +08:00
Rework node slab garbage collection to limit blocking work threads
Also remove debug mode from forcing foreground mode
This commit is contained in:
parent
f159fe61f9
commit
9ca10b2413
|
@ -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_;
|
||||
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_)
|
||||
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;
|
||||
|
||||
objs_per_slab = (fmp_->slab_size / fmp_->obj_size);
|
||||
slab_idx_ = (slab_idx_ % kv_size(fmp_->slabs));
|
||||
|
||||
i = 0;
|
||||
freed_slabs = 0;
|
||||
while(i < kv_size(fmp_->slabs))
|
||||
{
|
||||
char *slab;
|
||||
uint64_t objs_in_slab;
|
||||
slab = kv_A(fmp_->slabs,slab_idx_);
|
||||
|
||||
slab = kv_A(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;
|
||||
|
||||
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,slab_idx_);
|
||||
fmp_slab_free_mmap(fmp_,slab);
|
||||
|
||||
fmp_remove_objs_in_slab(fmp_,slab);
|
||||
|
||||
kv_delete(fmp_->slabs,i);
|
||||
|
||||
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
|
||||
|
|
|
@ -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,38 +4004,40 @@ void
|
|||
metrics_log_nodes_info(struct fuse *f_,
|
||||
FILE *file_)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
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) == 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)
|
||||
metrics_log_nodes_info_to_tmp_dir(f);
|
||||
|
|
|
@ -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…
Reference in New Issue
Block a user