Commit 58bcd554 authored by Jim Harris's avatar Jim Harris Committed by Daniel Verkamp
Browse files

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: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I99d7c2d455fb5c3c87712a5bbfd890d257630f88

Reviewed-on: https://review.gerrithub.io/413151


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 95e98467
Loading
Loading
Loading
Loading
+19 −47
Original line number Diff line number Diff line
@@ -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,16 +337,6 @@ 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);
@@ -382,7 +346,6 @@ bdevperf_verify_write_complete(struct spdk_bdev_io *bdev_io, bool success,
		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") ||