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: Maciej Szwed <maciej.szwed@intel.com>
Change-Id: Ib1ea02dbf9d1eed476d9dd0114ea96b1376e0c45
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/477911
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Maciej Szwed 2019-12-13 10:56:17 +01:00 committed by Tomasz Zawadzki
parent 61d6254d18
commit 32a961fc5d
3 changed files with 22 additions and 1 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;