mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 16:37:50 +00:00
dm: respect REQ_NOWAIT flag in normal bios issued to DM
Update DM core's normal IO submission to allocate required memory
using GFP_NOWAIT if REQ_NOWAIT is set.
Tested with simple test provided in commit a9ce385344
("dm: don't
attempt to queue IO under RCU protection") that was enhanced to check
error codes. Also tested using fio's pvsync2 with nowait=1.
But testing with induced GFP_NOWAIT allocation failures wasn't
performed (yet).
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
This commit is contained in:
parent
4a2fe29608
commit
6f25dd1c57
1 changed files with 29 additions and 11 deletions
|
@ -570,13 +570,15 @@ static void dm_end_io_acct(struct dm_io *io)
|
|||
dm_io_acct(io, true);
|
||||
}
|
||||
|
||||
static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
|
||||
static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio, gfp_t gfp_mask)
|
||||
{
|
||||
struct dm_io *io;
|
||||
struct dm_target_io *tio;
|
||||
struct bio *clone;
|
||||
|
||||
clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->mempools->io_bs);
|
||||
clone = bio_alloc_clone(NULL, bio, gfp_mask, &md->mempools->io_bs);
|
||||
if (unlikely(!clone))
|
||||
return NULL;
|
||||
tio = clone_to_tio(clone);
|
||||
tio->flags = 0;
|
||||
dm_tio_set_flag(tio, DM_TIO_INSIDE_DM_IO);
|
||||
|
@ -1714,10 +1716,6 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
|
|||
if (unlikely(!ti))
|
||||
return BLK_STS_IOERR;
|
||||
|
||||
if (unlikely((ci->bio->bi_opf & REQ_NOWAIT) != 0) &&
|
||||
unlikely(!dm_target_supports_nowait(ti->type)))
|
||||
return BLK_STS_NOTSUPP;
|
||||
|
||||
if (unlikely(ci->is_abnormal_io))
|
||||
return __process_abnormal_io(ci, ti);
|
||||
|
||||
|
@ -1729,7 +1727,17 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
|
|||
|
||||
len = min_t(sector_t, max_io_len(ti, ci->sector), ci->sector_count);
|
||||
setup_split_accounting(ci, len);
|
||||
clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
|
||||
|
||||
if (unlikely(ci->bio->bi_opf & REQ_NOWAIT)) {
|
||||
if (unlikely(!dm_target_supports_nowait(ti->type)))
|
||||
return BLK_STS_NOTSUPP;
|
||||
|
||||
clone = alloc_tio(ci, ti, 0, &len, GFP_NOWAIT);
|
||||
if (unlikely(!clone))
|
||||
return BLK_STS_AGAIN;
|
||||
} else {
|
||||
clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
|
||||
}
|
||||
__map_bio(clone);
|
||||
|
||||
ci->sector += len;
|
||||
|
@ -1738,11 +1746,11 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
|
|||
return BLK_STS_OK;
|
||||
}
|
||||
|
||||
static void init_clone_info(struct clone_info *ci, struct mapped_device *md,
|
||||
static void init_clone_info(struct clone_info *ci, struct dm_io *io,
|
||||
struct dm_table *map, struct bio *bio, bool is_abnormal)
|
||||
{
|
||||
ci->map = map;
|
||||
ci->io = alloc_io(md, bio);
|
||||
ci->io = io;
|
||||
ci->bio = bio;
|
||||
ci->is_abnormal_io = is_abnormal;
|
||||
ci->submit_as_polled = false;
|
||||
|
@ -1777,8 +1785,18 @@ static void dm_split_and_process_bio(struct mapped_device *md,
|
|||
return;
|
||||
}
|
||||
|
||||
init_clone_info(&ci, md, map, bio, is_abnormal);
|
||||
io = ci.io;
|
||||
/* Only support nowait for normal IO */
|
||||
if (unlikely(bio->bi_opf & REQ_NOWAIT) && !is_abnormal) {
|
||||
io = alloc_io(md, bio, GFP_NOWAIT);
|
||||
if (unlikely(!io)) {
|
||||
/* Unable to do anything without dm_io. */
|
||||
bio_wouldblock_error(bio);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
io = alloc_io(md, bio, GFP_NOIO);
|
||||
}
|
||||
init_clone_info(&ci, io, map, bio, is_abnormal);
|
||||
|
||||
if (bio->bi_opf & REQ_PREFLUSH) {
|
||||
__send_empty_flush(&ci);
|
||||
|
|
Loading…
Reference in a new issue