mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
xfs: add a separate bio_set for spliting GC writes
Allocating the new bio for a split from the same pool as the original
one can deadlock under memory pressure as the origin bio could be the
last one from the mempool.
Add a separate pool for splitting GC write bios to avoid this.
Fixes: 080d01c41d ("xfs: implement zoned garbage collection")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
parent
e2b4a85608
commit
63de191993
|
|
@ -130,6 +130,9 @@ struct xfs_zone_gc_data {
|
|||
/* bioset used to allocate the gc_bios */
|
||||
struct bio_set bio_set;
|
||||
|
||||
/* bioset used when writes need to be split to hardware limits */
|
||||
struct bio_set split_bio_set;
|
||||
|
||||
/*
|
||||
* Scratchpad to buffer GC data, organized as a ring buffer over
|
||||
* discontiguous folios. scratch_head is where the buffer is filled,
|
||||
|
|
@ -221,6 +224,9 @@ xfs_zone_gc_data_alloc(
|
|||
if (bioset_init(&data->bio_set, 16, offsetof(struct xfs_gc_bio, bio),
|
||||
BIOSET_NEED_BVECS))
|
||||
goto out_free_recs;
|
||||
if (bioset_init(&data->split_bio_set, 16,
|
||||
offsetof(struct xfs_gc_bio, bio), 0))
|
||||
goto out_exit_bio_set;
|
||||
for (i = 0; i < XFS_GC_NR_BUFS; i++) {
|
||||
data->scratch_folios[i] =
|
||||
folio_alloc(GFP_KERNEL, get_order(XFS_GC_BUF_SIZE));
|
||||
|
|
@ -238,6 +244,8 @@ xfs_zone_gc_data_alloc(
|
|||
out_free_scratch:
|
||||
while (--i >= 0)
|
||||
folio_put(data->scratch_folios[i]);
|
||||
bioset_exit(&data->split_bio_set);
|
||||
out_exit_bio_set:
|
||||
bioset_exit(&data->bio_set);
|
||||
out_free_recs:
|
||||
kfree(data->iter.recs);
|
||||
|
|
@ -254,6 +262,7 @@ xfs_zone_gc_data_free(
|
|||
|
||||
for (i = 0; i < XFS_GC_NR_BUFS; i++)
|
||||
folio_put(data->scratch_folios[i]);
|
||||
bioset_exit(&data->split_bio_set);
|
||||
bioset_exit(&data->bio_set);
|
||||
kfree(data->iter.recs);
|
||||
kfree(data);
|
||||
|
|
@ -810,7 +819,8 @@ xfs_zone_gc_split_write(
|
|||
data->mp->m_sb.sb_blocksize) >> SECTOR_SHIFT;
|
||||
split_len = split_sectors << SECTOR_SHIFT;
|
||||
|
||||
split = bio_split(&chunk->bio, split_sectors, GFP_NOFS, &data->bio_set);
|
||||
split = bio_split(&chunk->bio, split_sectors, GFP_NOFS,
|
||||
&data->split_bio_set);
|
||||
split_chunk = container_of(split, struct xfs_gc_bio, bio);
|
||||
split_chunk->data = data;
|
||||
ihold(VFS_I(chunk->ip));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user