Skip to content

Commit 6f25dd1

Browse files
author
Mike Snitzer
committed
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 a9ce385 ("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>
1 parent 4a2fe29 commit 6f25dd1

1 file changed

Lines changed: 29 additions & 11 deletions

File tree

drivers/md/dm.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -570,13 +570,15 @@ static void dm_end_io_acct(struct dm_io *io)
570570
dm_io_acct(io, true);
571571
}
572572

573-
static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
573+
static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio, gfp_t gfp_mask)
574574
{
575575
struct dm_io *io;
576576
struct dm_target_io *tio;
577577
struct bio *clone;
578578

579-
clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->mempools->io_bs);
579+
clone = bio_alloc_clone(NULL, bio, gfp_mask, &md->mempools->io_bs);
580+
if (unlikely(!clone))
581+
return NULL;
580582
tio = clone_to_tio(clone);
581583
tio->flags = 0;
582584
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)
17141716
if (unlikely(!ti))
17151717
return BLK_STS_IOERR;
17161718

1717-
if (unlikely((ci->bio->bi_opf & REQ_NOWAIT) != 0) &&
1718-
unlikely(!dm_target_supports_nowait(ti->type)))
1719-
return BLK_STS_NOTSUPP;
1720-
17211719
if (unlikely(ci->is_abnormal_io))
17221720
return __process_abnormal_io(ci, ti);
17231721

@@ -1729,7 +1727,17 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
17291727

17301728
len = min_t(sector_t, max_io_len(ti, ci->sector), ci->sector_count);
17311729
setup_split_accounting(ci, len);
1732-
clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
1730+
1731+
if (unlikely(ci->bio->bi_opf & REQ_NOWAIT)) {
1732+
if (unlikely(!dm_target_supports_nowait(ti->type)))
1733+
return BLK_STS_NOTSUPP;
1734+
1735+
clone = alloc_tio(ci, ti, 0, &len, GFP_NOWAIT);
1736+
if (unlikely(!clone))
1737+
return BLK_STS_AGAIN;
1738+
} else {
1739+
clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
1740+
}
17331741
__map_bio(clone);
17341742

17351743
ci->sector += len;
@@ -1738,11 +1746,11 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
17381746
return BLK_STS_OK;
17391747
}
17401748

1741-
static void init_clone_info(struct clone_info *ci, struct mapped_device *md,
1749+
static void init_clone_info(struct clone_info *ci, struct dm_io *io,
17421750
struct dm_table *map, struct bio *bio, bool is_abnormal)
17431751
{
17441752
ci->map = map;
1745-
ci->io = alloc_io(md, bio);
1753+
ci->io = io;
17461754
ci->bio = bio;
17471755
ci->is_abnormal_io = is_abnormal;
17481756
ci->submit_as_polled = false;
@@ -1777,8 +1785,18 @@ static void dm_split_and_process_bio(struct mapped_device *md,
17771785
return;
17781786
}
17791787

1780-
init_clone_info(&ci, md, map, bio, is_abnormal);
1781-
io = ci.io;
1788+
/* Only support nowait for normal IO */
1789+
if (unlikely(bio->bi_opf & REQ_NOWAIT) && !is_abnormal) {
1790+
io = alloc_io(md, bio, GFP_NOWAIT);
1791+
if (unlikely(!io)) {
1792+
/* Unable to do anything without dm_io. */
1793+
bio_wouldblock_error(bio);
1794+
return;
1795+
}
1796+
} else {
1797+
io = alloc_io(md, bio, GFP_NOIO);
1798+
}
1799+
init_clone_info(&ci, io, map, bio, is_abnormal);
17821800

17831801
if (bio->bi_opf & REQ_PREFLUSH) {
17841802
__send_empty_flush(&ci);

0 commit comments

Comments
 (0)