f2fs: shrink unreferenced extent_caches first
If an extent_tree entry has a zero reference count, we can drop it from the cache in higher priority rather than currently referencing entries. Reviewed-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
bb96a8d51e
commit
7023a1ad17
|
@ -662,21 +662,54 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
|
||||||
struct radix_tree_root *root = &sbi->extent_tree_root;
|
struct radix_tree_root *root = &sbi->extent_tree_root;
|
||||||
unsigned int found;
|
unsigned int found;
|
||||||
unsigned int node_cnt = 0, tree_cnt = 0;
|
unsigned int node_cnt = 0, tree_cnt = 0;
|
||||||
|
int remained;
|
||||||
|
|
||||||
if (!test_opt(sbi, EXTENT_CACHE))
|
if (!test_opt(sbi, EXTENT_CACHE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!down_write_trylock(&sbi->extent_tree_lock))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* 1. remove unreferenced extent tree */
|
||||||
|
while ((found = radix_tree_gang_lookup(root,
|
||||||
|
(void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
ino = treevec[found - 1]->ino + 1;
|
||||||
|
for (i = 0; i < found; i++) {
|
||||||
|
struct extent_tree *et = treevec[i];
|
||||||
|
|
||||||
|
if (!atomic_read(&et->refcount)) {
|
||||||
|
write_lock(&et->lock);
|
||||||
|
node_cnt += __free_extent_tree(sbi, et, true);
|
||||||
|
write_unlock(&et->lock);
|
||||||
|
|
||||||
|
radix_tree_delete(root, et->ino);
|
||||||
|
kmem_cache_free(extent_tree_slab, et);
|
||||||
|
sbi->total_ext_tree--;
|
||||||
|
tree_cnt++;
|
||||||
|
|
||||||
|
if (node_cnt + tree_cnt >= nr_shrink)
|
||||||
|
goto unlock_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up_write(&sbi->extent_tree_lock);
|
||||||
|
|
||||||
|
/* 2. remove LRU extent entries */
|
||||||
|
if (!down_write_trylock(&sbi->extent_tree_lock))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
remained = nr_shrink - (node_cnt + tree_cnt);
|
||||||
|
|
||||||
spin_lock(&sbi->extent_lock);
|
spin_lock(&sbi->extent_lock);
|
||||||
list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) {
|
list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) {
|
||||||
if (!nr_shrink--)
|
if (!remained--)
|
||||||
break;
|
break;
|
||||||
list_del_init(&en->list);
|
list_del_init(&en->list);
|
||||||
}
|
}
|
||||||
spin_unlock(&sbi->extent_lock);
|
spin_unlock(&sbi->extent_lock);
|
||||||
|
|
||||||
if (!down_write_trylock(&sbi->extent_tree_lock))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
while ((found = radix_tree_gang_lookup(root,
|
while ((found = radix_tree_gang_lookup(root,
|
||||||
(void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
|
(void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -688,14 +721,12 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
|
||||||
write_lock(&et->lock);
|
write_lock(&et->lock);
|
||||||
node_cnt += __free_extent_tree(sbi, et, false);
|
node_cnt += __free_extent_tree(sbi, et, false);
|
||||||
write_unlock(&et->lock);
|
write_unlock(&et->lock);
|
||||||
if (!atomic_read(&et->refcount) && !et->count) {
|
|
||||||
radix_tree_delete(root, et->ino);
|
if (node_cnt + tree_cnt >= nr_shrink)
|
||||||
kmem_cache_free(extent_tree_slab, et);
|
break;
|
||||||
sbi->total_ext_tree--;
|
|
||||||
tree_cnt++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unlock_out:
|
||||||
up_write(&sbi->extent_tree_lock);
|
up_write(&sbi->extent_tree_lock);
|
||||||
out:
|
out:
|
||||||
trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt);
|
trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt);
|
||||||
|
|
Loading…
Reference in New Issue