mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 03:01:41 +02:00
btrfs: remove locked subpage bitmap
Currently there are two members inside btrfs_folio_state that are related to locked bitmap: - locked sub-bitmap inside btrfs_folio_state::bitmaps[] The enum btrfs_bitmap_nr_locked determines the sub-bitmap. - btrfs_folio_state::nr_locked Which records how many blocks are locked inside the folio. The locked sub-bitmap is a btrfs specific per-block tracking mechanism, which is mostly for async-submission, utilized by compressed writes. The sub-bitmap itself is a super set of nr_locked, as it can provide a more reliable tracking. But the sub-bitmap itself can be pretty large for the incoming huge folio, 2M sized folio for 4K page size, meaning 512 bits for one sub-bitmap. Furthermore, in the long run compression will be reworked to get rid of async-submission completely, there is not much need for a full sub-bitmap to track the locked status. This patch removes the locked sub-bitmap and only relies on @nr_locked atomic to do the tracking. This can also save 64 bytes from btrfs_folio_state::bitmaps[] for a huge folio. This will reduce some safety checks, as previously if a block is not locked, btrfs_folio_end_lock()/btrfs_folio_end_lock_bitmap() will find out that, and skip reducing @nr_locked for that block, and avoid under-flow. But this safety net itself shouldn't be necessary in the first place. If we're unlocking a block that is not locked, it's a bug in the logic, and we should catch it, not silently ignoring it. Thus I believe the removal of the extra safety net should not be a problem. Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
0af37c217e
commit
0e7fff6eca
|
|
@ -224,11 +224,8 @@ static bool btrfs_subpage_end_and_test_lock(const struct btrfs_fs_info *fs_info,
|
|||
struct folio *folio, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_folio_state *bfs = folio_get_private(folio);
|
||||
const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
|
||||
const int nbits = (len >> fs_info->sectorsize_bits);
|
||||
unsigned long flags;
|
||||
unsigned int cleared = 0;
|
||||
int bit = start_bit;
|
||||
bool last;
|
||||
|
||||
btrfs_subpage_assert(fs_info, folio, start, len);
|
||||
|
|
@ -245,15 +242,10 @@ static bool btrfs_subpage_end_and_test_lock(const struct btrfs_fs_info *fs_info,
|
|||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
return true;
|
||||
}
|
||||
|
||||
for_each_set_bit_from(bit, bfs->bitmaps, start_bit + nbits) {
|
||||
clear_bit(bit, bfs->bitmaps);
|
||||
cleared++;
|
||||
}
|
||||
ASSERT(atomic_read(&bfs->nr_locked) >= cleared,
|
||||
"atomic_read(&bfs->nr_locked)=%d cleared=%d",
|
||||
atomic_read(&bfs->nr_locked), cleared);
|
||||
last = atomic_sub_and_test(cleared, &bfs->nr_locked);
|
||||
ASSERT(atomic_read(&bfs->nr_locked) >= nbits,
|
||||
"atomic_read(&bfs->nr_locked)=%d nbits=%d",
|
||||
atomic_read(&bfs->nr_locked), nbits);
|
||||
last = atomic_sub_and_test(nbits, &bfs->nr_locked);
|
||||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
return last;
|
||||
}
|
||||
|
|
@ -309,11 +301,9 @@ void btrfs_folio_end_lock_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
{
|
||||
struct btrfs_folio_state *bfs = folio_get_private(folio);
|
||||
const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
|
||||
const int start_bit = blocks_per_folio * btrfs_bitmap_nr_locked;
|
||||
const unsigned int nbits = bitmap_weight(&bitmap, blocks_per_folio);
|
||||
unsigned long flags;
|
||||
bool last = false;
|
||||
int cleared = 0;
|
||||
int bit;
|
||||
|
||||
if (!btrfs_is_subpage(fs_info, folio)) {
|
||||
folio_unlock(folio);
|
||||
|
|
@ -327,14 +317,10 @@ void btrfs_folio_end_lock_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
}
|
||||
|
||||
spin_lock_irqsave(&bfs->lock, flags);
|
||||
for_each_set_bit(bit, &bitmap, blocks_per_folio) {
|
||||
if (test_and_clear_bit(bit + start_bit, bfs->bitmaps))
|
||||
cleared++;
|
||||
}
|
||||
ASSERT(atomic_read(&bfs->nr_locked) >= cleared,
|
||||
"atomic_read(&bfs->nr_locked)=%d cleared=%d",
|
||||
atomic_read(&bfs->nr_locked), cleared);
|
||||
last = atomic_sub_and_test(cleared, &bfs->nr_locked);
|
||||
ASSERT(atomic_read(&bfs->nr_locked) >= nbits,
|
||||
"atomic_read(&bfs->nr_locked)=%d nbits=%d",
|
||||
atomic_read(&bfs->nr_locked), nbits);
|
||||
last = atomic_sub_and_test(nbits, &bfs->nr_locked);
|
||||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
if (last)
|
||||
folio_unlock(folio);
|
||||
|
|
@ -696,7 +682,6 @@ void btrfs_folio_set_lock(const struct btrfs_fs_info *fs_info,
|
|||
{
|
||||
struct btrfs_folio_state *bfs;
|
||||
unsigned long flags;
|
||||
unsigned int start_bit;
|
||||
unsigned int nbits;
|
||||
int ret;
|
||||
|
||||
|
|
@ -705,15 +690,8 @@ void btrfs_folio_set_lock(const struct btrfs_fs_info *fs_info,
|
|||
return;
|
||||
|
||||
bfs = folio_get_private(folio);
|
||||
start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
|
||||
nbits = len >> fs_info->sectorsize_bits;
|
||||
spin_lock_irqsave(&bfs->lock, flags);
|
||||
/* Target range should not yet be locked. */
|
||||
if (unlikely(!bitmap_test_range_all_zero(bfs->bitmaps, start_bit, nbits))) {
|
||||
SUBPAGE_DUMP_BITMAP(fs_info, folio, locked, start, len);
|
||||
ASSERT(bitmap_test_range_all_zero(bfs->bitmaps, start_bit, nbits));
|
||||
}
|
||||
bitmap_set(bfs->bitmaps, start_bit, nbits);
|
||||
ret = atomic_add_return(nbits, &bfs->nr_locked);
|
||||
ASSERT(ret <= btrfs_blocks_per_folio(fs_info, folio));
|
||||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
|
|
@ -750,7 +728,6 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
unsigned long dirty_bitmap;
|
||||
unsigned long writeback_bitmap;
|
||||
unsigned long ordered_bitmap;
|
||||
unsigned long locked_bitmap;
|
||||
unsigned long flags;
|
||||
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
|
|
@ -762,16 +739,14 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
GET_SUBPAGE_BITMAP(fs_info, folio, dirty, &dirty_bitmap);
|
||||
GET_SUBPAGE_BITMAP(fs_info, folio, writeback, &writeback_bitmap);
|
||||
GET_SUBPAGE_BITMAP(fs_info, folio, ordered, &ordered_bitmap);
|
||||
GET_SUBPAGE_BITMAP(fs_info, folio, locked, &locked_bitmap);
|
||||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
|
||||
dump_page(folio_page(folio, 0), "btrfs folio state dump");
|
||||
btrfs_warn(fs_info,
|
||||
"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl locked=%*pbl writeback=%*pbl ordered=%*pbl",
|
||||
"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl writeback=%*pbl ordered=%*pbl",
|
||||
start, len, folio_pos(folio),
|
||||
blocks_per_folio, &uptodate_bitmap,
|
||||
blocks_per_folio, &dirty_bitmap,
|
||||
blocks_per_folio, &locked_bitmap,
|
||||
blocks_per_folio, &writeback_bitmap,
|
||||
blocks_per_folio, &ordered_bitmap);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,16 +45,6 @@ enum {
|
|||
*/
|
||||
btrfs_bitmap_nr_ordered,
|
||||
|
||||
/*
|
||||
* The locked bit is for async delalloc range (compression), currently
|
||||
* async extent is queued with the range locked, until the compression
|
||||
* is done.
|
||||
* So an async extent can unlock the range at any random timing.
|
||||
*
|
||||
* This will need a rework on the async extent lifespan (mark writeback
|
||||
* and do compression) before deprecating this flag.
|
||||
*/
|
||||
btrfs_bitmap_nr_locked,
|
||||
btrfs_bitmap_nr_max
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user