Commit 246307745c406379996e6ed6411f0e20f1ce1449
1 parent
8e919d1304
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ext4: optimize ext4_es_shrink()
When the system is under memory pressure, ext4_es_srhink() will get called very often. So optimize returning the number of items in the file system's extent status cache by keeping a per-filesystem count, instead of calculating it each time by scanning all of the inodes in the extent status cache. Also rename the slab used for the extent status cache to be "ext4_extent_status" so it's obviousl the slab in question is created by ext4. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Zheng Liu <gnehzuil.liu@gmail.com>
Showing 3 changed files with 26 additions and 54 deletions Side-by-side Diff
fs/ext4/ext4.h
fs/ext4/extents_status.c
... | ... | @@ -147,11 +147,12 @@ |
147 | 147 | ext4_lblk_t end); |
148 | 148 | static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, |
149 | 149 | int nr_to_scan); |
150 | -static int ext4_es_reclaim_extents_count(struct super_block *sb); | |
151 | 150 | |
152 | 151 | int __init ext4_init_es(void) |
153 | 152 | { |
154 | - ext4_es_cachep = KMEM_CACHE(extent_status, SLAB_RECLAIM_ACCOUNT); | |
153 | + ext4_es_cachep = kmem_cache_create("ext4_extent_status", | |
154 | + sizeof(struct extent_status), | |
155 | + 0, (SLAB_RECLAIM_ACCOUNT), NULL); | |
155 | 156 | if (ext4_es_cachep == NULL) |
156 | 157 | return -ENOMEM; |
157 | 158 | return 0; |
158 | 159 | |
... | ... | @@ -302,8 +303,10 @@ |
302 | 303 | /* |
303 | 304 | * We don't count delayed extent because we never try to reclaim them |
304 | 305 | */ |
305 | - if (!ext4_es_is_delayed(es)) | |
306 | + if (!ext4_es_is_delayed(es)) { | |
306 | 307 | EXT4_I(inode)->i_es_lru_nr++; |
308 | + atomic_inc(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); | |
309 | + } | |
307 | 310 | |
308 | 311 | return es; |
309 | 312 | } |
... | ... | @@ -314,6 +317,7 @@ |
314 | 317 | if (!ext4_es_is_delayed(es)) { |
315 | 318 | BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0); |
316 | 319 | EXT4_I(inode)->i_es_lru_nr--; |
320 | + atomic_dec(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); | |
317 | 321 | } |
318 | 322 | |
319 | 323 | kmem_cache_free(ext4_es_cachep, es); |
320 | 324 | |
... | ... | @@ -674,10 +678,11 @@ |
674 | 678 | int nr_to_scan = sc->nr_to_scan; |
675 | 679 | int ret, nr_shrunk = 0; |
676 | 680 | |
677 | - trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan); | |
681 | + ret = atomic_read(&sbi->s_extent_cache_cnt); | |
682 | + trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan, ret); | |
678 | 683 | |
679 | 684 | if (!nr_to_scan) |
680 | - return ext4_es_reclaim_extents_count(sbi->s_sb); | |
685 | + return ret; | |
681 | 686 | |
682 | 687 | INIT_LIST_HEAD(&scanned); |
683 | 688 | |
684 | 689 | |
... | ... | @@ -705,9 +710,10 @@ |
705 | 710 | } |
706 | 711 | list_splice_tail(&scanned, &sbi->s_es_lru); |
707 | 712 | spin_unlock(&sbi->s_es_lru_lock); |
708 | - trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk); | |
709 | 713 | |
710 | - return ext4_es_reclaim_extents_count(sbi->s_sb); | |
714 | + ret = atomic_read(&sbi->s_extent_cache_cnt); | |
715 | + trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); | |
716 | + return ret; | |
711 | 717 | } |
712 | 718 | |
713 | 719 | void ext4_es_register_shrinker(struct super_block *sb) |
... | ... | @@ -749,25 +755,6 @@ |
749 | 755 | if (!list_empty(&ei->i_es_lru)) |
750 | 756 | list_del_init(&ei->i_es_lru); |
751 | 757 | spin_unlock(&sbi->s_es_lru_lock); |
752 | -} | |
753 | - | |
754 | -static int ext4_es_reclaim_extents_count(struct super_block *sb) | |
755 | -{ | |
756 | - struct ext4_sb_info *sbi = EXT4_SB(sb); | |
757 | - struct ext4_inode_info *ei; | |
758 | - struct list_head *cur; | |
759 | - int nr_cached = 0; | |
760 | - | |
761 | - spin_lock(&sbi->s_es_lru_lock); | |
762 | - list_for_each(cur, &sbi->s_es_lru) { | |
763 | - ei = list_entry(cur, struct ext4_inode_info, i_es_lru); | |
764 | - read_lock(&ei->i_es_lock); | |
765 | - nr_cached += ei->i_es_lru_nr; | |
766 | - read_unlock(&ei->i_es_lock); | |
767 | - } | |
768 | - spin_unlock(&sbi->s_es_lru_lock); | |
769 | - trace_ext4_es_reclaim_extents_count(sb, nr_cached); | |
770 | - return nr_cached; | |
771 | 758 | } |
772 | 759 | |
773 | 760 | static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, |
include/trace/events/ext4.h
... | ... | @@ -2255,64 +2255,48 @@ |
2255 | 2255 | __entry->found ? __entry->status : 0) |
2256 | 2256 | ); |
2257 | 2257 | |
2258 | -TRACE_EVENT(ext4_es_reclaim_extents_count, | |
2259 | - TP_PROTO(struct super_block *sb, int nr_cached), | |
2260 | - | |
2261 | - TP_ARGS(sb, nr_cached), | |
2262 | - | |
2263 | - TP_STRUCT__entry( | |
2264 | - __field( dev_t, dev ) | |
2265 | - __field( int, nr_cached ) | |
2266 | - ), | |
2267 | - | |
2268 | - TP_fast_assign( | |
2269 | - __entry->dev = sb->s_dev; | |
2270 | - __entry->nr_cached = nr_cached; | |
2271 | - ), | |
2272 | - | |
2273 | - TP_printk("dev %d,%d cached objects nr %d", | |
2274 | - MAJOR(__entry->dev), MINOR(__entry->dev), | |
2275 | - __entry->nr_cached) | |
2276 | -); | |
2277 | - | |
2278 | 2258 | TRACE_EVENT(ext4_es_shrink_enter, |
2279 | - TP_PROTO(struct super_block *sb, int nr_to_scan), | |
2259 | + TP_PROTO(struct super_block *sb, int nr_to_scan, int cache_cnt), | |
2280 | 2260 | |
2281 | - TP_ARGS(sb, nr_to_scan), | |
2261 | + TP_ARGS(sb, nr_to_scan, cache_cnt), | |
2282 | 2262 | |
2283 | 2263 | TP_STRUCT__entry( |
2284 | 2264 | __field( dev_t, dev ) |
2285 | 2265 | __field( int, nr_to_scan ) |
2266 | + __field( int, cache_cnt ) | |
2286 | 2267 | ), |
2287 | 2268 | |
2288 | 2269 | TP_fast_assign( |
2289 | 2270 | __entry->dev = sb->s_dev; |
2290 | 2271 | __entry->nr_to_scan = nr_to_scan; |
2272 | + __entry->cache_cnt = cache_cnt; | |
2291 | 2273 | ), |
2292 | 2274 | |
2293 | - TP_printk("dev %d,%d nr to scan %d", | |
2275 | + TP_printk("dev %d,%d nr_to_scan %d cache_cnt %d", | |
2294 | 2276 | MAJOR(__entry->dev), MINOR(__entry->dev), |
2295 | - __entry->nr_to_scan) | |
2277 | + __entry->nr_to_scan, __entry->cache_cnt) | |
2296 | 2278 | ); |
2297 | 2279 | |
2298 | 2280 | TRACE_EVENT(ext4_es_shrink_exit, |
2299 | - TP_PROTO(struct super_block *sb, int shrunk_nr), | |
2281 | + TP_PROTO(struct super_block *sb, int shrunk_nr, int cache_cnt), | |
2300 | 2282 | |
2301 | - TP_ARGS(sb, shrunk_nr), | |
2283 | + TP_ARGS(sb, shrunk_nr, cache_cnt), | |
2302 | 2284 | |
2303 | 2285 | TP_STRUCT__entry( |
2304 | 2286 | __field( dev_t, dev ) |
2305 | 2287 | __field( int, shrunk_nr ) |
2288 | + __field( int, cache_cnt ) | |
2306 | 2289 | ), |
2307 | 2290 | |
2308 | 2291 | TP_fast_assign( |
2309 | 2292 | __entry->dev = sb->s_dev; |
2310 | 2293 | __entry->shrunk_nr = shrunk_nr; |
2294 | + __entry->cache_cnt = cache_cnt; | |
2311 | 2295 | ), |
2312 | 2296 | |
2313 | - TP_printk("dev %d,%d nr to scan %d", | |
2297 | + TP_printk("dev %d,%d shrunk_nr %d cache_cnt %d", | |
2314 | 2298 | MAJOR(__entry->dev), MINOR(__entry->dev), |
2315 | - __entry->shrunk_nr) | |
2299 | + __entry->shrunk_nr, __entry->cache_cnt) | |
2316 | 2300 | ); |
2317 | 2301 | |
2318 | 2302 | #endif /* _TRACE_EXT4_H */ |