Commit 32a961fc authored by Maciej Szwed's avatar Maciej Szwed Committed by Tomasz Zawadzki
Browse files

bdev: Add check for atomic compare and write unit



Compare and write fused operation num_blocks should
not exceed value of 'atomic compare and write unit'.
In case of NVMe native support we should read this
value from 'namespace atomic compare and write unit'
if set in namespace identify data, otherwise from
'atomic and write unit' field in controller identify
data. If bdev does not support this natively we should
set this value to 1.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Change-Id: Ib1ea02dbf9d1eed476d9dd0114ea96b1376e0c45
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/477911


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 61d6254d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -271,6 +271,9 @@ struct spdk_bdev {
	/** Number of blocks required for write */
	uint32_t write_unit_size;

	/** Atomic compare & write unit */
	uint16_t acwu;

	/**
	 * Specifies an alignment requirement for data buffers associated with an spdk_bdev_io.
	 * 0 = no alignment requirement
+9 −0
Original line number Diff line number Diff line
@@ -3657,6 +3657,10 @@ spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io
		return -EINVAL;
	}

	if (num_blocks > bdev->acwu) {
		return -EINVAL;
	}

	bdev_io = bdev_channel_get_io(channel);
	if (!bdev_io) {
		return -ENOMEM;
@@ -4750,6 +4754,11 @@ bdev_init(struct spdk_bdev *bdev)
		bdev->write_unit_size = 1;
	}

	/* Set ACWU value to 1 if bdev module did not set it (does not support it natively) */
	if (bdev->acwu == 0) {
		bdev->acwu = 1;
	}

	TAILQ_INIT(&bdev->internal.open_descs);
	TAILQ_INIT(&bdev->internal.locked_ranges);
	TAILQ_INIT(&bdev->internal.pending_locked_ranges);
+10 −1
Original line number Diff line number Diff line
@@ -899,9 +899,10 @@ nvme_ctrlr_populate_standard_namespace(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr,
		bdev->disk.uuid = *uuid;
	}

	nsdata = spdk_nvme_ns_get_data(ns);

	bdev->disk.md_len = spdk_nvme_ns_get_md_size(ns);
	if (bdev->disk.md_len != 0) {
		nsdata = spdk_nvme_ns_get_data(ns);
		bdev->disk.md_interleave = nsdata->flbas.extended;
		bdev->disk.dif_type = (enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns);
		if (bdev->disk.dif_type != SPDK_DIF_DISABLE) {
@@ -910,6 +911,14 @@ nvme_ctrlr_populate_standard_namespace(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr,
		}
	}

	if (!bdev_nvme_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE)) {
		bdev->disk.acwu = 0;
	} else if (nsdata->nsfeat.ns_atomic_write_unit) {
		bdev->disk.acwu = nsdata->nacwu;
	} else {
		bdev->disk.acwu = cdata->acwu;
	}

	bdev->disk.ctxt = bdev;
	bdev->disk.fn_table = &nvmelib_fn_table;
	bdev->disk.module = &nvme_if;