bdev_ut: add examine_locks test

This updates the way that the bdev_ut examine callbacks are called such
that tests can specify test-specific examine_config and examine_disk
callbacks. A test is added that uses this to verify that no locks are
held while examine callbacks are called.

Change-Id: Ic1a402a0edc17aeb9cd596e1f6822af9f59c7d5b
Signed-off-by: Mike Gerdts <mgerdts@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15283
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
Mike Gerdts 2022-11-02 22:37:58 -05:00 committed by Jim Harris
parent 7241a075be
commit ae215731ef

View File

@ -463,7 +463,8 @@ struct spdk_bdev_module bdev_ut_if = {
.async_init = true, .async_init = true,
}; };
static void vbdev_ut_examine(struct spdk_bdev *bdev); static void vbdev_ut_examine_config(struct spdk_bdev *bdev);
static void vbdev_ut_examine_disk(struct spdk_bdev *bdev);
static int static int
vbdev_ut_module_init(void) vbdev_ut_module_init(void)
@ -480,20 +481,52 @@ struct spdk_bdev_module vbdev_ut_if = {
.name = "vbdev_ut", .name = "vbdev_ut",
.module_init = vbdev_ut_module_init, .module_init = vbdev_ut_module_init,
.module_fini = vbdev_ut_module_fini, .module_fini = vbdev_ut_module_fini,
.examine_config = vbdev_ut_examine, .examine_config = vbdev_ut_examine_config,
.examine_disk = vbdev_ut_examine_disk,
}; };
SPDK_BDEV_MODULE_REGISTER(bdev_ut, &bdev_ut_if) SPDK_BDEV_MODULE_REGISTER(bdev_ut, &bdev_ut_if)
SPDK_BDEV_MODULE_REGISTER(vbdev_ut, &vbdev_ut_if) SPDK_BDEV_MODULE_REGISTER(vbdev_ut, &vbdev_ut_if)
struct ut_examine_ctx {
void (*examine_config)(struct spdk_bdev *bdev);
void (*examine_disk)(struct spdk_bdev *bdev);
uint32_t examine_config_count;
uint32_t examine_disk_count;
};
static void static void
vbdev_ut_examine(struct spdk_bdev *bdev) vbdev_ut_examine_config(struct spdk_bdev *bdev)
{ {
struct ut_examine_ctx *ctx = bdev->ctxt;
if (ctx != NULL) {
ctx->examine_config_count++;
if (ctx->examine_config != NULL) {
ctx->examine_config(bdev);
}
}
spdk_bdev_module_examine_done(&vbdev_ut_if);
}
static void
vbdev_ut_examine_disk(struct spdk_bdev *bdev)
{
struct ut_examine_ctx *ctx = bdev->ctxt;
if (ctx != NULL) {
ctx->examine_disk_count++;
if (ctx->examine_disk != NULL) {
ctx->examine_disk(bdev);
}
}
spdk_bdev_module_examine_done(&vbdev_ut_if); spdk_bdev_module_examine_done(&vbdev_ut_if);
} }
static struct spdk_bdev * static struct spdk_bdev *
allocate_bdev(char *name) allocate_bdev_ctx(char *name, void *ctx)
{ {
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
int rc; int rc;
@ -501,6 +534,7 @@ allocate_bdev(char *name)
bdev = calloc(1, sizeof(*bdev)); bdev = calloc(1, sizeof(*bdev));
SPDK_CU_ASSERT_FATAL(bdev != NULL); SPDK_CU_ASSERT_FATAL(bdev != NULL);
bdev->ctxt = ctx;
bdev->name = name; bdev->name = name;
bdev->fn_table = &fn_table; bdev->fn_table = &fn_table;
bdev->module = &bdev_ut_if; bdev->module = &bdev_ut_if;
@ -516,6 +550,12 @@ allocate_bdev(char *name)
return bdev; return bdev;
} }
static struct spdk_bdev *
allocate_bdev(char *name)
{
return allocate_bdev_ctx(name, NULL);
}
static struct spdk_bdev * static struct spdk_bdev *
allocate_vbdev(char *name) allocate_vbdev(char *name)
{ {
@ -6173,6 +6213,49 @@ bdev_copy_split_test(void)
ut_fini_bdev(); ut_fini_bdev();
} }
static void
examine_claim(struct spdk_bdev *bdev)
{
int rc;
rc = spdk_bdev_module_claim_bdev(bdev, NULL, &vbdev_ut_if);
CU_ASSERT(rc == 0);
}
static void
examine_no_lock_held(struct spdk_bdev *bdev)
{
CU_ASSERT(!spdk_spin_held(&g_bdev_mgr.spinlock));
CU_ASSERT(!spdk_spin_held(&bdev->internal.spinlock));
}
static void
examine_locks(void)
{
struct spdk_bdev *bdev;
struct ut_examine_ctx ctx = { 0 };
/* Without any claims, one code path is taken */
ctx.examine_config = examine_no_lock_held;
ctx.examine_disk = examine_no_lock_held;
bdev = allocate_bdev_ctx("bdev0", &ctx);
CU_ASSERT(ctx.examine_config_count == 1);
CU_ASSERT(ctx.examine_disk_count == 1);
CU_ASSERT(bdev->internal.claim_module == NULL);
free_bdev(bdev);
/* Exercise the other path that is taken when examine_config() takes a claim. */
memset(&ctx, 0, sizeof(ctx));
ctx.examine_config = examine_claim;
ctx.examine_disk = examine_no_lock_held;
bdev = allocate_bdev_ctx("bdev0", &ctx);
CU_ASSERT(ctx.examine_config_count == 1);
CU_ASSERT(ctx.examine_disk_count == 1);
CU_ASSERT(bdev->internal.claim_module == &vbdev_ut_if);
spdk_bdev_module_release_bdev(bdev);
free_bdev(bdev);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -6235,6 +6318,7 @@ main(int argc, char **argv)
CU_ADD_TEST(suite, bdev_seek_test); CU_ADD_TEST(suite, bdev_seek_test);
CU_ADD_TEST(suite, bdev_copy); CU_ADD_TEST(suite, bdev_copy);
CU_ADD_TEST(suite, bdev_copy_split_test); CU_ADD_TEST(suite, bdev_copy_split_test);
CU_ADD_TEST(suite, examine_locks);
allocate_cores(1); allocate_cores(1);
allocate_threads(1); allocate_threads(1);