@@ -2781,6 +2781,37 @@ ext4_group_t ext4_mb_prefetch(struct super_block *sb, ext4_group_t group,
27812781 return group ;
27822782}
27832783
2784+ /*
2785+ * Batch reads of the block allocation bitmaps to get
2786+ * multiple READs in flight; limit prefetching at inexpensive
2787+ * CR, otherwise mballoc can spend a lot of time loading
2788+ * imperfect groups
2789+ */
2790+ static void ext4_mb_might_prefetch (struct ext4_allocation_context * ac ,
2791+ ext4_group_t group )
2792+ {
2793+ struct ext4_sb_info * sbi ;
2794+
2795+ if (ac -> ac_prefetch_grp != group )
2796+ return ;
2797+
2798+ sbi = EXT4_SB (ac -> ac_sb );
2799+ if (ext4_mb_cr_expensive (ac -> ac_criteria ) ||
2800+ ac -> ac_prefetch_ios < sbi -> s_mb_prefetch_limit ) {
2801+ unsigned int nr = sbi -> s_mb_prefetch ;
2802+
2803+ if (ext4_has_feature_flex_bg (ac -> ac_sb )) {
2804+ nr = 1 << sbi -> s_log_groups_per_flex ;
2805+ nr -= group & (nr - 1 );
2806+ nr = umin (nr , sbi -> s_mb_prefetch );
2807+ }
2808+
2809+ ac -> ac_prefetch_nr = nr ;
2810+ ac -> ac_prefetch_grp = ext4_mb_prefetch (ac -> ac_sb , group , nr ,
2811+ & ac -> ac_prefetch_ios );
2812+ }
2813+ }
2814+
27842815/*
27852816 * Prefetching reads the block bitmap into the buffer cache; but we
27862817 * need to make sure that the buddy bitmap in the page cache has been
@@ -2817,10 +2848,9 @@ void ext4_mb_prefetch_fini(struct super_block *sb, ext4_group_t group,
28172848static noinline_for_stack int
28182849ext4_mb_regular_allocator (struct ext4_allocation_context * ac )
28192850{
2820- ext4_group_t prefetch_grp = 0 , ngroups , group , i ;
2851+ ext4_group_t ngroups , group , i ;
28212852 enum criteria new_cr , cr = CR_GOAL_LEN_FAST ;
28222853 int err = 0 , first_err = 0 ;
2823- unsigned int nr = 0 , prefetch_ios = 0 ;
28242854 struct ext4_sb_info * sbi ;
28252855 struct super_block * sb ;
28262856 struct ext4_buddy e4b ;
@@ -2881,6 +2911,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
28812911 cr = CR_POWER2_ALIGNED ;
28822912
28832913 ac -> ac_e4b = & e4b ;
2914+ ac -> ac_prefetch_ios = 0 ;
28842915repeat :
28852916 for (; cr < EXT4_MB_NUM_CRS && ac -> ac_status == AC_STATUS_CONTINUE ; cr ++ ) {
28862917 ac -> ac_criteria = cr ;
@@ -2890,8 +2921,8 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
28902921 */
28912922 group = ac -> ac_g_ex .fe_group ;
28922923 ac -> ac_groups_linear_remaining = sbi -> s_mb_max_linear_groups ;
2893- prefetch_grp = group ;
2894- nr = 0 ;
2924+ ac -> ac_prefetch_grp = group ;
2925+ ac -> ac_prefetch_nr = 0 ;
28952926
28962927 for (i = 0 , new_cr = cr ; i < ngroups ; i ++ ,
28972928 ext4_mb_choose_next_group (ac , & new_cr , & group , ngroups )) {
@@ -2903,24 +2934,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
29032934 goto repeat ;
29042935 }
29052936
2906- /*
2907- * Batch reads of the block allocation bitmaps
2908- * to get multiple READs in flight; limit
2909- * prefetching at inexpensive CR, otherwise mballoc
2910- * can spend a lot of time loading imperfect groups
2911- */
2912- if ((prefetch_grp == group ) &&
2913- (ext4_mb_cr_expensive (cr ) ||
2914- prefetch_ios < sbi -> s_mb_prefetch_limit )) {
2915- nr = sbi -> s_mb_prefetch ;
2916- if (ext4_has_feature_flex_bg (sb )) {
2917- nr = 1 << sbi -> s_log_groups_per_flex ;
2918- nr -= group & (nr - 1 );
2919- nr = min (nr , sbi -> s_mb_prefetch );
2920- }
2921- prefetch_grp = ext4_mb_prefetch (sb , group ,
2922- nr , & prefetch_ios );
2923- }
2937+ ext4_mb_might_prefetch (ac , group );
29242938
29252939 /* prevent unnecessary buddy loading. */
29262940 if (cr < CR_ANY_FREE &&
@@ -3018,8 +3032,8 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
30183032 ac -> ac_b_ex .fe_len , ac -> ac_o_ex .fe_len , ac -> ac_status ,
30193033 ac -> ac_flags , cr , err );
30203034
3021- if (nr )
3022- ext4_mb_prefetch_fini (sb , prefetch_grp , nr );
3035+ if (ac -> ac_prefetch_nr )
3036+ ext4_mb_prefetch_fini (sb , ac -> ac_prefetch_grp , ac -> ac_prefetch_nr );
30233037
30243038 return err ;
30253039}
0 commit comments