[PROBLEM]
The existing scrub code for data extents always limit the block size to
sectorsize.
This causes quite some extra scrub_block being allocated:
(there is a data extent at logical bytenr
298844160, length 64KiB)
alloc_scrub_block: new block: logical=
298844160 physical=
298844160 mirror=1
alloc_scrub_block: new block: logical=
298848256 physical=
298848256 mirror=1
alloc_scrub_block: new block: logical=
298852352 physical=
298852352 mirror=1
alloc_scrub_block: new block: logical=
298856448 physical=
298856448 mirror=1
alloc_scrub_block: new block: logical=
298860544 physical=
298860544 mirror=1
alloc_scrub_block: new block: logical=
298864640 physical=
298864640 mirror=1
alloc_scrub_block: new block: logical=
298868736 physical=
298868736 mirror=1
alloc_scrub_block: new block: logical=
298872832 physical=
298872832 mirror=1
alloc_scrub_block: new block: logical=
298876928 physical=
298876928 mirror=1
alloc_scrub_block: new block: logical=
298881024 physical=
298881024 mirror=1
alloc_scrub_block: new block: logical=
298885120 physical=
298885120 mirror=1
alloc_scrub_block: new block: logical=
298889216 physical=
298889216 mirror=1
alloc_scrub_block: new block: logical=
298893312 physical=
298893312 mirror=1
alloc_scrub_block: new block: logical=
298897408 physical=
298897408 mirror=1
alloc_scrub_block: new block: logical=
298901504 physical=
298901504 mirror=1
alloc_scrub_block: new block: logical=
298905600 physical=
298905600 mirror=1
...
scrub_block_put: free block: logical=
298844160 physical=
298844160 len=4096 mirror=1
scrub_block_put: free block: logical=
298848256 physical=
298848256 len=4096 mirror=1
scrub_block_put: free block: logical=
298852352 physical=
298852352 len=4096 mirror=1
scrub_block_put: free block: logical=
298856448 physical=
298856448 len=4096 mirror=1
scrub_block_put: free block: logical=
298860544 physical=
298860544 len=4096 mirror=1
scrub_block_put: free block: logical=
298864640 physical=
298864640 len=4096 mirror=1
scrub_block_put: free block: logical=
298868736 physical=
298868736 len=4096 mirror=1
scrub_block_put: free block: logical=
298872832 physical=
298872832 len=4096 mirror=1
scrub_block_put: free block: logical=
298876928 physical=
298876928 len=4096 mirror=1
scrub_block_put: free block: logical=
298881024 physical=
298881024 len=4096 mirror=1
scrub_block_put: free block: logical=
298885120 physical=
298885120 len=4096 mirror=1
scrub_block_put: free block: logical=
298889216 physical=
298889216 len=4096 mirror=1
scrub_block_put: free block: logical=
298893312 physical=
298893312 len=4096 mirror=1
scrub_block_put: free block: logical=
298897408 physical=
298897408 len=4096 mirror=1
scrub_block_put: free block: logical=
298901504 physical=
298901504 len=4096 mirror=1
scrub_block_put: free block: logical=
298905600 physical=
298905600 len=4096 mirror=1
This behavior will waste a lot of memory, especially after we have moved
quite some members from scrub_sector to scrub_block.
[FIX]
To reduce the allocation of scrub_block, and to reduce memory usage, use
BTRFS_STRIPE_LEN instead of sectorsize as the block size to scrub data
extents.
This results only one scrub_block to be allocated for above data extent:
alloc_scrub_block: new block: logical=
298844160 physical=
298844160 mirror=1
scrub_block_put: free block: logical=
298844160 physical=
298844160 len=65536 mirror=1
This would greatly reduce the memory usage (even it's just transient)
for larger data extents scrub.
For above example, the memory usage would be:
Old: num_sectors * (sizeof(scrub_block) + sizeof(scrub_sector))
16 * (408 + 96) = 8065
New: sizeof(scrub_block) + num_sectors * sizeof(scrub_sector)
408 + 16 * 96 = 1944
A good reduction of 75.9%.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>