test/reduce: allow for non-synchronous operations
In some upcoming unit tests, we will need to test overlapped I/O operations, so add a facility in the reduce unit tests to allow for that. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: Ia9c6a3af3db104999f5d01e1115b0f1d164cef22 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448329 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
670db76047
commit
94d353ea30
@ -50,6 +50,28 @@ static char g_path[REDUCE_PATH_MAX];
|
|||||||
|
|
||||||
#define TEST_MD_PATH "/tmp"
|
#define TEST_MD_PATH "/tmp"
|
||||||
|
|
||||||
|
enum ut_reduce_bdev_io_type {
|
||||||
|
UT_REDUCE_IO_READV = 1,
|
||||||
|
UT_REDUCE_IO_WRITEV = 2,
|
||||||
|
UT_REDUCE_IO_UNMAP = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ut_reduce_bdev_io {
|
||||||
|
enum ut_reduce_bdev_io_type type;
|
||||||
|
struct spdk_reduce_backing_dev *backing_dev;
|
||||||
|
struct iovec *iov;
|
||||||
|
int iovcnt;
|
||||||
|
uint64_t lba;
|
||||||
|
uint32_t lba_count;
|
||||||
|
struct spdk_reduce_vol_cb_args *args;
|
||||||
|
TAILQ_ENTRY(ut_reduce_bdev_io) link;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool g_defer_bdev_io = false;
|
||||||
|
static TAILQ_HEAD(, ut_reduce_bdev_io) g_pending_bdev_io =
|
||||||
|
TAILQ_HEAD_INITIALIZER(g_pending_bdev_io);
|
||||||
|
static uint32_t g_pending_bdev_io_count = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sync_pm_buf(const void *addr, size_t length)
|
sync_pm_buf(const void *addr, size_t length)
|
||||||
{
|
{
|
||||||
@ -237,11 +259,39 @@ backing_dev_readv_execute(struct spdk_reduce_backing_dev *backing_dev,
|
|||||||
args->cb_fn(args->cb_arg, 0);
|
args->cb_fn(args->cb_arg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
backing_dev_insert_io(enum ut_reduce_bdev_io_type type, struct spdk_reduce_backing_dev *backing_dev,
|
||||||
|
struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
|
||||||
|
struct spdk_reduce_vol_cb_args *args)
|
||||||
|
{
|
||||||
|
struct ut_reduce_bdev_io *ut_bdev_io;
|
||||||
|
|
||||||
|
ut_bdev_io = calloc(1, sizeof(*ut_bdev_io));
|
||||||
|
SPDK_CU_ASSERT_FATAL(ut_bdev_io != NULL);
|
||||||
|
|
||||||
|
ut_bdev_io->type = type;
|
||||||
|
ut_bdev_io->backing_dev = backing_dev;
|
||||||
|
ut_bdev_io->iov = iov;
|
||||||
|
ut_bdev_io->iovcnt = iovcnt;
|
||||||
|
ut_bdev_io->lba = lba;
|
||||||
|
ut_bdev_io->lba_count = lba_count;
|
||||||
|
ut_bdev_io->args = args;
|
||||||
|
TAILQ_INSERT_TAIL(&g_pending_bdev_io, ut_bdev_io, link);
|
||||||
|
g_pending_bdev_io_count++;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
backing_dev_readv(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
|
backing_dev_readv(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
|
||||||
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
||||||
{
|
{
|
||||||
backing_dev_readv_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
|
if (g_defer_bdev_io == false) {
|
||||||
|
CU_ASSERT(g_pending_bdev_io_count == 0);
|
||||||
|
CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
|
||||||
|
backing_dev_readv_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
backing_dev_insert_io(UT_REDUCE_IO_READV, backing_dev, iov, iovcnt, lba, lba_count, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -265,7 +315,14 @@ static void
|
|||||||
backing_dev_writev(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
|
backing_dev_writev(struct spdk_reduce_backing_dev *backing_dev, struct iovec *iov, int iovcnt,
|
||||||
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
||||||
{
|
{
|
||||||
backing_dev_writev_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
|
if (g_defer_bdev_io == false) {
|
||||||
|
CU_ASSERT(g_pending_bdev_io_count == 0);
|
||||||
|
CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
|
||||||
|
backing_dev_writev_execute(backing_dev, iov, iovcnt, lba, lba_count, args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
backing_dev_insert_io(UT_REDUCE_IO_WRITEV, backing_dev, iov, iovcnt, lba, lba_count, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -284,7 +341,52 @@ static void
|
|||||||
backing_dev_unmap(struct spdk_reduce_backing_dev *backing_dev,
|
backing_dev_unmap(struct spdk_reduce_backing_dev *backing_dev,
|
||||||
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
uint64_t lba, uint32_t lba_count, struct spdk_reduce_vol_cb_args *args)
|
||||||
{
|
{
|
||||||
backing_dev_unmap_execute(backing_dev, lba, lba_count, args);
|
if (g_defer_bdev_io == false) {
|
||||||
|
CU_ASSERT(g_pending_bdev_io_count == 0);
|
||||||
|
CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
|
||||||
|
backing_dev_unmap_execute(backing_dev, lba, lba_count, args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
backing_dev_insert_io(UT_REDUCE_IO_UNMAP, backing_dev, NULL, 0, lba, lba_count, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
backing_dev_io_execute(uint32_t count)
|
||||||
|
{
|
||||||
|
struct ut_reduce_bdev_io *ut_bdev_io;
|
||||||
|
uint32_t done = 0;
|
||||||
|
|
||||||
|
CU_ASSERT(g_defer_bdev_io == true);
|
||||||
|
while (!TAILQ_EMPTY(&g_pending_bdev_io) && (count == 0 || done < count)) {
|
||||||
|
ut_bdev_io = TAILQ_FIRST(&g_pending_bdev_io);
|
||||||
|
TAILQ_REMOVE(&g_pending_bdev_io, ut_bdev_io, link);
|
||||||
|
g_pending_bdev_io_count--;
|
||||||
|
switch (ut_bdev_io->type) {
|
||||||
|
case UT_REDUCE_IO_READV:
|
||||||
|
backing_dev_readv_execute(ut_bdev_io->backing_dev,
|
||||||
|
ut_bdev_io->iov, ut_bdev_io->iovcnt,
|
||||||
|
ut_bdev_io->lba, ut_bdev_io->lba_count,
|
||||||
|
ut_bdev_io->args);
|
||||||
|
break;
|
||||||
|
case UT_REDUCE_IO_WRITEV:
|
||||||
|
backing_dev_writev_execute(ut_bdev_io->backing_dev,
|
||||||
|
ut_bdev_io->iov, ut_bdev_io->iovcnt,
|
||||||
|
ut_bdev_io->lba, ut_bdev_io->lba_count,
|
||||||
|
ut_bdev_io->args);
|
||||||
|
break;
|
||||||
|
case UT_REDUCE_IO_UNMAP:
|
||||||
|
backing_dev_unmap_execute(ut_bdev_io->backing_dev,
|
||||||
|
ut_bdev_io->lba, ut_bdev_io->lba_count,
|
||||||
|
ut_bdev_io->args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CU_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(ut_bdev_io);
|
||||||
|
done++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -796,6 +898,69 @@ destroy(void)
|
|||||||
backing_dev_destroy(&backing_dev);
|
backing_dev_destroy(&backing_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This test primarily checks that the reduce unit test infrastructure for asynchronous
|
||||||
|
* backing device I/O operations is working correctly.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
defer_bdev_io(void)
|
||||||
|
{
|
||||||
|
struct spdk_reduce_vol_params params = {};
|
||||||
|
struct spdk_reduce_backing_dev backing_dev = {};
|
||||||
|
const uint32_t logical_block_size = 512;
|
||||||
|
struct iovec iov;
|
||||||
|
char buf[logical_block_size];
|
||||||
|
char compare_buf[logical_block_size];
|
||||||
|
|
||||||
|
params.chunk_size = 16 * 1024;
|
||||||
|
params.backing_io_unit_size = 4096;
|
||||||
|
params.logical_block_size = logical_block_size;
|
||||||
|
spdk_uuid_generate(¶ms.uuid);
|
||||||
|
|
||||||
|
backing_dev_init(&backing_dev, ¶ms, 512);
|
||||||
|
|
||||||
|
g_vol = NULL;
|
||||||
|
g_reduce_errno = -1;
|
||||||
|
spdk_reduce_vol_init(¶ms, &backing_dev, TEST_MD_PATH, init_cb, NULL);
|
||||||
|
CU_ASSERT(g_reduce_errno == 0);
|
||||||
|
SPDK_CU_ASSERT_FATAL(g_vol != NULL);
|
||||||
|
|
||||||
|
/* Write 0xAA to 1 512-byte logical block. */
|
||||||
|
memset(buf, 0xAA, params.logical_block_size);
|
||||||
|
iov.iov_base = buf;
|
||||||
|
iov.iov_len = params.logical_block_size;
|
||||||
|
g_reduce_errno = -100;
|
||||||
|
g_defer_bdev_io = true;
|
||||||
|
spdk_reduce_vol_writev(g_vol, &iov, 1, 0, 1, write_cb, NULL);
|
||||||
|
/* Callback should not have executed, so this should still equal -100. */
|
||||||
|
CU_ASSERT(g_reduce_errno == -100);
|
||||||
|
CU_ASSERT(!TAILQ_EMPTY(&g_pending_bdev_io));
|
||||||
|
/* We wrote to part of one chunk which was previously unallocated. This should result in
|
||||||
|
* 4 pending I/O - one for each backing io unit in the chunk.
|
||||||
|
*/
|
||||||
|
CU_ASSERT(g_pending_bdev_io_count == params.chunk_size / params.backing_io_unit_size);
|
||||||
|
|
||||||
|
backing_dev_io_execute(0);
|
||||||
|
CU_ASSERT(TAILQ_EMPTY(&g_pending_bdev_io));
|
||||||
|
CU_ASSERT(g_reduce_errno == 0);
|
||||||
|
|
||||||
|
g_defer_bdev_io = false;
|
||||||
|
memset(compare_buf, 0xAA, sizeof(compare_buf));
|
||||||
|
memset(buf, 0xFF, sizeof(buf));
|
||||||
|
iov.iov_base = buf;
|
||||||
|
iov.iov_len = params.logical_block_size;
|
||||||
|
g_reduce_errno = -100;
|
||||||
|
spdk_reduce_vol_readv(g_vol, &iov, 1, 0, 1, read_cb, NULL);
|
||||||
|
CU_ASSERT(g_reduce_errno == 0);
|
||||||
|
CU_ASSERT(memcmp(buf, compare_buf, sizeof(buf)) == 0);
|
||||||
|
|
||||||
|
g_reduce_errno = -1;
|
||||||
|
spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
|
||||||
|
CU_ASSERT(g_reduce_errno == 0);
|
||||||
|
|
||||||
|
persistent_pm_buf_destroy();
|
||||||
|
backing_dev_destroy(&backing_dev);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -821,7 +986,8 @@ main(int argc, char **argv)
|
|||||||
CU_add_test(suite, "load", load) == NULL ||
|
CU_add_test(suite, "load", load) == NULL ||
|
||||||
CU_add_test(suite, "write_maps", write_maps) == NULL ||
|
CU_add_test(suite, "write_maps", write_maps) == NULL ||
|
||||||
CU_add_test(suite, "read_write", read_write) == NULL ||
|
CU_add_test(suite, "read_write", read_write) == NULL ||
|
||||||
CU_add_test(suite, "destroy", destroy) == NULL
|
CU_add_test(suite, "destroy", destroy) == NULL ||
|
||||||
|
CU_add_test(suite, "defer_bdev_io", defer_bdev_io) == NULL
|
||||||
) {
|
) {
|
||||||
CU_cleanup_registry();
|
CU_cleanup_registry();
|
||||||
return CU_get_error();
|
return CU_get_error();
|
||||||
|
Loading…
Reference in New Issue
Block a user