Commit e1b5d28c authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

bdev/nvme: set `max_segment_size` and `max_num_segments`



Maximum Data Transfer Size indicates the maximum data transfer size
for a command that transfers data between memory and the controller.
SPDK NVMe driver will split IO request based on MDTS and stripe
boundary, however, if user submited a big enough IO size, SPDK
NVMe driver will run out of requests data structure and return
-EINVAL as the error code, it's OK for application who call SPDK
NVMe driver directly.

SPDK bdev module also will do similar split based on `max_segment_size`
and `max_num_segments`, but we don't set them for bdev/nvme driver,
once there was a big enough IO request, the NVMe driver will return
-EINVAL to bdev module, here we set `max_segment_size` based on MDTS
and set `max_num_segments` based on number of requests of NVMe
controller.

Fix #2403.

Change-Id: Ic6e14a0b12413783597122285ac648b87e1f1e16
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12186


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent 9df0f594
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2871,11 +2871,13 @@ nvme_disk_create(struct spdk_bdev *disk, const char *base_name,
	const uint8_t *nguid;
	const struct spdk_nvme_ctrlr_data *cdata;
	const struct spdk_nvme_ns_data	*nsdata;
	const struct spdk_nvme_ctrlr_opts *opts;
	enum spdk_nvme_csi		csi;
	uint32_t atomic_bs, phys_bs, bs;

	cdata = spdk_nvme_ctrlr_get_data(ctrlr);
	csi = spdk_nvme_ns_get_csi(ns);
	opts = spdk_nvme_ctrlr_get_opts(ctrlr);

	switch (csi) {
	case SPDK_NVME_CSI_NVM:
@@ -2910,6 +2912,16 @@ nvme_disk_create(struct spdk_bdev *disk, const char *base_name,
	}
	disk->blocklen = spdk_nvme_ns_get_extended_sector_size(ns);
	disk->blockcnt = spdk_nvme_ns_get_num_sectors(ns);
	disk->max_segment_size = spdk_nvme_ctrlr_get_max_xfer_size(ctrlr);
	/* NVMe driver will split one request into multiple requests
	 * based on MDTS and stripe boundary, the bdev layer will use
	 * max_segment_size and max_num_segments to split one big IO
	 * into multiple requests, then small request can't run out
	 * of NVMe internal requests data structure.
	 */
	if (opts && opts->io_queue_requests) {
		disk->max_num_segments = opts->io_queue_requests / 2;
	}
	disk->optimal_io_boundary = spdk_nvme_ns_get_optimal_io_boundary(ns);

	nguid = spdk_nvme_ns_get_nguid(ns);