Skip to content

Commit bc840b2

Browse files
keithbuschaxboe
authored andcommitted
nvme: remove virtual boundary for sgl capable devices
The nvme virtual boundary is only required for the PRP format. Devices that can use SGL for DMA don't need it for IO queues. Drop reporting it for such devices; rdma fabrics controllers will continue to use the limit as they currently don't report any boundary requirements, but tcp and fc never needed it in the first place so they get to report no virtual boundary. Applications may continue to align to the same virtual boundaries for optimization purposes if they want, and the driver will continue to decide whether to use the PRP format the same as before if the IO allows it. Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Keith Busch <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 2f6b256 commit bc840b2

9 files changed

Lines changed: 48 additions & 8 deletions

File tree

drivers/nvme/host/apple.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,7 @@ static const struct nvme_ctrl_ops nvme_ctrl_ops = {
12831283
.reg_read64 = apple_nvme_reg_read64,
12841284
.free_ctrl = apple_nvme_free_ctrl,
12851285
.get_address = apple_nvme_get_address,
1286+
.get_virt_boundary = nvme_get_virt_boundary,
12861287
};
12871288

12881289
static void apple_nvme_async_probe(void *data, async_cookie_t cookie)

drivers/nvme/host/core.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,13 +2069,13 @@ static u32 nvme_max_drv_segments(struct nvme_ctrl *ctrl)
20692069
}
20702070

20712071
static void nvme_set_ctrl_limits(struct nvme_ctrl *ctrl,
2072-
struct queue_limits *lim)
2072+
struct queue_limits *lim, bool is_admin)
20732073
{
20742074
lim->max_hw_sectors = ctrl->max_hw_sectors;
20752075
lim->max_segments = min_t(u32, USHRT_MAX,
20762076
min_not_zero(nvme_max_drv_segments(ctrl), ctrl->max_segments));
20772077
lim->max_integrity_segments = ctrl->max_integrity_segments;
2078-
lim->virt_boundary_mask = NVME_CTRL_PAGE_SIZE - 1;
2078+
lim->virt_boundary_mask = ctrl->ops->get_virt_boundary(ctrl, is_admin);
20792079
lim->max_segment_size = UINT_MAX;
20802080
lim->dma_alignment = 3;
20812081
}
@@ -2177,7 +2177,7 @@ static int nvme_update_ns_info_generic(struct nvme_ns *ns,
21772177
int ret;
21782178

21792179
lim = queue_limits_start_update(ns->disk->queue);
2180-
nvme_set_ctrl_limits(ns->ctrl, &lim);
2180+
nvme_set_ctrl_limits(ns->ctrl, &lim, false);
21812181

21822182
memflags = blk_mq_freeze_queue(ns->disk->queue);
21832183
ret = queue_limits_commit_update(ns->disk->queue, &lim);
@@ -2381,7 +2381,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
23812381
ns->head->lba_shift = id->lbaf[lbaf].ds;
23822382
ns->head->nuse = le64_to_cpu(id->nuse);
23832383
capacity = nvme_lba_to_sect(ns->head, le64_to_cpu(id->nsze));
2384-
nvme_set_ctrl_limits(ns->ctrl, &lim);
2384+
nvme_set_ctrl_limits(ns->ctrl, &lim, false);
23852385
nvme_configure_metadata(ns->ctrl, ns->head, id, nvm, info);
23862386
nvme_set_chunk_sectors(ns, id, &lim);
23872387
if (!nvme_update_disk_info(ns, id, &lim))
@@ -3588,7 +3588,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
35883588
min_not_zero(ctrl->max_hw_sectors, max_hw_sectors);
35893589

35903590
lim = queue_limits_start_update(ctrl->admin_q);
3591-
nvme_set_ctrl_limits(ctrl, &lim);
3591+
nvme_set_ctrl_limits(ctrl, &lim, true);
35923592
ret = queue_limits_commit_update(ctrl->admin_q, &lim);
35933593
if (ret)
35943594
goto out_free;

drivers/nvme/host/fabrics.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,12 @@ static inline unsigned int nvmf_nr_io_queues(struct nvmf_ctrl_options *opts)
217217
min(opts->nr_poll_queues, num_online_cpus());
218218
}
219219

220+
static inline unsigned long nvmf_get_virt_boundary(struct nvme_ctrl *ctrl,
221+
bool is_admin)
222+
{
223+
return 0;
224+
}
225+
220226
int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val);
221227
int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val);
222228
int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val);

drivers/nvme/host/fc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,6 +3360,7 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = {
33603360
.submit_async_event = nvme_fc_submit_async_event,
33613361
.delete_ctrl = nvme_fc_delete_ctrl,
33623362
.get_address = nvmf_get_address,
3363+
.get_virt_boundary = nvmf_get_virt_boundary,
33633364
};
33643365

33653366
static void

drivers/nvme/host/nvme.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,12 @@ static inline bool nvme_ns_has_pi(struct nvme_ns_head *head)
558558
return head->pi_type && head->ms == head->pi_size;
559559
}
560560

561+
static inline unsigned long nvme_get_virt_boundary(struct nvme_ctrl *ctrl,
562+
bool is_admin)
563+
{
564+
return NVME_CTRL_PAGE_SIZE - 1;
565+
}
566+
561567
struct nvme_ctrl_ops {
562568
const char *name;
563569
struct module *module;
@@ -578,6 +584,7 @@ struct nvme_ctrl_ops {
578584
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
579585
void (*print_device_info)(struct nvme_ctrl *ctrl);
580586
bool (*supports_pci_p2pdma)(struct nvme_ctrl *ctrl);
587+
unsigned long (*get_virt_boundary)(struct nvme_ctrl *ctrl, bool is_admin);
581588
};
582589

583590
/*

drivers/nvme/host/pci.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,22 @@ static inline enum nvme_use_sgl nvme_pci_use_sgls(struct nvme_dev *dev,
613613
struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
614614

615615
if (nvmeq->qid && nvme_ctrl_sgl_supported(&dev->ctrl)) {
616-
if (nvme_req(req)->flags & NVME_REQ_USERCMD)
617-
return SGL_FORCED;
618-
if (req->nr_integrity_segments > 1)
616+
/*
617+
* When the controller is capable of using SGL, there are
618+
* several conditions that we force to use it:
619+
*
620+
* 1. A request containing page gaps within the controller's
621+
* mask can not use the PRP format.
622+
*
623+
* 2. User commands use SGL because that lets the device
624+
* validate the requested transfer lengths.
625+
*
626+
* 3. Multiple integrity segments must use SGL as that's the
627+
* only way to describe such a command in NVMe.
628+
*/
629+
if (req_phys_gap_mask(req) & (NVME_CTRL_PAGE_SIZE - 1) ||
630+
nvme_req(req)->flags & NVME_REQ_USERCMD ||
631+
req->nr_integrity_segments > 1)
619632
return SGL_FORCED;
620633
return SGL_SUPPORTED;
621634
}
@@ -3243,6 +3256,14 @@ static bool nvme_pci_supports_pci_p2pdma(struct nvme_ctrl *ctrl)
32433256
return dma_pci_p2pdma_supported(dev->dev);
32443257
}
32453258

3259+
static unsigned long nvme_pci_get_virt_boundary(struct nvme_ctrl *ctrl,
3260+
bool is_admin)
3261+
{
3262+
if (!nvme_ctrl_sgl_supported(ctrl) || is_admin)
3263+
return NVME_CTRL_PAGE_SIZE - 1;
3264+
return 0;
3265+
}
3266+
32463267
static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
32473268
.name = "pcie",
32483269
.module = THIS_MODULE,
@@ -3257,6 +3278,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
32573278
.get_address = nvme_pci_get_address,
32583279
.print_device_info = nvme_pci_print_device_info,
32593280
.supports_pci_p2pdma = nvme_pci_supports_pci_p2pdma,
3281+
.get_virt_boundary = nvme_pci_get_virt_boundary,
32603282
};
32613283

32623284
static int nvme_dev_map(struct nvme_dev *dev)

drivers/nvme/host/rdma.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,6 +2202,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
22022202
.delete_ctrl = nvme_rdma_delete_ctrl,
22032203
.get_address = nvmf_get_address,
22042204
.stop_ctrl = nvme_rdma_stop_ctrl,
2205+
.get_virt_boundary = nvme_get_virt_boundary,
22052206
};
22062207

22072208
/*

drivers/nvme/host/tcp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,6 +2865,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = {
28652865
.delete_ctrl = nvme_tcp_delete_ctrl,
28662866
.get_address = nvme_tcp_get_address,
28672867
.stop_ctrl = nvme_tcp_stop_ctrl,
2868+
.get_virt_boundary = nvmf_get_virt_boundary,
28682869
};
28692870

28702871
static bool

drivers/nvme/target/loop.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ static const struct nvme_ctrl_ops nvme_loop_ctrl_ops = {
511511
.submit_async_event = nvme_loop_submit_async_event,
512512
.delete_ctrl = nvme_loop_delete_ctrl_host,
513513
.get_address = nvmf_get_address,
514+
.get_virt_boundary = nvme_get_virt_boundary,
514515
};
515516

516517
static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)

0 commit comments

Comments
 (0)