Skip to content

Commit 4a2fe29

Browse files
author
Mike Snitzer
committed
dm: enhance alloc_multiple_bios() to be more versatile
alloc_multiple_bios() has the useful ability to try allocating bios with GFP_NOWAIT but will fallback to using GFP_NOIO. The callers service both empty flush bios and abnormal bios (e.g. discard). alloc_multiple_bios() enhancements offered in this commit: - don't require table_devices_lock if num_bios = 1 - allow caller to pass GFP_NOWAIT to do usual GFP_NOWAIT with GFP_NOIO fallback - allow caller to pass GFP_NOIO to _only_ allocate using GFP_NOIO Flush bios with data may be issued to DM with REQ_NOWAIT, as such it makes sense to attempt servicing them with GFP_NOWAIT allocations. But abnormal IO should never be issued using REQ_NOWAIT (if that changes in the future that's fine, but no sense supporting it now). While at it, rename __send_changing_extent_only() to __send_abnormal_io(). [Thanks to both Ming and Mikulas for help with translating known possible IO scenarios to requirements.] Suggested-by: Ming Lei <ming.lei@redhat.com> Suggested-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
1 parent 34dbaa8 commit 4a2fe29

1 file changed

Lines changed: 34 additions & 34 deletions

File tree

drivers/md/dm.c

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,15 +1478,15 @@ static void setup_split_accounting(struct clone_info *ci, unsigned int len)
14781478

14791479
static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
14801480
struct dm_target *ti, unsigned int num_bios,
1481-
unsigned *len)
1481+
unsigned *len, gfp_t gfp_flag)
14821482
{
14831483
struct bio *bio;
1484-
int try;
1484+
int try = (gfp_flag & GFP_NOWAIT) ? 0 : 1;
14851485

1486-
for (try = 0; try < 2; try++) {
1486+
for (; try < 2; try++) {
14871487
int bio_nr;
14881488

1489-
if (try)
1489+
if (try && num_bios > 1)
14901490
mutex_lock(&ci->io->md->table_devices_lock);
14911491
for (bio_nr = 0; bio_nr < num_bios; bio_nr++) {
14921492
bio = alloc_tio(ci, ti, bio_nr, len,
@@ -1496,7 +1496,7 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
14961496

14971497
bio_list_add(blist, bio);
14981498
}
1499-
if (try)
1499+
if (try && num_bios > 1)
15001500
mutex_unlock(&ci->io->md->table_devices_lock);
15011501
if (bio_nr == num_bios)
15021502
return;
@@ -1507,33 +1507,30 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
15071507
}
15081508

15091509
static unsigned int __send_duplicate_bios(struct clone_info *ci, struct dm_target *ti,
1510-
unsigned int num_bios, unsigned int *len)
1510+
unsigned int num_bios, unsigned int *len,
1511+
gfp_t gfp_flag)
15111512
{
15121513
struct bio_list blist = BIO_EMPTY_LIST;
15131514
struct bio *clone;
15141515
unsigned int ret = 0;
15151516

1516-
switch (num_bios) {
1517-
case 0:
1518-
break;
1519-
case 1:
1520-
if (len)
1521-
setup_split_accounting(ci, *len);
1522-
clone = alloc_tio(ci, ti, 0, len, GFP_NOIO);
1523-
__map_bio(clone);
1524-
ret = 1;
1525-
break;
1526-
default:
1527-
if (len)
1528-
setup_split_accounting(ci, *len);
1529-
/* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
1530-
alloc_multiple_bios(&blist, ci, ti, num_bios, len);
1531-
while ((clone = bio_list_pop(&blist))) {
1517+
if (WARN_ON_ONCE(num_bios == 0)) /* num_bios = 0 is a bug in caller */
1518+
return 0;
1519+
1520+
/* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
1521+
if (len)
1522+
setup_split_accounting(ci, *len);
1523+
1524+
/*
1525+
* Using alloc_multiple_bios(), even if num_bios is 1, to consistently
1526+
* support allocating using GFP_NOWAIT with GFP_NOIO fallback.
1527+
*/
1528+
alloc_multiple_bios(&blist, ci, ti, num_bios, len, gfp_flag);
1529+
while ((clone = bio_list_pop(&blist))) {
1530+
if (num_bios > 1)
15321531
dm_tio_set_flag(clone_to_tio(clone), DM_TIO_IS_DUPLICATE_BIO);
1533-
__map_bio(clone);
1534-
ret += 1;
1535-
}
1536-
break;
1532+
__map_bio(clone);
1533+
ret += 1;
15371534
}
15381535

15391536
return ret;
@@ -1560,8 +1557,12 @@ static void __send_empty_flush(struct clone_info *ci)
15601557
unsigned int bios;
15611558
struct dm_target *ti = dm_table_get_target(t, i);
15621559

1560+
if (unlikely(ti->num_flush_bios == 0))
1561+
continue;
1562+
15631563
atomic_add(ti->num_flush_bios, &ci->io->io_count);
1564-
bios = __send_duplicate_bios(ci, ti, ti->num_flush_bios, NULL);
1564+
bios = __send_duplicate_bios(ci, ti, ti->num_flush_bios,
1565+
NULL, GFP_NOWAIT);
15651566
atomic_sub(ti->num_flush_bios - bios, &ci->io->io_count);
15661567
}
15671568

@@ -1574,18 +1575,17 @@ static void __send_empty_flush(struct clone_info *ci)
15741575
bio_uninit(ci->bio);
15751576
}
15761577

1577-
static void __send_changing_extent_only(struct clone_info *ci, struct dm_target *ti,
1578-
unsigned int num_bios,
1579-
unsigned int max_granularity,
1580-
unsigned int max_sectors)
1578+
static void __send_abnormal_io(struct clone_info *ci, struct dm_target *ti,
1579+
unsigned int num_bios, unsigned int max_granularity,
1580+
unsigned int max_sectors)
15811581
{
15821582
unsigned int len, bios;
15831583

15841584
len = min_t(sector_t, ci->sector_count,
15851585
__max_io_len(ti, ci->sector, max_granularity, max_sectors));
15861586

15871587
atomic_add(num_bios, &ci->io->io_count);
1588-
bios = __send_duplicate_bios(ci, ti, num_bios, &len);
1588+
bios = __send_duplicate_bios(ci, ti, num_bios, &len, GFP_NOIO);
15891589
/*
15901590
* alloc_io() takes one extra reference for submission, so the
15911591
* reference won't reach 0 without the following (+1) subtraction
@@ -1654,8 +1654,8 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
16541654
if (unlikely(!num_bios))
16551655
return BLK_STS_NOTSUPP;
16561656

1657-
__send_changing_extent_only(ci, ti, num_bios,
1658-
max_granularity, max_sectors);
1657+
__send_abnormal_io(ci, ti, num_bios, max_granularity, max_sectors);
1658+
16591659
return BLK_STS_OK;
16601660
}
16611661

0 commit comments

Comments
 (0)