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: paul luse <paul.e.luse@intel.com>
Change-Id: Ifa55da54246735e7b603fafd34718965b0f27b94
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1180
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
paul luse 2020-03-06 14:57:22 +00:00 committed by Tomasz Zawadzki
parent d688779dc8
commit 4a9f28a482

View File

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