diff mbox series

btrfs: scrub: avoid unnecessary extent tree search for striped profiles

Message ID 88abe1beac119b714a62f5e622c673f418afede2.1692083778.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: scrub: avoid unnecessary extent tree search for striped profiles | expand

Commit Message

Qu Wenruo Aug. 15, 2023, 7:16 a.m. UTC
[PROBLEM]
Since commit 8557635ed2b0 ("btrfs: scrub: introduce dedicated helper to
scrub simple-stripe based range"), the scrub speed of striped profiles
(RAID0/RAID10/RAID5/RAID6) are degraded, if the block group is mostly
empty or fragmented.

[CAUSE]
In scrub_simple_stripe(), which is the responsible for RAID0/RAID10
profiles, we just call scrub_simple_mirror() and increase our
@cur_logical and @cur_physical.

The problem is, if there are no more extents inside the block group, or
the next extent is far away from our current logical, we would call
scrub_simple_mirror() for the empty ranges again and again, until we
reach the next next.

This is completely a waste of CPU time, thus it greatly degrade the
scrub performance for stripped profiles.

This is also affecting RAID56, as we rely on scrub_simple_mirror() for
data stripes of RAID56.

[FIX]
- Introduce scrub_ctx::found_next to record the next extent we found
  This member would be updated by find_first_extent_item() calls inside
  scrub_find_fill_first_stripe().

- Skip to the next stripe directly in scrub_simple_stripe()
  If we detect sctx->found_next is beyond our current stripe, we just
  skip to the full stripe which covers the target bytenr.

- Skip to the next full stripe covering sctx->found_next
  Unlike RAID0/RAID10, we can not easily skip to the next stripe due to
  rotation.
  But we can still skip to the next full stripe, which can still save us
  a lot of time.

Fixes: 8557635ed2b0 ("btrfs: scrub: introduce dedicated helper to scrub simple-stripe based range")
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
This patch is based on the scrub_testing branch (which is misc-next +
scrub performance fixes).

Thus there would be quite some conflicts for stable branches and would
need manual backport.
---
 fs/btrfs/scrub.c | 96 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 82 insertions(+), 14 deletions(-)

Comments

kernel test robot Aug. 15, 2023, 9:56 a.m. UTC | #1
Hi Qu,

kernel test robot noticed the following build errors:

[auto build test ERROR on kdave/for-next]
[cannot apply to linus/master v6.5-rc6 next-20230809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qu-Wenruo/btrfs-scrub-avoid-unnecessary-extent-tree-search-for-striped-profiles/20230815-151842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link:    https://lore.kernel.org/r/88abe1beac119b714a62f5e622c673f418afede2.1692083778.git.wqu%40suse.com
patch subject: [PATCH] btrfs: scrub: avoid unnecessary extent tree search for striped profiles
config: arm-randconfig-r046-20230815 (https://download.01.org/0day-ci/archive/20230815/202308151711.XfmQjlrj-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230815/202308151711.XfmQjlrj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308151711.XfmQjlrj-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

WARNING: modpost: missing MODULE_DESCRIPTION() in vmlinux.o
WARNING: modpost: missing MODULE_DESCRIPTION() in kernel/scftorture.o
WARNING: modpost: missing MODULE_DESCRIPTION() in mm/dmapool_test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp775.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp857.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp869.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp949.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp1251.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_iso8859-3.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_iso8859-6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_cp1255.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/nls_iso8859-9.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-celtic.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-croatian.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-iceland.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-inuit.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-romanian.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-roman.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/nls/mac-turkish.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/binfmt_misc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/binfmt_script.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/autofs/autofs4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in fs/btrfs/btrfs.o
WARNING: modpost: missing MODULE_DESCRIPTION() in crypto/xor.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/math/prime_numbers.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test-string_helpers.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_hexdump.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_min_heap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_module.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_rhashtable.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_static_keys.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_static_key_base.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_xarray.o
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/test_memcat_p.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/bus/vexpress-config.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/video/backlight/rt4831-backlight.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/video/fbdev/goldfishfb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/char/hw_random/omap-rng.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/char/hw_random/omap3-rom-rng.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/char/hw_random/nomadik-rng.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/char/ppdev.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/bridge/lontium-lt9611.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/bridge/lontium-lt9611uxc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/bridge/sil-sii8620.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/bridge/sii9234.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/drm_panel_orientation_quirks.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/base/regmap/regmap-slimbus.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/misc/open-dice.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mfd/arizona.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mfd/vexpress-sysreg.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/scsi/scsi_common.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvme/host/nvme-core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvme/host/nvme-fabrics.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvme/target/nvme-loop.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/phy/phy-am335x-control.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/phy/phy-am335x.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/host/xhci-pci-renesas.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/storage/uas.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/misc/yurex.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/mmc_core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/pwrseq_simple.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/devfreq/governor_simpleondemand.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/devfreq/governor_performance.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/parport/parport.o
>> ERROR: modpost: "__aeabi_uldivmod" [fs/btrfs/btrfs.ko] undefined!
kernel test robot Aug. 15, 2023, 10:06 a.m. UTC | #2
Hi Qu,

kernel test robot noticed the following build errors:

[auto build test ERROR on kdave/for-next]
[cannot apply to linus/master v6.5-rc6 next-20230809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qu-Wenruo/btrfs-scrub-avoid-unnecessary-extent-tree-search-for-striped-profiles/20230815-151842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link:    https://lore.kernel.org/r/88abe1beac119b714a62f5e622c673f418afede2.1692083778.git.wqu%40suse.com
patch subject: [PATCH] btrfs: scrub: avoid unnecessary extent tree search for striped profiles
config: riscv-randconfig-r021-20230815 (https://download.01.org/0day-ci/archive/20230815/202308151705.NQScDZfJ-lkp@intel.com/config)
compiler: riscv32-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230815/202308151705.NQScDZfJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308151705.NQScDZfJ-lkp@intel.com/

All errors (new ones prefixed by >>):

   riscv32-linux-ld: fs/btrfs/scrub.o: in function `.L0 ':
>> fs/btrfs/scrub.c:2186: undefined reference to `__udivdi3'
>> riscv32-linux-ld: fs/btrfs/scrub.c:2354: undefined reference to `__umoddi3'


vim +2186 fs/btrfs/scrub.c

8557635ed2b04b Qu Wenruo       2022-03-11  2172  
d9d181c1ba7aa0 Stefan Behrens  2012-11-02  2173  static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2174  					   struct btrfs_block_group *bg,
bc88b486d54b2a Qu Wenruo       2022-05-13  2175  					   struct extent_map *em,
a36cf8b8933e4a Stefan Behrens  2012-11-02  2176  					   struct btrfs_device *scrub_dev,
bc88b486d54b2a Qu Wenruo       2022-05-13  2177  					   int stripe_index)
a2de733c78fa7a Arne Jansen     2011-03-08  2178  {
fb456252d3d9c0 Jeff Mahoney    2016-06-22  2179  	struct btrfs_fs_info *fs_info = sctx->fs_info;
bc88b486d54b2a Qu Wenruo       2022-05-13  2180  	struct map_lookup *map = em->map_lookup;
09022b14fafc86 Qu Wenruo       2022-03-11  2181  	const u64 profile = map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK;
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2182  	const u64 chunk_logical = bg->start;
a2de733c78fa7a Arne Jansen     2011-03-08  2183  	int ret;
8eb3dd17eadd21 Qu Wenruo       2023-04-06  2184  	int ret2;
1194a82481d8f3 Qu Wenruo       2022-03-11  2185  	u64 physical = map->stripes[stripe_index].physical;
bc88b486d54b2a Qu Wenruo       2022-05-13 @2186  	const u64 dev_stripe_len = btrfs_calc_stripe_length(em);
bc88b486d54b2a Qu Wenruo       2022-05-13  2187  	const u64 physical_end = physical + dev_stripe_len;
a2de733c78fa7a Arne Jansen     2011-03-08  2188  	u64 logical;
625f1c8dc66d77 Liu Bo          2013-04-27  2189  	u64 logic_end;
18d30ab961497f Qu Wenruo       2022-03-11  2190  	/* The logical increment after finishing one stripe */
5c07c53f2d273b Jiapeng Chong   2022-01-21  2191  	u64 increment;
18d30ab961497f Qu Wenruo       2022-03-11  2192  	/* Offset inside the chunk */
a2de733c78fa7a Arne Jansen     2011-03-08  2193  	u64 offset;
5a6ac9eacb4914 Miao Xie        2014-11-06  2194  	u64 stripe_logical;
3b080b2564287b Wang Shilong    2014-04-01  2195  	int stop_loop = 0;
53b381b3abeb86 David Woodhouse 2013-01-29  2196  
303c4c1391fc98 Qu Wenruo       2023-08-03  2197  	/* Extent_path should be probably released. */
303c4c1391fc98 Qu Wenruo       2023-08-03  2198  	ASSERT(sctx->extent_path.nodes[0] == NULL);
a64bd62aaf1157 Qu Wenruo       2023-08-15  2199  	sctx->found_next = chunk_logical;
303c4c1391fc98 Qu Wenruo       2023-08-03  2200  
cb7ab02156e4ba Wang Shilong    2013-12-04  2201  	scrub_blocked_if_needed(fs_info);
a2de733c78fa7a Arne Jansen     2011-03-08  2202  
de17addce7a20d Naohiro Aota    2021-02-04  2203  	if (sctx->is_dev_replace &&
de17addce7a20d Naohiro Aota    2021-02-04  2204  	    btrfs_dev_is_sequential(sctx->wr_tgtdev, physical)) {
de17addce7a20d Naohiro Aota    2021-02-04  2205  		mutex_lock(&sctx->wr_lock);
de17addce7a20d Naohiro Aota    2021-02-04  2206  		sctx->write_pointer = physical;
de17addce7a20d Naohiro Aota    2021-02-04  2207  		mutex_unlock(&sctx->wr_lock);
de17addce7a20d Naohiro Aota    2021-02-04  2208  	}
de17addce7a20d Naohiro Aota    2021-02-04  2209  
1009254bf22a3f Qu Wenruo       2023-03-28  2210  	/* Prepare the extra data stripes used by RAID56. */
1009254bf22a3f Qu Wenruo       2023-03-28  2211  	if (profile & BTRFS_BLOCK_GROUP_RAID56_MASK) {
1009254bf22a3f Qu Wenruo       2023-03-28  2212  		ASSERT(sctx->raid56_data_stripes == NULL);
1009254bf22a3f Qu Wenruo       2023-03-28  2213  
1009254bf22a3f Qu Wenruo       2023-03-28  2214  		sctx->raid56_data_stripes = kcalloc(nr_data_stripes(map),
1009254bf22a3f Qu Wenruo       2023-03-28  2215  						    sizeof(struct scrub_stripe),
1009254bf22a3f Qu Wenruo       2023-03-28  2216  						    GFP_KERNEL);
1009254bf22a3f Qu Wenruo       2023-03-28  2217  		if (!sctx->raid56_data_stripes) {
1009254bf22a3f Qu Wenruo       2023-03-28  2218  			ret = -ENOMEM;
1009254bf22a3f Qu Wenruo       2023-03-28  2219  			goto out;
1009254bf22a3f Qu Wenruo       2023-03-28  2220  		}
1009254bf22a3f Qu Wenruo       2023-03-28  2221  		for (int i = 0; i < nr_data_stripes(map); i++) {
1009254bf22a3f Qu Wenruo       2023-03-28  2222  			ret = init_scrub_stripe(fs_info,
1009254bf22a3f Qu Wenruo       2023-03-28  2223  						&sctx->raid56_data_stripes[i]);
1009254bf22a3f Qu Wenruo       2023-03-28  2224  			if (ret < 0)
1009254bf22a3f Qu Wenruo       2023-03-28  2225  				goto out;
1009254bf22a3f Qu Wenruo       2023-03-28  2226  			sctx->raid56_data_stripes[i].bg = bg;
1009254bf22a3f Qu Wenruo       2023-03-28  2227  			sctx->raid56_data_stripes[i].sctx = sctx;
1009254bf22a3f Qu Wenruo       2023-03-28  2228  		}
1009254bf22a3f Qu Wenruo       2023-03-28  2229  	}
09022b14fafc86 Qu Wenruo       2022-03-11  2230  	/*
09022b14fafc86 Qu Wenruo       2022-03-11  2231  	 * There used to be a big double loop to handle all profiles using the
09022b14fafc86 Qu Wenruo       2022-03-11  2232  	 * same routine, which grows larger and more gross over time.
09022b14fafc86 Qu Wenruo       2022-03-11  2233  	 *
09022b14fafc86 Qu Wenruo       2022-03-11  2234  	 * So here we handle each profile differently, so simpler profiles
09022b14fafc86 Qu Wenruo       2022-03-11  2235  	 * have simpler scrubbing function.
09022b14fafc86 Qu Wenruo       2022-03-11  2236  	 */
09022b14fafc86 Qu Wenruo       2022-03-11  2237  	if (!(profile & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10 |
09022b14fafc86 Qu Wenruo       2022-03-11  2238  			 BTRFS_BLOCK_GROUP_RAID56_MASK))) {
09022b14fafc86 Qu Wenruo       2022-03-11  2239  		/*
09022b14fafc86 Qu Wenruo       2022-03-11  2240  		 * Above check rules out all complex profile, the remaining
09022b14fafc86 Qu Wenruo       2022-03-11  2241  		 * profiles are SINGLE|DUP|RAID1|RAID1C*, which is simple
09022b14fafc86 Qu Wenruo       2022-03-11  2242  		 * mirrored duplication without stripe.
09022b14fafc86 Qu Wenruo       2022-03-11  2243  		 *
09022b14fafc86 Qu Wenruo       2022-03-11  2244  		 * Only @physical and @mirror_num needs to calculated using
09022b14fafc86 Qu Wenruo       2022-03-11  2245  		 * @stripe_index.
09022b14fafc86 Qu Wenruo       2022-03-11  2246  		 */
6b4d375a81551b Qu Wenruo       2023-01-16  2247  		ret = scrub_simple_mirror(sctx, bg, map, bg->start, bg->length,
6b4d375a81551b Qu Wenruo       2023-01-16  2248  				scrub_dev, map->stripes[stripe_index].physical,
09022b14fafc86 Qu Wenruo       2022-03-11  2249  				stripe_index + 1);
e430c4287ebdaf Qu Wenruo       2022-03-11  2250  		offset = 0;
09022b14fafc86 Qu Wenruo       2022-03-11  2251  		goto out;
09022b14fafc86 Qu Wenruo       2022-03-11  2252  	}
8557635ed2b04b Qu Wenruo       2022-03-11  2253  	if (profile & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
6b4d375a81551b Qu Wenruo       2023-01-16  2254  		ret = scrub_simple_stripe(sctx, bg, map, scrub_dev, stripe_index);
cb091225a53800 Qu Wenruo       2023-06-22  2255  		offset = btrfs_stripe_nr_to_offset(stripe_index / map->sub_stripes);
8557635ed2b04b Qu Wenruo       2022-03-11  2256  		goto out;
8557635ed2b04b Qu Wenruo       2022-03-11  2257  	}
8557635ed2b04b Qu Wenruo       2022-03-11  2258  
8557635ed2b04b Qu Wenruo       2022-03-11  2259  	/* Only RAID56 goes through the old code */
8557635ed2b04b Qu Wenruo       2022-03-11  2260  	ASSERT(map->type & BTRFS_BLOCK_GROUP_RAID56_MASK);
a2de733c78fa7a Arne Jansen     2011-03-08  2261  	ret = 0;
e430c4287ebdaf Qu Wenruo       2022-03-11  2262  
e430c4287ebdaf Qu Wenruo       2022-03-11  2263  	/* Calculate the logical end of the stripe */
e430c4287ebdaf Qu Wenruo       2022-03-11  2264  	get_raid56_logic_offset(physical_end, stripe_index,
e430c4287ebdaf Qu Wenruo       2022-03-11  2265  				map, &logic_end, NULL);
e430c4287ebdaf Qu Wenruo       2022-03-11  2266  	logic_end += chunk_logical;
e430c4287ebdaf Qu Wenruo       2022-03-11  2267  
e430c4287ebdaf Qu Wenruo       2022-03-11  2268  	/* Initialize @offset in case we need to go to out: label */
e430c4287ebdaf Qu Wenruo       2022-03-11  2269  	get_raid56_logic_offset(physical, stripe_index, map, &offset, NULL);
cb091225a53800 Qu Wenruo       2023-06-22  2270  	increment = btrfs_stripe_nr_to_offset(nr_data_stripes(map));
e430c4287ebdaf Qu Wenruo       2022-03-11  2271  
a2de733c78fa7a Arne Jansen     2011-03-08  2272  	/*
18d30ab961497f Qu Wenruo       2022-03-11  2273  	 * Due to the rotation, for RAID56 it's better to iterate each stripe
18d30ab961497f Qu Wenruo       2022-03-11  2274  	 * using their physical offset.
a2de733c78fa7a Arne Jansen     2011-03-08  2275  	 */
18d30ab961497f Qu Wenruo       2022-03-11  2276  	while (physical < physical_end) {
a64bd62aaf1157 Qu Wenruo       2023-08-15  2277  		u64 full_stripe_start;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2278  		u32 full_stripe_len = increment;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2279  
18d30ab961497f Qu Wenruo       2022-03-11  2280  		ret = get_raid56_logic_offset(physical, stripe_index, map,
18d30ab961497f Qu Wenruo       2022-03-11  2281  					      &logical, &stripe_logical);
a64bd62aaf1157 Qu Wenruo       2023-08-15  2282  		full_stripe_start = rounddown(logical, full_stripe_len) +
a64bd62aaf1157 Qu Wenruo       2023-08-15  2283  				    chunk_logical;
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2284  		logical += chunk_logical;
f2f66a2f886383 Zhao Lei        2015-07-21  2285  		if (ret) {
7955323bdcab30 Zhao Lei        2015-08-18  2286  			/* it is parity strip */
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2287  			stripe_logical += chunk_logical;
1009254bf22a3f Qu Wenruo       2023-03-28  2288  			ret = scrub_raid56_parity_stripe(sctx, scrub_dev, bg,
1009254bf22a3f Qu Wenruo       2023-03-28  2289  							 map, stripe_logical);
f2f66a2f886383 Zhao Lei        2015-07-21  2290  			if (ret)
f2f66a2f886383 Zhao Lei        2015-07-21  2291  				goto out;
d7cad2389560f3 Zhao Lei        2015-07-22  2292  			goto next;
89490303a42942 Filipe Manana   2020-05-08  2293  		}
625f1c8dc66d77 Liu Bo          2013-04-27  2294  
3b080b2564287b Wang Shilong    2014-04-01  2295  		/*
18d30ab961497f Qu Wenruo       2022-03-11  2296  		 * Now we're at a data stripe, scrub each extents in the range.
18d30ab961497f Qu Wenruo       2022-03-11  2297  		 *
18d30ab961497f Qu Wenruo       2022-03-11  2298  		 * At this stage, if we ignore the repair part, inside each data
18d30ab961497f Qu Wenruo       2022-03-11  2299  		 * stripe it is no different than SINGLE profile.
18d30ab961497f Qu Wenruo       2022-03-11  2300  		 * We can reuse scrub_simple_mirror() here, as the repair part
18d30ab961497f Qu Wenruo       2022-03-11  2301  		 * is still based on @mirror_num.
3b080b2564287b Wang Shilong    2014-04-01  2302  		 */
6b4d375a81551b Qu Wenruo       2023-01-16  2303  		ret = scrub_simple_mirror(sctx, bg, map, logical, BTRFS_STRIPE_LEN,
18d30ab961497f Qu Wenruo       2022-03-11  2304  					  scrub_dev, physical, 1);
18d30ab961497f Qu Wenruo       2022-03-11  2305  		if (ret < 0)
5a6ac9eacb4914 Miao Xie        2014-11-06  2306  			goto out;
a2de733c78fa7a Arne Jansen     2011-03-08  2307  next:
a64bd62aaf1157 Qu Wenruo       2023-08-15  2308  		/* No more extent in the block group. */
a64bd62aaf1157 Qu Wenruo       2023-08-15  2309  		if (sctx->found_next >= bg->start + bg->length) {
a64bd62aaf1157 Qu Wenruo       2023-08-15  2310  			spin_lock(&sctx->stat_lock);
a64bd62aaf1157 Qu Wenruo       2023-08-15  2311  			sctx->stat.last_physical = physical_end;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2312  			spin_unlock(&sctx->stat_lock);
a64bd62aaf1157 Qu Wenruo       2023-08-15  2313  			goto out;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2314  		}
a64bd62aaf1157 Qu Wenruo       2023-08-15  2315  
a64bd62aaf1157 Qu Wenruo       2023-08-15  2316  		if (sctx->found_next >= full_stripe_start + full_stripe_len) {
a64bd62aaf1157 Qu Wenruo       2023-08-15  2317  			unsigned int stripes_skipped;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2318  
a64bd62aaf1157 Qu Wenruo       2023-08-15  2319  			stripes_skipped = div_u64(sctx->found_next - full_stripe_start,
a64bd62aaf1157 Qu Wenruo       2023-08-15  2320  						  full_stripe_len);
a64bd62aaf1157 Qu Wenruo       2023-08-15  2321  			if (stripes_skipped == 0)
a64bd62aaf1157 Qu Wenruo       2023-08-15  2322  				stripes_skipped = 1;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2323  			logical += increment * stripes_skipped;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2324  			physical += BTRFS_STRIPE_LEN * stripes_skipped;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2325  		} else {
a2de733c78fa7a Arne Jansen     2011-03-08  2326  			logical += increment;
a97699d1d61071 Qu Wenruo       2023-02-17  2327  			physical += BTRFS_STRIPE_LEN;
a64bd62aaf1157 Qu Wenruo       2023-08-15  2328  		}
a64bd62aaf1157 Qu Wenruo       2023-08-15  2329  
d9d181c1ba7aa0 Stefan Behrens  2012-11-02  2330  		spin_lock(&sctx->stat_lock);
625f1c8dc66d77 Liu Bo          2013-04-27  2331  		if (stop_loop)
bc88b486d54b2a Qu Wenruo       2022-05-13  2332  			sctx->stat.last_physical =
bc88b486d54b2a Qu Wenruo       2022-05-13  2333  				map->stripes[stripe_index].physical + dev_stripe_len;
625f1c8dc66d77 Liu Bo          2013-04-27  2334  		else
d9d181c1ba7aa0 Stefan Behrens  2012-11-02  2335  			sctx->stat.last_physical = physical;
d9d181c1ba7aa0 Stefan Behrens  2012-11-02  2336  		spin_unlock(&sctx->stat_lock);
625f1c8dc66d77 Liu Bo          2013-04-27  2337  		if (stop_loop)
625f1c8dc66d77 Liu Bo          2013-04-27  2338  			break;
a2de733c78fa7a Arne Jansen     2011-03-08  2339  	}
ff023aac31198e Stefan Behrens  2012-11-06  2340  out:
8eb3dd17eadd21 Qu Wenruo       2023-04-06  2341  	ret2 = flush_scrub_stripes(sctx);
b50f2d048ecf15 Qu Wenruo       2023-06-14  2342  	if (!ret)
8eb3dd17eadd21 Qu Wenruo       2023-04-06  2343  		ret = ret2;
303c4c1391fc98 Qu Wenruo       2023-08-03  2344  	btrfs_release_path(&sctx->extent_path);
5c3d78f9a5e26b Qu Wenruo       2023-08-03  2345  	btrfs_release_path(&sctx->csum_path);
303c4c1391fc98 Qu Wenruo       2023-08-03  2346  
1009254bf22a3f Qu Wenruo       2023-03-28  2347  	if (sctx->raid56_data_stripes) {
1009254bf22a3f Qu Wenruo       2023-03-28  2348  		for (int i = 0; i < nr_data_stripes(map); i++)
1009254bf22a3f Qu Wenruo       2023-03-28  2349  			release_scrub_stripe(&sctx->raid56_data_stripes[i]);
1009254bf22a3f Qu Wenruo       2023-03-28  2350  		kfree(sctx->raid56_data_stripes);
1009254bf22a3f Qu Wenruo       2023-03-28  2351  		sctx->raid56_data_stripes = NULL;
1009254bf22a3f Qu Wenruo       2023-03-28  2352  	}
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2353  
7db1c5d14dcd52 Naohiro Aota    2021-02-04 @2354  	if (sctx->is_dev_replace && ret >= 0) {
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2355  		int ret2;
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2356  
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2357  		ret2 = sync_write_pointer_for_zoned(sctx,
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2358  				chunk_logical + offset,
2ae8ae3d3def4c Qu Wenruo       2021-12-15  2359  				map->stripes[stripe_index].physical,
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2360  				physical_end);
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2361  		if (ret2)
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2362  			ret = ret2;
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2363  	}
7db1c5d14dcd52 Naohiro Aota    2021-02-04  2364  
a2de733c78fa7a Arne Jansen     2011-03-08  2365  	return ret < 0 ? ret : 0;
a2de733c78fa7a Arne Jansen     2011-03-08  2366  }
a2de733c78fa7a Arne Jansen     2011-03-08  2367
Johannes Thumshirn Aug. 15, 2023, 10:15 a.m. UTC | #3
On 15.08.23 09:17, Qu Wenruo wrote:
> +
> +		/* No more extent item. all done. */
> +		if (sctx->found_next >= bg->start + bg->length) {
> +			sctx->stat.last_physical = orig_physical +
> +				bg->length / (map->num_stripes / map->sub_stripes);
> +			return 0;
> +		}

bg->length is a u64 so you'll need div_u64() here as well.
kernel test robot Aug. 15, 2023, 10:17 a.m. UTC | #4
Hi Qu,

kernel test robot noticed the following build errors:

[auto build test ERROR on kdave/for-next]
[cannot apply to linus/master v6.5-rc6 next-20230809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qu-Wenruo/btrfs-scrub-avoid-unnecessary-extent-tree-search-for-striped-profiles/20230815-151842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link:    https://lore.kernel.org/r/88abe1beac119b714a62f5e622c673f418afede2.1692083778.git.wqu%40suse.com
patch subject: [PATCH] btrfs: scrub: avoid unnecessary extent tree search for striped profiles
config: microblaze-randconfig-r023-20230815 (https://download.01.org/0day-ci/archive/20230815/202308151856.hgpwaE7D-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230815/202308151856.hgpwaE7D-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308151856.hgpwaE7D-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-purpletv.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-pv951.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-rc6-mce.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-real-audio-220-32-keys.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-reddo.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-snapstream-firefly.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-streamzap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-su3000.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tanix-tx3mini.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tanix-tx5max.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tbs-nec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-technisat-ts35.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-technisat-usb2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-terratec-cinergy-xs.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-terratec-slim-2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-terratec-slim.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tevii-nec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tivo.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-total-media-in-hand-02.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-total-media-in-hand.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-trekstor.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-tt-1500.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-twinhan1027.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-vega-s9x.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-videomate-m1f.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-videomate-s350.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-videomate-tv-pvr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-videostrong-kii-pro.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-wetek-hub.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-wetek-play2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-winfast.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-x96max.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-xbox-360.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-xbox-dvd.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/keymaps/rc-zx-irdec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/rc/rc-core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/host/tmio_mmc_core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/host/renesas_sdhi_core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/mmc_core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/pwrseq_simple.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/pwrseq_emmc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/sdio_uart.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-bootrom.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-loopback.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-audio-manager.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mailbox/mtk-cmdq-mailbox.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/devfreq/governor_performance.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/devfreq/governor_userspace.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hwtracing/intel_th/intel_th_msu_sink.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_pruss.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/pcmcia/pcmcia_rsrc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/greybus/greybus.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/greybus/gb-es2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/iio/adc/ingenic-adc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/iio/buffer/kfifo_buf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-hub.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-aspeed.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-ast-cf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/core/snd-pcm-dmaengine.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/drivers/snd-pcmtest.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/codecs/snd-soc-sigmadsp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/codecs/snd-soc-wm-adsp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/amd/snd-acp-config.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/xilinx/snd-soc-xlnx-i2s.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/xilinx/snd-soc-xlnx-formatter-pcm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/ac97_bus.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/802/stp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/act_gate.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_htb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_hfsc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_red.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_prio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_plug.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_ets.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_choke.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/cls_u32.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netlink/netlink_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ip_gre.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/udp_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/raw_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/xfrm/xfrm_user.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/ah6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/xfrm6_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/sit.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/8021q/8021q.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/caif/chnl_net.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/vmw_vsock/vsock_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/bridge/bridge.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ieee802154/6lowpan/ieee802154_6lowpan.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ieee802154/ieee802154_socket.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/nfc/nci/nci.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/nfc/nfc_digital.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/hsr/hsr.o
>> ERROR: modpost: "__umoddi3" [fs/btrfs/btrfs.ko] undefined!
>> ERROR: modpost: "__udivdi3" [fs/btrfs/btrfs.ko] undefined!
Qu Wenruo Aug. 15, 2023, 10:43 a.m. UTC | #5
On 2023/8/15 18:15, Johannes Thumshirn wrote:
> On 15.08.23 09:17, Qu Wenruo wrote:
>> +
>> +		/* No more extent item. all done. */
>> +		if (sctx->found_next >= bg->start + bg->length) {
>> +			sctx->stat.last_physical = orig_physical +
>> +				bg->length / (map->num_stripes / map->sub_stripes);
>> +			return 0;
>> +		}
>
> bg->length is a u64 so you'll need div_u64() here as well.
>
Yep, let me check if I have any variable at hand just like the
@physical_end one in the RAID56 realm.

Thanks,
Qu
diff mbox series

Patch

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 6d83f5ed1d93..c3f576537114 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -219,6 +219,14 @@  struct scrub_ctx {
 	 * doing the wakeup() call.
 	 */
 	refcount_t              refs;
+
+	/*
+	 * Indicate the next logical that is covered by an extent.
+	 *
+	 * This is for striped profiles to skip stripes which doesn't have
+	 * any extent.
+	 */
+	u64			found_next;
 };
 
 struct scrub_warning {
@@ -1365,7 +1373,8 @@  static int compare_extent_item_range(struct btrfs_path *path,
  */
 static int find_first_extent_item(struct btrfs_root *extent_root,
 				  struct btrfs_path *path,
-				  u64 search_start, u64 search_len)
+				  u64 search_start, u64 search_len,
+				  u64 *found_next_ret)
 {
 	struct btrfs_fs_info *fs_info = extent_root->fs_info;
 	struct btrfs_key key;
@@ -1401,8 +1410,11 @@  static int find_first_extent_item(struct btrfs_root *extent_root,
 search_forward:
 	while (true) {
 		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
-		if (key.objectid >= search_start + search_len)
+		if (key.objectid >= search_start + search_len) {
+			if (found_next_ret)
+				*found_next_ret = key.objectid;
 			break;
+		}
 		if (key.type != BTRFS_METADATA_ITEM_KEY &&
 		    key.type != BTRFS_EXTENT_ITEM_KEY)
 			goto next;
@@ -1410,13 +1422,18 @@  static int find_first_extent_item(struct btrfs_root *extent_root,
 		ret = compare_extent_item_range(path, search_start, search_len);
 		if (ret == 0)
 			return ret;
-		if (ret > 0)
+		if (ret > 0) {
+			if (found_next_ret)
+				*found_next_ret = key.objectid;
 			break;
+		}
 next:
 		path->slots[0]++;
 		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
 			ret = btrfs_next_leaf(extent_root, path);
 			if (ret) {
+				if (ret > 0 && found_next_ret)
+					*found_next_ret = U64_MAX;
 				/* Either no more item or fatal error */
 				btrfs_release_path(path);
 				return ret;
@@ -1518,7 +1535,8 @@  static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
 					struct btrfs_device *dev, u64 physical,
 					int mirror_num, u64 logical_start,
 					u32 logical_len,
-					struct scrub_stripe *stripe)
+					struct scrub_stripe *stripe,
+					u64 *found_next_ret)
 {
 	struct btrfs_fs_info *fs_info = bg->fs_info;
 	struct btrfs_root *extent_root = btrfs_extent_root(fs_info, bg->start);
@@ -1540,7 +1558,7 @@  static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
 	ASSERT(logical_start >= bg->start && logical_end <= bg->start + bg->length);
 
 	ret = find_first_extent_item(extent_root, extent_path, logical_start,
-				     logical_len);
+				     logical_len, found_next_ret);
 	/* Either error or not found. */
 	if (ret)
 		goto out;
@@ -1574,7 +1592,8 @@  static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
 	/* Fill the extent info for the remaining sectors. */
 	while (cur_logical <= stripe_end) {
 		ret = find_first_extent_item(extent_root, extent_path, cur_logical,
-					     stripe_end - cur_logical + 1);
+					     stripe_end - cur_logical + 1,
+					     found_next_ret);
 		if (ret < 0)
 			goto out;
 		if (ret > 0) {
@@ -1809,7 +1828,7 @@  static int queue_scrub_stripe(struct scrub_ctx *sctx, struct btrfs_block_group *
 	scrub_reset_stripe(stripe);
 	ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path,
 			&sctx->csum_path, dev, physical, mirror_num, logical,
-			length, stripe);
+			length, stripe, &sctx->found_next);
 	/* Either >0 as no more extents or <0 for error. */
 	if (ret)
 		return ret;
@@ -1881,7 +1900,7 @@  static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 		ret = scrub_find_fill_first_stripe(bg, &extent_path, &csum_path,
 				map->stripes[stripe_index].dev, physical, 1,
 				full_stripe_start + btrfs_stripe_nr_to_offset(i),
-				BTRFS_STRIPE_LEN, stripe);
+				BTRFS_STRIPE_LEN, stripe, NULL);
 		if (ret < 0)
 			goto out;
 		/*
@@ -2124,10 +2143,33 @@  static int scrub_simple_stripe(struct scrub_ctx *sctx,
 					  mirror_num);
 		if (ret)
 			return ret;
-		/* Skip to next stripe which belongs to the target device */
-		cur_logical += logical_increment;
-		/* For physical offset, we just go to next stripe */
-		cur_physical += BTRFS_STRIPE_LEN;
+
+		/* No more extent item. all done. */
+		if (sctx->found_next >= bg->start + bg->length) {
+			sctx->stat.last_physical = orig_physical +
+				bg->length / (map->num_stripes / map->sub_stripes);
+			return 0;
+		}
+		/*
+		 * The next found extent is already beyond our stripe.
+		 * Skip to the next extent.
+		 */
+		if (sctx->found_next >= cur_logical + BTRFS_STRIPE_LEN) {
+			unsigned int stripes_skipped;
+
+			/* Advance to the next stripe covering sctx->found_next. */
+			stripes_skipped = div_u64(sctx->found_next - cur_logical,
+						  logical_increment);
+			if (stripes_skipped == 0)
+				stripes_skipped = 1;
+			cur_logical += logical_increment * stripes_skipped;
+			cur_physical += BTRFS_STRIPE_LEN * stripes_skipped;
+		} else {
+			/* Skip to next stripe which belongs to the target device */
+			cur_logical += logical_increment;
+			/* For physical offset, we just go to next stripe */
+			cur_physical += BTRFS_STRIPE_LEN;
+		}
 	}
 	return ret;
 }
@@ -2158,6 +2200,7 @@  static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
 
 	/* Extent_path should be probably released. */
 	ASSERT(sctx->extent_path.nodes[0] == NULL);
+	sctx->found_next = chunk_logical;
 
 	scrub_blocked_if_needed(fs_info);
 
@@ -2235,8 +2278,13 @@  static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
 	 * using their physical offset.
 	 */
 	while (physical < physical_end) {
+		u64 full_stripe_start;
+		u32 full_stripe_len = increment;
+
 		ret = get_raid56_logic_offset(physical, stripe_index, map,
 					      &logical, &stripe_logical);
+		full_stripe_start = rounddown(logical, full_stripe_len) +
+				    chunk_logical;
 		logical += chunk_logical;
 		if (ret) {
 			/* it is parity strip */
@@ -2261,8 +2309,28 @@  static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
 		if (ret < 0)
 			goto out;
 next:
-		logical += increment;
-		physical += BTRFS_STRIPE_LEN;
+		/* No more extent in the block group. */
+		if (sctx->found_next >= bg->start + bg->length) {
+			spin_lock(&sctx->stat_lock);
+			sctx->stat.last_physical = physical_end;
+			spin_unlock(&sctx->stat_lock);
+			goto out;
+		}
+
+		if (sctx->found_next >= full_stripe_start + full_stripe_len) {
+			unsigned int stripes_skipped;
+
+			stripes_skipped = div_u64(sctx->found_next - full_stripe_start,
+						  full_stripe_len);
+			if (stripes_skipped == 0)
+				stripes_skipped = 1;
+			logical += increment * stripes_skipped;
+			physical += BTRFS_STRIPE_LEN * stripes_skipped;
+		} else {
+			logical += increment;
+			physical += BTRFS_STRIPE_LEN;
+		}
+
 		spin_lock(&sctx->stat_lock);
 		if (stop_loop)
 			sctx->stat.last_physical =