Commit 442e13c0 authored by Jonas Pfefferle's avatar Jonas Pfefferle Committed by Tomasz Zawadzki
Browse files

bdev: split *_ext unit tests



Split *_ext tests into:
- bdev_io_ext: run with valid ext_opts
- bdev_io_ext_no_opts: run without ext_opts
- bdev_io_ext_invalid_opts: fail with invalid ext opts
- bdev_io_ext_split: check metadata is correctly split
- bdev_io_ext_bounce_buffer: memory domain specified but not
                             supported by bdev -> bounce buf

Signed-off-by: default avatarJonas Pfefferle <pepperjo@japf.ch>
Change-Id: I79b444fd5753150afee4017fd39fca0d89c6bda9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14026


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 7ba89d1e
Loading
Loading
Loading
Loading
+180 −27
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ struct ut_expected_io {
	struct iovec			iov[BDEV_IO_NUM_CHILD_IOV];
	void				*md_buf;
	struct spdk_bdev_ext_io_opts	*ext_io_opts;
	bool				copy_opts;
	TAILQ_ENTRY(ut_expected_io)	link;
};

@@ -248,6 +249,22 @@ stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
		}
	}

	if (expected_io->copy_opts) {
		if (expected_io->ext_io_opts) {
			/* opts are not NULL so it should have been copied */
			CU_ASSERT(expected_io->ext_io_opts != bdev_io->u.bdev.ext_opts);
			CU_ASSERT(bdev_io->u.bdev.ext_opts == &bdev_io->internal.ext_opts_copy);
			/* internal opts always points to opts passed */
			CU_ASSERT(expected_io->ext_io_opts == bdev_io->internal.ext_opts);
		} else {
			/* passed opts was NULL so we expect bdev_io opts to be NULL */
			CU_ASSERT(bdev_io->u.bdev.ext_opts == NULL);
		}
	} else {
		/* opts were not copied so they should be equal */
		CU_ASSERT(expected_io->ext_io_opts == bdev_io->u.bdev.ext_opts);
	}

	if (expected_io->length == 0) {
		free(expected_io);
		return;
@@ -274,10 +291,6 @@ stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
		CU_ASSERT(iov->iov_base == expected_iov->iov_base);
	}

	if (expected_io->ext_io_opts) {
		CU_ASSERT(expected_io->ext_io_opts == bdev_io->internal.ext_opts)
	}

	free(expected_io);
}

@@ -3435,6 +3448,7 @@ bdev_compare_and_write(void)
	CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS);
	CU_ASSERT(memcmp(write_buf, bb_buf, sizeof(write_buf)) == 0);

	/* Test miscompare */
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, num_blocks, 0);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

@@ -5103,7 +5117,7 @@ bdev_get_memory_domains(void)
}

static void
bdev_writev_readv_ext(void)
_bdev_io_ext(struct spdk_bdev_ext_io_opts *ext_io_opts)
{
	struct spdk_bdev *bdev;
	struct spdk_bdev_desc *desc = NULL;
@@ -5111,10 +5125,6 @@ bdev_writev_readv_ext(void)
	char io_buf[512];
	struct iovec iov = { .iov_base = io_buf, .iov_len = 512 };
	struct ut_expected_io *expected_io;
	struct spdk_bdev_ext_io_opts ext_io_opts = {
		.metadata = (void *)0xFF000000,
		.size = sizeof(ext_io_opts)
	};
	int rc;

	spdk_bdev_initialize(bdev_init_cb, NULL);
@@ -5130,15 +5140,17 @@ bdev_writev_readv_ext(void)
	io_ch = spdk_bdev_get_io_channel(desc);
	CU_ASSERT(io_ch != NULL);

	/* Test 1, Simple test */
	/* read */
	g_io_done = false;
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 32, 14, 1);
	expected_io->md_buf = ext_io_opts.metadata;
	expected_io->ext_io_opts = &ext_io_opts;
	if (ext_io_opts) {
		expected_io->md_buf = ext_io_opts->metadata;
		expected_io->ext_io_opts = ext_io_opts;
	}
	ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, ext_io_opts);

	CU_ASSERT(rc == 0);
	CU_ASSERT(g_io_done == false);
@@ -5146,14 +5158,17 @@ bdev_writev_readv_ext(void)
	stub_complete_io(1);
	CU_ASSERT(g_io_done == true);

	/* write */
	g_io_done = false;
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 1);
	expected_io->md_buf = ext_io_opts.metadata;
	expected_io->ext_io_opts = &ext_io_opts;
	if (ext_io_opts) {
		expected_io->md_buf = ext_io_opts->metadata;
		expected_io->ext_io_opts = ext_io_opts;
	}
	ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, ext_io_opts);

	CU_ASSERT(rc == 0);
	CU_ASSERT(g_io_done == false);
@@ -5161,27 +5176,114 @@ bdev_writev_readv_ext(void)
	stub_complete_io(1);
	CU_ASSERT(g_io_done == true);

	/* Test 2, invalid ext_opts size */
	spdk_put_io_channel(io_ch);
	spdk_bdev_close(desc);
	free_bdev(bdev);
	spdk_bdev_finish(bdev_fini_cb, NULL);
	poll_threads();

}

static void
bdev_io_ext(void)
{
	struct spdk_bdev_ext_io_opts ext_io_opts = {
		.metadata = (void *)0xFF000000,
		.size = sizeof(ext_io_opts)
	};

	_bdev_io_ext(&ext_io_opts);
}

static void
bdev_io_ext_no_opts(void)
{
	_bdev_io_ext(NULL);
}

static void
bdev_io_ext_invalid_opts(void)
{
	struct spdk_bdev *bdev;
	struct spdk_bdev_desc *desc = NULL;
	struct spdk_io_channel *io_ch;
	char io_buf[512];
	struct iovec iov = { .iov_base = io_buf, .iov_len = 512 };
	struct spdk_bdev_ext_io_opts ext_io_opts = {
		.metadata = (void *)0xFF000000,
		.size = sizeof(ext_io_opts)
	};
	int rc;

	spdk_bdev_initialize(bdev_init_cb, NULL);

	bdev = allocate_bdev("bdev0");
	bdev->md_interleave = false;
	bdev->md_len = 8;

	rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc);
	CU_ASSERT(rc == 0);
	SPDK_CU_ASSERT_FATAL(desc != NULL);
	CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc));
	io_ch = spdk_bdev_get_io_channel(desc);
	CU_ASSERT(io_ch != NULL);

	/* Test invalid ext_opts size */
	ext_io_opts.size = 0;
	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);
	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);

	ext_io_opts.size = sizeof(ext_io_opts) * 2;
	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);
	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);

	ext_io_opts.size = offsetof(struct spdk_bdev_ext_io_opts, metadata) +
			   sizeof(ext_io_opts.metadata) - 1;
	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);
	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
	CU_ASSERT(rc != 0);
	CU_ASSERT(rc == -EINVAL);

	spdk_put_io_channel(io_ch);
	spdk_bdev_close(desc);
	free_bdev(bdev);
	spdk_bdev_finish(bdev_fini_cb, NULL);
	poll_threads();
}

	/* Test 3, Check that IO request with ext_opts and metadata is split correctly
static void
bdev_io_ext_split(void)
{
	struct spdk_bdev *bdev;
	struct spdk_bdev_desc *desc = NULL;
	struct spdk_io_channel *io_ch;
	char io_buf[512];
	struct iovec iov = { .iov_base = io_buf, .iov_len = 512 };
	struct ut_expected_io *expected_io;
	struct spdk_bdev_ext_io_opts ext_io_opts = {
		.metadata = (void *)0xFF000000,
		.size = sizeof(ext_io_opts)
	};
	int rc;

	spdk_bdev_initialize(bdev_init_cb, NULL);

	bdev = allocate_bdev("bdev0");
	bdev->md_interleave = false;
	bdev->md_len = 8;

	rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc);
	CU_ASSERT(rc == 0);
	SPDK_CU_ASSERT_FATAL(desc != NULL);
	CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc));
	io_ch = spdk_bdev_get_io_channel(desc);
	CU_ASSERT(io_ch != NULL);

	/* Check that IO request with ext_opts and metadata is split correctly
	 * Offset 14, length 8, payload 0xF000
	 *  Child - Offset 14, length 2, payload 0xF000
	 *  Child - Offset 16, length 6, payload 0xF000 + 2 * 512
@@ -5201,11 +5303,15 @@ bdev_writev_readv_ext(void)
	/* read */
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1);
	expected_io->md_buf = ext_io_opts.metadata;
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1);
	expected_io->md_buf = ext_io_opts.metadata + 2 * 8;
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

@@ -5222,11 +5328,15 @@ bdev_writev_readv_ext(void)
	g_io_done = false;
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 1);
	expected_io->md_buf = ext_io_opts.metadata;
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 6, 1);
	expected_io->md_buf = ext_io_opts.metadata + 2 * 8;
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512);
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

@@ -5239,14 +5349,51 @@ bdev_writev_readv_ext(void)
	CU_ASSERT(g_io_done == true);
	CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0);

	/* Test 4, Verify data pull/push
	 * bdev doens't support memory domains, so buffers from bdev memory pool will be used */
	spdk_put_io_channel(io_ch);
	spdk_bdev_close(desc);
	free_bdev(bdev);
	spdk_bdev_finish(bdev_fini_cb, NULL);
	poll_threads();
}

static void
bdev_io_ext_bounce_buffer(void)
{
	struct spdk_bdev *bdev;
	struct spdk_bdev_desc *desc = NULL;
	struct spdk_io_channel *io_ch;
	char io_buf[512];
	struct iovec iov = { .iov_base = io_buf, .iov_len = 512 };
	struct ut_expected_io *expected_io;
	struct spdk_bdev_ext_io_opts ext_io_opts = {
		.metadata = (void *)0xFF000000,
		.size = sizeof(ext_io_opts)
	};
	int rc;

	spdk_bdev_initialize(bdev_init_cb, NULL);

	bdev = allocate_bdev("bdev0");
	bdev->md_interleave = false;
	bdev->md_len = 8;

	rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc);
	CU_ASSERT(rc == 0);
	SPDK_CU_ASSERT_FATAL(desc != NULL);
	CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc));
	io_ch = spdk_bdev_get_io_channel(desc);
	CU_ASSERT(io_ch != NULL);

	/* Verify data pull/push
	 * bdev doesn't support memory domains, so buffers from bdev memory pool will be used */
	ext_io_opts.memory_domain = (struct spdk_memory_domain *)0xdeadbeef;

	/* read */
	g_io_done = false;
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 32, 14, 1);
	ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len);
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
@@ -5258,10 +5405,12 @@ bdev_writev_readv_ext(void)
	CU_ASSERT(g_memory_domain_push_data_called == true);
	CU_ASSERT(g_io_done == true);

	/* write */
	g_io_done = false;
	expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 1);
	ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len);
	expected_io->ext_io_opts = &ext_io_opts;
	expected_io->copy_opts = true;
	TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link);

	rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts);
@@ -5490,7 +5639,11 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, bdev_set_options_test);
	CU_ADD_TEST(suite, bdev_multi_allocation);
	CU_ADD_TEST(suite, bdev_get_memory_domains);
	CU_ADD_TEST(suite, bdev_writev_readv_ext);
	CU_ADD_TEST(suite, bdev_io_ext);
	CU_ADD_TEST(suite, bdev_io_ext_no_opts);
	CU_ADD_TEST(suite, bdev_io_ext_invalid_opts);
	CU_ADD_TEST(suite, bdev_io_ext_split);
	CU_ADD_TEST(suite, bdev_io_ext_bounce_buffer);
	CU_ADD_TEST(suite, bdev_register_uuid_alias);
	CU_ADD_TEST(suite, bdev_unregister_by_name);
	CU_ADD_TEST(suite, for_each_bdev_test);