bdevperf: add unmap IO workload

There is an existing unmap "workload" but it is not a
real workload - it's just used as a type of verify
function to check if an unmapped region later returns
zeroes.  This has typically been true for Intel NVMe SSDs
but is not universal, so this functionality is not really
useful.  It's not used anywhere in any of the tests in the
SPDK tree either.

So replace it with a real "unmap" workload that will
do sequential unmap operations on the underlying
bdev.  A future enhancement could make these unmap
operations random across the bdev - but that can be
added later.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I99d7c2d455fb5c3c87712a5bbfd890d257630f88

Reviewed-on: https://review.gerrithub.io/413151
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2018-05-31 06:16:10 -07:00 committed by Daniel Verkamp
parent 95e9846781
commit 58bcd554b5

View File

@ -291,7 +291,7 @@ bdevperf_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
printf("task offset: %lu on target bdev=%s fails\n",
task->offset_blocks, target->name);
}
} else if (g_verify || g_reset || g_unmap) {
} else if (g_verify || g_reset) {
spdk_bdev_io_get_iovec(bdev_io, &iovs, &iovcnt);
assert(iovcnt == 1);
assert(iovs != NULL);
@ -327,32 +327,6 @@ bdevperf_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
}
}
static void
bdevperf_unmap_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
struct io_target *target;
struct bdevperf_task *task = cb_arg;
int rc;
target = task->target;
/* Set the expected buffer to 0. */
memset(task->buf, 0, g_io_size);
/* Read the data back in */
rc = spdk_bdev_read_blocks(target->bdev_desc, target->ch, NULL, task->offset_blocks,
target->io_size_blocks, bdevperf_complete, task);
if (rc) {
printf("Failed to submit read: %d\n", rc);
target->is_draining = true;
g_run_failed = true;
return;
}
spdk_bdev_free_io(bdev_io);
}
static void
bdevperf_verify_write_complete(struct spdk_bdev_io *bdev_io, bool success,
void *cb_arg)
@ -363,25 +337,14 @@ bdevperf_verify_write_complete(struct spdk_bdev_io *bdev_io, bool success,
target = task->target;
if (g_unmap) {
rc = spdk_bdev_unmap_blocks(target->bdev_desc, target->ch, task->offset_blocks,
target->io_size_blocks, bdevperf_unmap_complete, task);
if (rc) {
printf("Failed to submit unmap: %d\n", rc);
target->is_draining = true;
g_run_failed = true;
return;
}
} else {
/* Read the data back in */
rc = spdk_bdev_read_blocks(target->bdev_desc, target->ch, NULL, task->offset_blocks,
target->io_size_blocks, bdevperf_complete, task);
if (rc) {
printf("Failed to submit read: %d\n", rc);
target->is_draining = true;
g_run_failed = true;
return;
}
/* Read the data back in */
rc = spdk_bdev_read_blocks(target->bdev_desc, target->ch, NULL, task->offset_blocks,
target->io_size_blocks, bdevperf_complete, task);
if (rc) {
printf("Failed to submit read: %d\n", rc);
target->is_draining = true;
g_run_failed = true;
return;
}
spdk_bdev_free_io(bdev_io);
@ -421,7 +384,7 @@ bdevperf_submit_single(struct io_target *target, struct bdevperf_task *task)
}
task->offset_blocks = offset_in_ios * target->io_size_blocks;
if (g_verify || g_reset || g_unmap) {
if (g_verify || g_reset) {
memset(task->buf, rand_r(&seed) % 256, g_io_size);
task->iov.iov_base = task->buf;
task->iov.iov_len = g_io_size;
@ -433,6 +396,15 @@ bdevperf_submit_single(struct io_target *target, struct bdevperf_task *task)
g_run_failed = true;
return;
}
} else if (g_unmap) {
rc = spdk_bdev_unmap_blocks(desc, ch, task->offset_blocks,
target->io_size_blocks, bdevperf_complete, task);
if (rc) {
printf("Failed to submit unmap: %d\n", rc);
target->is_draining = true;
g_run_failed = true;
return;
}
} else if ((g_rw_percentage == 100) ||
(g_rw_percentage != 0 && ((rand_r(&seed) % 100) < g_rw_percentage))) {
rbuf = g_zcopy ? NULL : task->buf;
@ -910,9 +882,12 @@ main(int argc, char **argv)
g_rw_percentage = 0;
}
if (!strcmp(workload_type, "unmap")) {
g_unmap = true;
}
if (!strcmp(workload_type, "verify") ||
!strcmp(workload_type, "reset") ||
!strcmp(workload_type, "unmap")) {
!strcmp(workload_type, "reset")) {
g_rw_percentage = 50;
if (g_io_size > SPDK_BDEV_LARGE_BUF_MAX_SIZE) {
fprintf(stderr, "Unable to exceed max I/O size of %d for verify. (%d provided).\n",
@ -927,9 +902,6 @@ main(int argc, char **argv)
if (!strcmp(workload_type, "reset")) {
g_reset = true;
}
if (!strcmp(workload_type, "unmap")) {
g_unmap = true;
}
}
if (!strcmp(workload_type, "read") ||