Commit 246307745c406379996e6ed6411f0e20f1ce1449

Authored by Theodore Ts'o
1 parent 8e919d1304

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

... ... @@ -1268,6 +1268,7 @@
1268 1268 atomic_t s_mb_preallocated;
1269 1269 atomic_t s_mb_discarded;
1270 1270 atomic_t s_lock_busy;
  1271 + atomic_t s_extent_cache_cnt;
1271 1272  
1272 1273 /* locality groups */
1273 1274 struct ext4_locality_group __percpu *s_locality_groups;
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 */