Skip to content

Commit be04c14

Browse files
author
Mike Snitzer
committed
dm: use op specific max_sectors when splitting abnormal io
Split abnormal IO in terms of the corresponding operation specific max_sectors (max_discard_sectors, max_secure_erase_sectors or max_write_zeroes_sectors). This fixes a significant dm-thinp discard performance regression that was introduced with commit e2dd8ac ("dm bio prison v1: improve concurrent IO performance"). Relative to discard: max_discard_sectors is used instead of max_sectors; which fixes excessive discard splitting (e.g. max_sectors=128K vs max_discard_sectors=64M). Tested by discarding an 1 Petabyte dm-thin device: lvcreate -V 1125899906842624B -T test/pool -n thin time blkdiscard /dev/test/thin Before this fix (splitting discards every 128K): ~116m After this fix (splitting discards every 64M) : 0m33.460s Reported-by: Zorro Lang <[email protected]> Fixes: 06961c4 ("dm: split discards further if target sets max_discard_granularity") Requires: 13f6fac ("dm: allow targets to require splitting WRITE_ZEROES and SECURE_ERASE") Fixes: e2dd8ac ("dm bio prison v1: improve concurrent IO performance") Signed-off-by: Mike Snitzer <[email protected]>
1 parent 722d908 commit be04c14

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

drivers/md/dm.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,8 @@ static inline sector_t max_io_len_target_boundary(struct dm_target *ti,
11721172
}
11731173

11741174
static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
1175-
unsigned int max_granularity)
1175+
unsigned int max_granularity,
1176+
unsigned int max_sectors)
11761177
{
11771178
sector_t target_offset = dm_target_offset(ti, sector);
11781179
sector_t len = max_io_len_target_boundary(ti, target_offset);
@@ -1186,13 +1187,13 @@ static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
11861187
if (!max_granularity)
11871188
return len;
11881189
return min_t(sector_t, len,
1189-
min(queue_max_sectors(ti->table->md->queue),
1190+
min(max_sectors ? : queue_max_sectors(ti->table->md->queue),
11901191
blk_chunk_sectors_left(target_offset, max_granularity)));
11911192
}
11921193

11931194
static inline sector_t max_io_len(struct dm_target *ti, sector_t sector)
11941195
{
1195-
return __max_io_len(ti, sector, ti->max_io_len);
1196+
return __max_io_len(ti, sector, ti->max_io_len, 0);
11961197
}
11971198

11981199
int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
@@ -1581,12 +1582,13 @@ static void __send_empty_flush(struct clone_info *ci)
15811582

15821583
static void __send_changing_extent_only(struct clone_info *ci, struct dm_target *ti,
15831584
unsigned int num_bios,
1584-
unsigned int max_granularity)
1585+
unsigned int max_granularity,
1586+
unsigned int max_sectors)
15851587
{
15861588
unsigned int len, bios;
15871589

15881590
len = min_t(sector_t, ci->sector_count,
1589-
__max_io_len(ti, ci->sector, max_granularity));
1591+
__max_io_len(ti, ci->sector, max_granularity, max_sectors));
15901592

15911593
atomic_add(num_bios, &ci->io->io_count);
15921594
bios = __send_duplicate_bios(ci, ti, num_bios, &len);
@@ -1623,23 +1625,27 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
16231625
{
16241626
unsigned int num_bios = 0;
16251627
unsigned int max_granularity = 0;
1628+
unsigned int max_sectors = 0;
16261629
struct queue_limits *limits = dm_get_queue_limits(ti->table->md);
16271630

16281631
switch (bio_op(ci->bio)) {
16291632
case REQ_OP_DISCARD:
16301633
num_bios = ti->num_discard_bios;
1634+
max_sectors = limits->max_discard_sectors;
16311635
if (ti->max_discard_granularity)
1632-
max_granularity = limits->max_discard_sectors;
1636+
max_granularity = max_sectors;
16331637
break;
16341638
case REQ_OP_SECURE_ERASE:
16351639
num_bios = ti->num_secure_erase_bios;
1640+
max_sectors = limits->max_secure_erase_sectors;
16361641
if (ti->max_secure_erase_granularity)
1637-
max_granularity = limits->max_secure_erase_sectors;
1642+
max_granularity = max_sectors;
16381643
break;
16391644
case REQ_OP_WRITE_ZEROES:
16401645
num_bios = ti->num_write_zeroes_bios;
1646+
max_sectors = limits->max_write_zeroes_sectors;
16411647
if (ti->max_write_zeroes_granularity)
1642-
max_granularity = limits->max_write_zeroes_sectors;
1648+
max_granularity = max_sectors;
16431649
break;
16441650
default:
16451651
break;
@@ -1654,7 +1660,8 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
16541660
if (unlikely(!num_bios))
16551661
return BLK_STS_NOTSUPP;
16561662

1657-
__send_changing_extent_only(ci, ti, num_bios, max_granularity);
1663+
__send_changing_extent_only(ci, ti, num_bios,
1664+
max_granularity, max_sectors);
16581665
return BLK_STS_OK;
16591666
}
16601667

0 commit comments

Comments
 (0)