Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753302AbbGAB0J (ORCPT ); Tue, 30 Jun 2015 21:26:09 -0400 Received: from mail.kernel.org ([198.145.29.136]:58542 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753242AbbGABZy (ORCPT ); Tue, 30 Jun 2015 21:25:54 -0400 From: Jaegeuk Kim To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Cc: Jaegeuk Kim Subject: [PATCH 2/2] f2fs: shrink unreferenced extent_caches first Date: Tue, 30 Jun 2015 18:25:46 -0700 Message-Id: <1435713946-6910-2-git-send-email-jaegeuk@kernel.org> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1435713946-6910-1-git-send-email-jaegeuk@kernel.org> References: <1435713946-6910-1-git-send-email-jaegeuk@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2845 Lines: 98 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. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8f059e0..a0a0e2b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -661,21 +661,54 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) struct radix_tree_root *root = &sbi->extent_tree_root; unsigned int found; unsigned int node_cnt = 0, tree_cnt = 0; + int remained; if (!test_opt(sbi, EXTENT_CACHE)) 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); list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) { - if (!nr_shrink--) + if (!remained--) break; list_del_init(&en->list); } spin_unlock(&sbi->extent_lock); - if (!down_write_trylock(&sbi->extent_tree_lock)) - goto out; - while ((found = radix_tree_gang_lookup(root, (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { unsigned i; @@ -687,14 +720,12 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) write_lock(&et->lock); node_cnt += __free_extent_tree(sbi, et, false); write_unlock(&et->lock); - if (!atomic_read(&et->refcount) && !et->count) { - 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) + break; } } +unlock_out: up_write(&sbi->extent_tree_lock); out: trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt); -- 2.1.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/