diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 19:33:21 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 19:33:21 -0800 |
commit | a7c1120d2dcc83691bafa034d98f70285757e826 (patch) | |
tree | 56779f292c2dea78feff290c3ce26724d33b3f3e /fs/ext4/extents_status.c | |
parent | 6ec40b423032ca769c96fbf9a080db822821893d (diff) | |
parent | 9b2ff35753c0512bc8c6adae9e9c87cbeee86f82 (diff) | |
download | op-kernel-dev-a7c1120d2dcc83691bafa034d98f70285757e826.zip op-kernel-dev-a7c1120d2dcc83691bafa034d98f70285757e826.tar.gz |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bug fixes from Ted Ts'o:
"Various bug fixes for ext4. The most important is a fix for the new
extent cache's slab shrinker which can cause significant, user-visible
pauses when the system is under memory pressure."
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: enable quotas before orphan cleanup
ext4: don't allow quota mount options when quota feature enabled
ext4: fix a warning from sparse check for ext4_dir_llseek
ext4: convert number of blocks to clusters properly
ext4: fix possible memory leak in ext4_remount()
jbd2: fix ERR_PTR dereference in jbd2__journal_start
ext4: use percpu counter for extent cache count
ext4: optimize ext4_es_shrink()
Diffstat (limited to 'fs/ext4/extents_status.c')
-rw-r--r-- | fs/ext4/extents_status.c | 39 |
1 files changed, 13 insertions, 26 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index f768f4a..95796a1 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -147,11 +147,12 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t end); static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, int nr_to_scan); -static int ext4_es_reclaim_extents_count(struct super_block *sb); int __init ext4_init_es(void) { - ext4_es_cachep = KMEM_CACHE(extent_status, SLAB_RECLAIM_ACCOUNT); + ext4_es_cachep = kmem_cache_create("ext4_extent_status", + sizeof(struct extent_status), + 0, (SLAB_RECLAIM_ACCOUNT), NULL); if (ext4_es_cachep == NULL) return -ENOMEM; return 0; @@ -302,8 +303,10 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, /* * We don't count delayed extent because we never try to reclaim them */ - if (!ext4_es_is_delayed(es)) + if (!ext4_es_is_delayed(es)) { EXT4_I(inode)->i_es_lru_nr++; + percpu_counter_inc(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); + } return es; } @@ -314,6 +317,7 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) if (!ext4_es_is_delayed(es)) { BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0); EXT4_I(inode)->i_es_lru_nr--; + percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); } kmem_cache_free(ext4_es_cachep, es); @@ -674,10 +678,11 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) int nr_to_scan = sc->nr_to_scan; int ret, nr_shrunk = 0; - trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan); + ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); + trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan, ret); if (!nr_to_scan) - return ext4_es_reclaim_extents_count(sbi->s_sb); + return ret; INIT_LIST_HEAD(&scanned); @@ -705,9 +710,10 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) } list_splice_tail(&scanned, &sbi->s_es_lru); spin_unlock(&sbi->s_es_lru_lock); - trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk); - return ext4_es_reclaim_extents_count(sbi->s_sb); + ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); + trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); + return ret; } void ext4_es_register_shrinker(struct super_block *sb) @@ -751,25 +757,6 @@ void ext4_es_lru_del(struct inode *inode) spin_unlock(&sbi->s_es_lru_lock); } -static int ext4_es_reclaim_extents_count(struct super_block *sb) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_inode_info *ei; - struct list_head *cur; - int nr_cached = 0; - - spin_lock(&sbi->s_es_lru_lock); - list_for_each(cur, &sbi->s_es_lru) { - ei = list_entry(cur, struct ext4_inode_info, i_es_lru); - read_lock(&ei->i_es_lock); - nr_cached += ei->i_es_lru_nr; - read_unlock(&ei->i_es_lock); - } - spin_unlock(&sbi->s_es_lru_lock); - trace_ext4_es_reclaim_extents_count(sb, nr_cached); - return nr_cached; -} - static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, int nr_to_scan) { |