From 9104fe73ce38c4f02c2c7db4d417d0d4b8f92492 Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Fri, 26 May 2017 12:58:04 +0800 Subject: [PATCH] bdev: make (v)bdev init in async manner Change-Id: I93684a004e2ae276734edbb4767b5ba1bac3dd48 Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/362111 Reviewed-by: Jim Harris Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp --- include/spdk_internal/bdev.h | 5 ++- lib/bdev/aio/blockdev_aio.c | 10 +++-- lib/bdev/bdev.c | 68 +++++++++++++++++++++++-------- lib/bdev/error/vbdev_error.c | 19 +++++---- lib/bdev/malloc/blockdev_malloc.c | 16 +++++--- lib/bdev/null/blockdev_null.c | 13 +++--- lib/bdev/nvme/blockdev_nvme.c | 28 +++++++------ lib/bdev/rbd/blockdev_rbd.c | 26 ++++++------ lib/bdev/split/vbdev_split.c | 27 +++++++----- 9 files changed, 136 insertions(+), 76 deletions(-) diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index ca2890333..6a1eb93c4 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -87,10 +87,11 @@ struct spdk_bdev_module_if { /** * Initialization function for the module. Called by the spdk * application during startup. + * User must call spdk_bdev_module_init_next() with return code inside this func. * * Modules are required to define this function. */ - int (*module_init)(void); + void (*module_init)(void); /** * Finish function for the module. Called by the spdk application @@ -381,6 +382,8 @@ void spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, void spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module); void spdk_vbdev_module_list_add(struct spdk_bdev_module_if *vbdev_module); +void spdk_bdev_module_init_next(int rc); +void spdk_vbdev_module_init_next(int rc); static inline struct spdk_bdev_io * spdk_bdev_io_from_ctx(void *ctx) diff --git a/lib/bdev/aio/blockdev_aio.c b/lib/bdev/aio/blockdev_aio.c index 73a35e498..6d3d57123 100644 --- a/lib/bdev/aio/blockdev_aio.c +++ b/lib/bdev/aio/blockdev_aio.c @@ -43,7 +43,7 @@ #include "spdk_internal/log.h" -static int blockdev_aio_initialize(void); +static void blockdev_aio_initialize(void); static void aio_free_disk(struct file_disk *fdisk); static int @@ -377,7 +377,8 @@ error_return: return NULL; } -static int blockdev_aio_initialize(void) +static void +blockdev_aio_initialize(void) { size_t i; struct spdk_conf_section *sp; @@ -385,7 +386,7 @@ static int blockdev_aio_initialize(void) sp = spdk_conf_find_section(NULL, "AIO"); if (!sp) { - return 0; + goto end; } i = 0; @@ -415,7 +416,8 @@ static int blockdev_aio_initialize(void) i++; } - return 0; +end: + spdk_bdev_module_init_next(0); } SPDK_LOG_REGISTER_TRACE_FLAG("aio", SPDK_TRACE_AIO) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index c2dbae775..4499c1fa7 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -76,6 +76,9 @@ static struct spdk_bdev_mgr g_bdev_mgr = { .bdevs = TAILQ_HEAD_INITIALIZER(g_bdev_mgr.bdevs), }; +static struct spdk_bdev_module_if *g_next_bdev_module; +static struct spdk_bdev_module_if *g_next_vbdev_module; + struct spdk_bdev_mgmt_channel { }; @@ -258,11 +261,56 @@ spdk_bdev_mgmt_channel_destroy(void *io_device, void *ctx_buf) { } +void +spdk_bdev_module_init_next(int rc) +{ + if (rc) { + assert(g_next_bdev_module != NULL); + SPDK_ERRLOG("Failed to init bdev module: %s\n", g_next_bdev_module->module_name); + spdk_subsystem_init_next(rc); + return; + } + + if (!g_next_bdev_module) { + g_next_bdev_module = TAILQ_FIRST(&g_bdev_mgr.bdev_modules); + } else { + g_next_bdev_module = TAILQ_NEXT(g_next_bdev_module, tailq); + } + + if (g_next_bdev_module) { + g_next_bdev_module->module_init(); + } else { + spdk_vbdev_module_init_next(0); + } +} + +void +spdk_vbdev_module_init_next(int rc) +{ + if (rc) { + assert(g_next_vbdev_module != NULL); + SPDK_ERRLOG("Failed to init vbdev module: %s\n", g_next_vbdev_module->module_name); + spdk_subsystem_init_next(rc); + return; + } + + if (!g_next_vbdev_module) { + g_next_vbdev_module = TAILQ_FIRST(&g_bdev_mgr.vbdev_modules); + } else { + g_next_vbdev_module = TAILQ_NEXT(g_next_vbdev_module, tailq); + } + + if (g_next_vbdev_module) { + g_next_vbdev_module->module_init(); + } else { + spdk_subsystem_init_next(0); + } +} + static void spdk_bdev_initialize(void) { int i, cache_size; - struct spdk_bdev_module_if *bdev_module; int rc = 0; g_bdev_mgr.bdev_io_pool = spdk_mempool_create("blockdev_io", @@ -309,22 +357,6 @@ spdk_bdev_initialize(void) if (!g_bdev_mgr.buf_large_pool) { SPDK_ERRLOG("create rbuf large pool failed\n"); rc = -1; - goto end; - } - - TAILQ_FOREACH(bdev_module, &g_bdev_mgr.bdev_modules, tailq) { - rc = bdev_module->module_init(); - if (rc) { - rc = -1; - goto end; - } - } - TAILQ_FOREACH(bdev_module, &g_bdev_mgr.vbdev_modules, tailq) { - rc = bdev_module->module_init(); - if (rc) { - rc = -1; - goto end; - } } spdk_io_device_register(&g_bdev_mgr, spdk_bdev_mgmt_channel_create, @@ -332,7 +364,7 @@ spdk_bdev_initialize(void) sizeof(struct spdk_bdev_mgmt_channel)); end: - spdk_subsystem_init_next(rc); + spdk_bdev_module_init_next(rc); } static int diff --git a/lib/bdev/error/vbdev_error.c b/lib/bdev/error/vbdev_error.c index c6cfc6a09..3d7c43b33 100644 --- a/lib/bdev/error/vbdev_error.c +++ b/lib/bdev/error/vbdev_error.c @@ -221,17 +221,17 @@ cleanup: return rc; } -static int +static void vbdev_error_init(void) { struct spdk_conf_section *sp; const char *base_bdev_name; - int i; + int i, rc = 0; struct spdk_bdev *base_bdev; sp = spdk_conf_find_section(NULL, "BdevError"); if (sp == NULL) { - return 0; + goto end; } for (i = 0; ; i++) { @@ -242,20 +242,25 @@ vbdev_error_init(void) base_bdev_name = spdk_conf_section_get_nmval(sp, "BdevError", i, 0); if (!base_bdev_name) { SPDK_ERRLOG("ErrorInjection configuration missing blockdev name\n"); - return -1; + rc = -1; + goto end; } base_bdev = spdk_bdev_get_by_name(base_bdev_name); if (!base_bdev) { SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", base_bdev_name); - return -1; + rc = -1; + goto end; } if (spdk_vbdev_error_create(base_bdev)) { - return -1; + rc = -1; + goto end; } } - return 0; + +end: + spdk_vbdev_module_init_next(rc); } static void diff --git a/lib/bdev/malloc/blockdev_malloc.c b/lib/bdev/malloc/blockdev_malloc.c index 2dcca0ef0..e8d12220b 100644 --- a/lib/bdev/malloc/blockdev_malloc.c +++ b/lib/bdev/malloc/blockdev_malloc.c @@ -88,7 +88,7 @@ static struct malloc_disk *g_malloc_disk_head = NULL; int malloc_disk_count = 0; -static int blockdev_malloc_initialize(void); +static void blockdev_malloc_initialize(void); static void blockdev_malloc_finish(void); static void blockdev_malloc_get_spdk_running_config(FILE *fp); @@ -421,10 +421,10 @@ static void free_malloc_disk(struct malloc_disk *mdisk) spdk_dma_free(mdisk); } -static int blockdev_malloc_initialize(void) +static void blockdev_malloc_initialize(void) { struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Malloc"); - int NumberOfLuns, LunSizeInMB, BlockSize, i; + int NumberOfLuns, LunSizeInMB, BlockSize, i, rc = 0; uint64_t size; struct spdk_bdev *bdev; @@ -434,7 +434,8 @@ static int blockdev_malloc_initialize(void) BlockSize = spdk_conf_section_get_intval(sp, "BlockSize"); if ((NumberOfLuns < 1) || (LunSizeInMB < 1)) { SPDK_ERRLOG("Malloc section present, but no devices specified\n"); - return EINVAL; + rc = EINVAL; + goto end; } if (BlockSize < 1) { /* Default is 512 bytes */ @@ -445,11 +446,14 @@ static int blockdev_malloc_initialize(void) bdev = create_malloc_disk(size / BlockSize, BlockSize); if (bdev == NULL) { SPDK_ERRLOG("Could not create malloc disk\n"); - return EINVAL; + rc = EINVAL; + goto end; } } } - return 0; + +end: + spdk_bdev_module_init_next(rc); } static void blockdev_malloc_finish(void) diff --git a/lib/bdev/null/blockdev_null.c b/lib/bdev/null/blockdev_null.c index e479d7733..fbd5e3b8f 100644 --- a/lib/bdev/null/blockdev_null.c +++ b/lib/bdev/null/blockdev_null.c @@ -170,12 +170,12 @@ null_bdev_destroy_cb(void *io_device, void *ctx_buf) { } -static int +static void blockdev_null_initialize(void) { struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Null"); uint64_t size_in_mb, num_blocks; - int block_size, i; + int block_size, i, rc = 0; struct spdk_bdev *bdev; const char *name, *val; @@ -195,7 +195,7 @@ blockdev_null_initialize(void) spdk_io_device_register(&g_null_bdev_head, null_bdev_create_cb, null_bdev_destroy_cb, 0); if (sp == NULL) { - return 0; + goto end; } i = 0; @@ -241,12 +241,15 @@ blockdev_null_initialize(void) bdev = create_null_bdev(name, num_blocks, block_size); if (bdev == NULL) { SPDK_ERRLOG("Could not create null bdev\n"); - return EINVAL; + rc = EINVAL; + goto end; } i++; } - return 0; + +end: + spdk_bdev_module_init_next(rc); } static void diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index bd0182093..f9983e240 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -125,7 +125,7 @@ static TAILQ_HEAD(, nvme_ctrlr) g_nvme_ctrlrs = TAILQ_HEAD_INITIALIZER(g_nvme_ct static TAILQ_HEAD(, nvme_bdev) g_nvme_bdevs = TAILQ_HEAD_INITIALIZER(g_nvme_bdevs); static void nvme_ctrlr_create_bdevs(struct nvme_ctrlr *nvme_ctrlr); -static int bdev_nvme_library_init(void); +static void bdev_nvme_library_init(void); static void bdev_nvme_library_fini(void); static int bdev_nvme_queue_cmd(struct nvme_bdev *bdev, struct spdk_nvme_qpair *qpair, struct nvme_bdev_io *bio, @@ -754,25 +754,26 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid, return 0; } -static int +static void bdev_nvme_library_init(void) { struct spdk_conf_section *sp; const char *val; - int rc; + int rc = 0; size_t i; - struct nvme_probe_ctx *probe_ctx; + struct nvme_probe_ctx *probe_ctx = NULL; int retry_count; sp = spdk_conf_find_section(NULL, "Nvme"); if (sp == NULL) { - return 0; + goto end; } probe_ctx = calloc(1, sizeof(*probe_ctx)); if (probe_ctx == NULL) { SPDK_ERRLOG("Failed to allocate probe_ctx\n"); - return -1; + rc = -1; + goto end; } if ((retry_count = spdk_conf_section_get_intval(sp, "RetryCount")) < 0) { @@ -795,15 +796,15 @@ bdev_nvme_library_init(void) rc = spdk_nvme_transport_id_parse(&probe_ctx->trids[i], val); if (rc < 0) { SPDK_ERRLOG("Unable to parse TransportID: %s\n", val); - free(probe_ctx); - return -1; + rc = -1; + goto end; } val = spdk_conf_section_get_nmval(sp, "TransportID", i, 1); if (val == NULL) { SPDK_ERRLOG("No name provided for TransportID\n"); - free(probe_ctx); - return -1; + rc = -1; + goto end; } probe_ctx->names[i] = val; @@ -863,8 +864,8 @@ bdev_nvme_library_init(void) } if (spdk_nvme_probe(NULL, probe_ctx, probe_cb, attach_cb, NULL)) { - free(probe_ctx); - return -1; + rc = -1; + goto end; } if (g_nvme_hotplug_enabled) { @@ -872,8 +873,9 @@ bdev_nvme_library_init(void) g_nvme_hotplug_poll_core, g_nvme_hotplug_poll_timeout_us); } +end: free(probe_ctx); - return 0; + spdk_bdev_module_init_next(rc); } static void diff --git a/lib/bdev/rbd/blockdev_rbd.c b/lib/bdev/rbd/blockdev_rbd.c index ff98f26d5..2b357092e 100644 --- a/lib/bdev/rbd/blockdev_rbd.c +++ b/lib/bdev/rbd/blockdev_rbd.c @@ -199,7 +199,7 @@ blockdev_rbd_start_aio(rbd_image_t image, struct blockdev_rbd_io *cmd, return 0; } -static int blockdev_rbd_library_init(void); +static void blockdev_rbd_library_init(void); static void blockdev_rbd_library_fini(void); static int @@ -543,10 +543,10 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block return &rbd->disk; } -static int +static void blockdev_rbd_library_init(void) { - int i; + int i, rc = 0; const char *val; const char *pool_name; const char *rbd_name; @@ -558,7 +558,7 @@ blockdev_rbd_library_init(void) /* * Ceph section not found. Do not initialize any rbd LUNS. */ - return 0; + goto end; } /* Init rbd block devices */ @@ -571,13 +571,15 @@ blockdev_rbd_library_init(void) pool_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 0); if (pool_name == NULL) { SPDK_ERRLOG("Ceph%d: rbd pool name needs to be provided\n", i); - goto cleanup; + rc = -1; + goto end; } rbd_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 1); if (rbd_name == NULL) { SPDK_ERRLOG("Ceph%d: format error\n", i); - goto cleanup; + rc = -1; + goto end; } val = spdk_conf_section_get_nmval(sp, "Ceph", i, 2); @@ -589,17 +591,17 @@ blockdev_rbd_library_init(void) if (block_size & 0x1ff) { SPDK_ERRLOG("current block_size = %d, it should be multiple of 512\n", block_size); - goto cleanup; + rc = -1; + goto end; } } if (spdk_bdev_rbd_create(pool_name, rbd_name, block_size) == NULL) { - goto cleanup; + rc = -1; + goto end; } } - return 0; -cleanup: - blockdev_rbd_library_fini(); - return -1; +end: + spdk_bdev_module_init_next(rc); } diff --git a/lib/bdev/split/vbdev_split.c b/lib/bdev/split/vbdev_split.c index 2982bd600..ff874ecce 100644 --- a/lib/bdev/split/vbdev_split.c +++ b/lib/bdev/split/vbdev_split.c @@ -331,19 +331,19 @@ cleanup: return rc; } -static int +static void vbdev_split_init(void) { struct spdk_conf_section *sp; const char *base_bdev_name; const char *split_count_str; const char *split_size_str; - int i, split_count, split_size; + int i, split_count, split_size, rc = 0; struct spdk_bdev *base_bdev; sp = spdk_conf_find_section(NULL, "Split"); if (sp == NULL) { - return 0; + goto end; } for (i = 0; ; i++) { @@ -354,25 +354,29 @@ vbdev_split_init(void) base_bdev_name = spdk_conf_section_get_nmval(sp, "Split", i, 0); if (!base_bdev_name) { SPDK_ERRLOG("Split configuration missing blockdev name\n"); - return -1; + rc = -1; + goto end; } base_bdev = spdk_bdev_get_by_name(base_bdev_name); if (!base_bdev) { SPDK_ERRLOG("Could not find Split bdev %s\n", base_bdev_name); - return -1; + rc = -1; + goto end; } split_count_str = spdk_conf_section_get_nmval(sp, "Split", i, 1); if (!split_count_str) { SPDK_ERRLOG("Split configuration missing split count\n"); - return -1; + rc = -1; + goto end; } split_count = atoi(split_count_str); if (split_count < 1) { SPDK_ERRLOG("Invalid Split count %d\n", split_count); - return -1; + rc = -1; + goto end; } /* Optional split size in MB */ @@ -382,16 +386,19 @@ vbdev_split_init(void) split_size = atoi(split_size_str); if (split_size <= 0) { SPDK_ERRLOG("Invalid Split size %d\n", split_size); - return -1; + rc = -1; + goto end; } } if (vbdev_split_create(base_bdev, split_count, split_size)) { - return -1; + rc = -1; + goto end; } } - return 0; +end: + spdk_vbdev_module_init_next(rc); } static void