@@ -2781,6 +2781,37 @@ ext4_group_t ext4_mb_prefetch(struct super_block *sb, ext4_group_t group,
2781
2781
return group ;
2782
2782
}
2783
2783
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
+
2784
2815
/*
2785
2816
* Prefetching reads the block bitmap into the buffer cache; but we
2786
2817
* 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,
2817
2848
static noinline_for_stack int
2818
2849
ext4_mb_regular_allocator (struct ext4_allocation_context * ac )
2819
2850
{
2820
- ext4_group_t prefetch_grp = 0 , ngroups , group , i ;
2851
+ ext4_group_t ngroups , group , i ;
2821
2852
enum criteria new_cr , cr = CR_GOAL_LEN_FAST ;
2822
2853
int err = 0 , first_err = 0 ;
2823
- unsigned int nr = 0 , prefetch_ios = 0 ;
2824
2854
struct ext4_sb_info * sbi ;
2825
2855
struct super_block * sb ;
2826
2856
struct ext4_buddy e4b ;
@@ -2881,6 +2911,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
2881
2911
cr = CR_POWER2_ALIGNED ;
2882
2912
2883
2913
ac -> ac_e4b = & e4b ;
2914
+ ac -> ac_prefetch_ios = 0 ;
2884
2915
repeat :
2885
2916
for (; cr < EXT4_MB_NUM_CRS && ac -> ac_status == AC_STATUS_CONTINUE ; cr ++ ) {
2886
2917
ac -> ac_criteria = cr ;
@@ -2890,8 +2921,8 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
2890
2921
*/
2891
2922
group = ac -> ac_g_ex .fe_group ;
2892
2923
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 ;
2895
2926
2896
2927
for (i = 0 , new_cr = cr ; i < ngroups ; i ++ ,
2897
2928
ext4_mb_choose_next_group (ac , & new_cr , & group , ngroups )) {
@@ -2903,24 +2934,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
2903
2934
goto repeat ;
2904
2935
}
2905
2936
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 );
2924
2938
2925
2939
/* prevent unnecessary buddy loading. */
2926
2940
if (cr < CR_ANY_FREE &&
@@ -3018,8 +3032,8 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
3018
3032
ac -> ac_b_ex .fe_len , ac -> ac_o_ex .fe_len , ac -> ac_status ,
3019
3033
ac -> ac_flags , cr , err );
3020
3034
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 );
3023
3037
3024
3038
return err ;
3025
3039
}
0 commit comments