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:
parent
d688779dc8
commit
4a9f28a482
@ -43,6 +43,7 @@
|
|||||||
#include "spdk/thread.h"
|
#include "spdk/thread.h"
|
||||||
#include "spdk/string.h"
|
#include "spdk/string.h"
|
||||||
#include "spdk/rpc.h"
|
#include "spdk/rpc.h"
|
||||||
|
#include "spdk/bit_array.h"
|
||||||
|
|
||||||
struct bdevperf_task {
|
struct bdevperf_task {
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
@ -110,6 +111,7 @@ struct io_target {
|
|||||||
bool is_draining;
|
bool is_draining;
|
||||||
struct spdk_poller *run_timer;
|
struct spdk_poller *run_timer;
|
||||||
struct spdk_poller *reset_timer;
|
struct spdk_poller *reset_timer;
|
||||||
|
struct spdk_bit_array *outstanding;
|
||||||
TAILQ_HEAD(, bdevperf_task) task_list;
|
TAILQ_HEAD(, bdevperf_task) task_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -267,6 +269,9 @@ bdevperf_free_target(struct io_target *target)
|
|||||||
free(task);
|
free(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_verify) {
|
||||||
|
spdk_bit_array_free(&target->outstanding);
|
||||||
|
}
|
||||||
free(target->name);
|
free(target->name);
|
||||||
free(target);
|
free(target);
|
||||||
}
|
}
|
||||||
@ -391,6 +396,9 @@ bdevperf_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
|||||||
target->current_queue_depth--;
|
target->current_queue_depth--;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
if (g_verify) {
|
||||||
|
spdk_bit_array_clear(target->outstanding, task->offset_blocks / target->io_size_blocks);
|
||||||
|
}
|
||||||
target->io_completed++;
|
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) {
|
if (target->offset_in_ios == target->size_in_ios) {
|
||||||
target->offset_in_ios = 0;
|
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;
|
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);
|
SPDK_ERRLOG("Could not open leaf bdev %s, error=%d\n", spdk_bdev_get_name(bdev), rc);
|
||||||
free(target->name);
|
free(target->name);
|
||||||
free(target);
|
free(target);
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
target->bdev = bdev;
|
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;
|
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);
|
TAILQ_INIT(&target->task_list);
|
||||||
|
|
||||||
target->group = group;
|
target->group = group;
|
||||||
|
Loading…
Reference in New Issue
Block a user