Commit 4a9f28a4 authored by paul luse's avatar paul luse Committed by Tomasz Zawadzki
Browse files

test/bdevperf: prevent overlaping w/r/v operations



There was no sync between the start of a w/r/v operation at
a specific block with the previous completion.  This resulted
in data miscompares either because the initial Q depth was
sized such that a disk wrap need to occur to complete it or in
the event that an IO takes longer to complete than when bdevperf
loops back around to that offset.

Fixes #1208

Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: Ifa55da54246735e7b603fafd34718965b0f27b94
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1180


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent d688779d
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "spdk/thread.h"
#include "spdk/string.h"
#include "spdk/rpc.h"
#include "spdk/bit_array.h"

struct bdevperf_task {
	struct iovec			iov;
@@ -110,6 +111,7 @@ struct io_target {
	bool				is_draining;
	struct spdk_poller		*run_timer;
	struct spdk_poller		*reset_timer;
	struct spdk_bit_array		*outstanding;
	TAILQ_HEAD(, bdevperf_task)	task_list;
};

@@ -267,6 +269,9 @@ bdevperf_free_target(struct io_target *target)
		free(task);
	}

	if (g_verify) {
		spdk_bit_array_free(&target->outstanding);
	}
	free(target->name);
	free(target);
}
@@ -391,6 +396,9 @@ bdevperf_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
	target->current_queue_depth--;

	if (success) {
		if (g_verify) {
			spdk_bit_array_clear(target->outstanding, task->offset_blocks / target->io_size_blocks);
		}
		target->io_completed++;
	}

@@ -677,6 +685,20 @@ bdevperf_submit_single(struct io_target *target, struct bdevperf_task *task)
		if (target->offset_in_ios == target->size_in_ios) {
			target->offset_in_ios = 0;
		}

		/* Increment of offset_in_ios if there's already an outstanding IO
		 * to that location. We only need this with g_verify as random
		 * offsets are not supported with g_verify at this time.
		 */
		if (g_verify && spdk_bit_array_get(target->outstanding, offset_in_ios)) {
			do {
				offset_in_ios++;
				if (target->offset_in_ios == target->size_in_ios) {
					target->offset_in_ios = 0;
				}
			} while (spdk_bit_array_get(target->outstanding, offset_in_ios));
			spdk_bit_array_set(target->outstanding, offset_in_ios);
		}
	}

	task->offset_blocks = offset_in_ios * target->io_size_blocks;
@@ -1081,7 +1103,7 @@ _bdevperf_construct_target(struct spdk_bdev *bdev, struct io_target_group *group
		SPDK_ERRLOG("Could not open leaf bdev %s, error=%d\n", spdk_bdev_get_name(bdev), rc);
		free(target->name);
		free(target);
		return 0;
		return -EINVAL;
	}

	target->bdev = bdev;
@@ -1101,6 +1123,17 @@ _bdevperf_construct_target(struct spdk_bdev *bdev, struct io_target_group *group

	target->size_in_ios = spdk_bdev_get_num_blocks(bdev) / target->io_size_blocks;

	if (g_verify) {
		target->outstanding = spdk_bit_array_create(target->size_in_ios);
		if (target->outstanding == NULL) {
			SPDK_ERRLOG("Could not create outstanding array bitmap for bdev %s\n", spdk_bdev_get_name(bdev));
			spdk_bdev_close(target->bdev_desc);
			free(target->name);
			free(target);
			return -ENOMEM;
		}
	}

	TAILQ_INIT(&target->task_list);

	target->group = group;