Skip to content

Commit 3831761

Browse files
axboeKeith Busch
authored andcommitted
nvme: only reconfigure discard if necessary
Currently nvme reconfigures discard for every disk revalidation. This is problematic because any O_WRONLY or O_RDWR open will trigger a partition scan through udev/systemd, and we will reconfigure discard. This blows away any user settings, like discard_max_bytes. Only re-configure the user settable settings if we need to. Signed-off-by: Jens Axboe <[email protected]> [removed redundant queue flag setting] Signed-off-by: Keith Busch <[email protected]>
1 parent 1811977 commit 3831761

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

drivers/nvme/host/core.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,23 +1347,32 @@ static void nvme_set_chunk_size(struct nvme_ns *ns)
13471347
blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(chunk_size));
13481348
}
13491349

1350-
static void nvme_config_discard(struct nvme_ctrl *ctrl,
1351-
unsigned stream_alignment, struct request_queue *queue)
1350+
static void nvme_config_discard(struct nvme_ns *ns)
13521351
{
1352+
struct nvme_ctrl *ctrl = ns->ctrl;
1353+
struct request_queue *queue = ns->queue;
13531354
u32 size = queue_logical_block_size(queue);
13541355

1355-
if (stream_alignment)
1356-
size *= stream_alignment;
1356+
if (!(ctrl->oncs & NVME_CTRL_ONCS_DSM)) {
1357+
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, queue);
1358+
return;
1359+
}
1360+
1361+
if (ctrl->nr_streams && ns->sws && ns->sgs)
1362+
size *= ns->sws * ns->sgs;
13571363

13581364
BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) <
13591365
NVME_DSM_MAX_RANGES);
13601366

13611367
queue->limits.discard_alignment = 0;
13621368
queue->limits.discard_granularity = size;
13631369

1370+
/* If discard is already enabled, don't reset queue limits */
1371+
if (blk_queue_flag_test_and_set(QUEUE_FLAG_DISCARD, queue))
1372+
return;
1373+
13641374
blk_queue_max_discard_sectors(queue, UINT_MAX);
13651375
blk_queue_max_discard_segments(queue, NVME_DSM_MAX_RANGES);
1366-
blk_queue_flag_set(QUEUE_FLAG_DISCARD, queue);
13671376

13681377
if (ctrl->quirks & NVME_QUIRK_DEALLOCATE_ZEROES)
13691378
blk_queue_max_write_zeroes_sectors(queue, UINT_MAX);
@@ -1407,10 +1416,6 @@ static void nvme_update_disk_info(struct gendisk *disk,
14071416
{
14081417
sector_t capacity = le64_to_cpup(&id->nsze) << (ns->lba_shift - 9);
14091418
unsigned short bs = 1 << ns->lba_shift;
1410-
unsigned stream_alignment = 0;
1411-
1412-
if (ns->ctrl->nr_streams && ns->sws && ns->sgs)
1413-
stream_alignment = ns->sws * ns->sgs;
14141419

14151420
blk_mq_freeze_queue(disk->queue);
14161421
blk_integrity_unregister(disk);
@@ -1424,10 +1429,9 @@ static void nvme_update_disk_info(struct gendisk *disk,
14241429
nvme_init_integrity(disk, ns->ms, ns->pi_type);
14251430
if (ns->ms && !nvme_ns_has_pi(ns) && !blk_get_integrity(disk))
14261431
capacity = 0;
1427-
set_capacity(disk, capacity);
14281432

1429-
if (ns->ctrl->oncs & NVME_CTRL_ONCS_DSM)
1430-
nvme_config_discard(ns->ctrl, stream_alignment, disk->queue);
1433+
set_capacity(disk, capacity);
1434+
nvme_config_discard(ns);
14311435
blk_mq_unfreeze_queue(disk->queue);
14321436
}
14331437

0 commit comments

Comments
 (0)