bdev: make module init asynchronous again
bdev_virtio requires us to do SCSI inquiry for each device and wait for a response. It currently polls inline for this response, taking up entire reactor exclusively. Making it async would allow other pollers to run while bdev_virtio still has to wait. Change-Id: Iefc88e0a2efb5b791ffe23b2e623b7c50d759084 Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/375573 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
5557843311
commit
c5ff3d7d26
@ -115,10 +115,10 @@ struct spdk_bdev_module_if {
|
||||
void (*examine)(struct spdk_bdev *bdev);
|
||||
|
||||
/**
|
||||
* Count of bdev examinations in progress. Used by generic bdev layer and must
|
||||
* not be modified by bdev modules.
|
||||
* Count of bdev inits/examinations in progress. Used by generic bdev
|
||||
* layer and must not be modified by bdev modules.
|
||||
*/
|
||||
uint32_t examine_in_progress;
|
||||
uint32_t action_in_progress;
|
||||
|
||||
TAILQ_ENTRY(spdk_bdev_module_if) tailq;
|
||||
};
|
||||
@ -384,7 +384,7 @@ void spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs,
|
||||
void spdk_vbdev_unregister(struct spdk_bdev *vbdev);
|
||||
|
||||
void spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module);
|
||||
|
||||
void spdk_bdev_module_init_done(struct spdk_bdev_module_if *module);
|
||||
int spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
||||
struct spdk_bdev_module_if *module);
|
||||
void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev);
|
||||
@ -437,7 +437,7 @@ spdk_bdev_io_from_ctx(void *ctx)
|
||||
((uintptr_t)ctx - offsetof(struct spdk_bdev_io, driver_ctx));
|
||||
}
|
||||
|
||||
#define SPDK_BDEV_MODULE_REGISTER(_name, init_fn, fini_fn, config_fn, ctx_size_fn, examine_fn)\
|
||||
#define SPDK_BDEV_MODULE_REGISTER(_name, init_fn, fini_fn, config_fn, ctx_size_fn, examine_fn) \
|
||||
static struct spdk_bdev_module_if _name ## _if = { \
|
||||
.name = #_name, \
|
||||
.module_init = init_fn, \
|
||||
@ -451,7 +451,17 @@ spdk_bdev_io_from_ctx(void *ctx)
|
||||
spdk_bdev_module_list_add(&_name ## _if); \
|
||||
}
|
||||
|
||||
#define SPDK_GET_BDEV_MODULE(name) &name ## _if
|
||||
#define SPDK_GET_BDEV_MODULE(name) (&name ## _if)
|
||||
|
||||
/*
|
||||
* Set module initialization to be asynchronous. After using this macro, the module
|
||||
* initialization has to be explicitly finished by calling spdk_bdev_module_init_done().
|
||||
*/
|
||||
#define SPDK_BDEV_MODULE_ASYNC_INIT(name) \
|
||||
__attribute__((constructor)) static void name ## _async_init(void) \
|
||||
{ \
|
||||
SPDK_GET_BDEV_MODULE(name)->action_in_progress = 1; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Modules are not required to use this macro. It allows modules to reference the module with
|
||||
|
@ -366,24 +366,53 @@ spdk_bdev_module_action_complete(void)
|
||||
struct spdk_bdev_module_if *m;
|
||||
|
||||
/*
|
||||
* Check all bdev modules for an examinations in progress. If any
|
||||
* Don't finish bdev subsystem initialization if
|
||||
* module pre-initialization is still in progress, or
|
||||
* the subsystem been already initialized.
|
||||
*/
|
||||
if (!g_bdev_mgr.module_init_complete || g_bdev_mgr.init_complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check all bdev modules for inits/examinations in progress. If any
|
||||
* exist, return immediately since we cannot finish bdev subsystem
|
||||
* initialization until all are completed.
|
||||
*/
|
||||
TAILQ_FOREACH(m, &g_bdev_mgr.bdev_modules, tailq) {
|
||||
if (m->examine_in_progress > 0) {
|
||||
if (m->action_in_progress > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Modules already finished initialization - now that all
|
||||
* the bdev moduless have finished their asynchronous I/O
|
||||
* the bdev modules have finished their asynchronous I/O
|
||||
* processing, the entire bdev layer can be marked as complete.
|
||||
*/
|
||||
spdk_bdev_init_complete(0);
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_bdev_module_action_done(struct spdk_bdev_module_if *module)
|
||||
{
|
||||
assert(module->action_in_progress > 0);
|
||||
module->action_in_progress--;
|
||||
spdk_bdev_module_action_complete();
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_module_init_done(struct spdk_bdev_module_if *module)
|
||||
{
|
||||
spdk_bdev_module_action_done(module);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module)
|
||||
{
|
||||
spdk_bdev_module_action_done(module);
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_bdev_modules_init(void)
|
||||
{
|
||||
@ -1433,7 +1462,7 @@ _spdk_bdev_register(struct spdk_bdev *bdev)
|
||||
|
||||
TAILQ_FOREACH(module, &g_bdev_mgr.bdev_modules, tailq) {
|
||||
if (module->examine) {
|
||||
module->examine_in_progress++;
|
||||
module->action_in_progress++;
|
||||
module->examine(bdev);
|
||||
}
|
||||
}
|
||||
@ -1510,24 +1539,6 @@ spdk_vbdev_unregister(struct spdk_bdev *vbdev)
|
||||
spdk_bdev_unregister(vbdev);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module)
|
||||
{
|
||||
assert(module->examine_in_progress > 0);
|
||||
module->examine_in_progress--;
|
||||
|
||||
if (!g_bdev_mgr.module_init_complete || g_bdev_mgr.init_complete) {
|
||||
/*
|
||||
* Don't finish bdev subsystem initialization if
|
||||
* module initialization is still in progress, or
|
||||
* the subsystem been already initialized.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_bdev_module_action_complete();
|
||||
}
|
||||
|
||||
int
|
||||
spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb,
|
||||
void *remove_ctx, struct spdk_bdev_desc **_desc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user