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);
|
void (*examine)(struct spdk_bdev *bdev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count of bdev examinations in progress. Used by generic bdev layer and must
|
* Count of bdev inits/examinations in progress. Used by generic bdev
|
||||||
* not be modified by bdev modules.
|
* 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;
|
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_vbdev_unregister(struct spdk_bdev *vbdev);
|
||||||
|
|
||||||
void spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module);
|
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,
|
int spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
||||||
struct spdk_bdev_module_if *module);
|
struct spdk_bdev_module_if *module);
|
||||||
void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev);
|
void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev);
|
||||||
@ -451,7 +451,17 @@ spdk_bdev_io_from_ctx(void *ctx)
|
|||||||
spdk_bdev_module_list_add(&_name ## _if); \
|
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
|
* 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;
|
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
|
* exist, return immediately since we cannot finish bdev subsystem
|
||||||
* initialization until all are completed.
|
* initialization until all are completed.
|
||||||
*/
|
*/
|
||||||
TAILQ_FOREACH(m, &g_bdev_mgr.bdev_modules, tailq) {
|
TAILQ_FOREACH(m, &g_bdev_mgr.bdev_modules, tailq) {
|
||||||
if (m->examine_in_progress > 0) {
|
if (m->action_in_progress > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modules already finished initialization - now that all
|
* 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.
|
* processing, the entire bdev layer can be marked as complete.
|
||||||
*/
|
*/
|
||||||
spdk_bdev_init_complete(0);
|
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
|
static int
|
||||||
spdk_bdev_modules_init(void)
|
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) {
|
TAILQ_FOREACH(module, &g_bdev_mgr.bdev_modules, tailq) {
|
||||||
if (module->examine) {
|
if (module->examine) {
|
||||||
module->examine_in_progress++;
|
module->action_in_progress++;
|
||||||
module->examine(bdev);
|
module->examine(bdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1510,24 +1539,6 @@ spdk_vbdev_unregister(struct spdk_bdev *vbdev)
|
|||||||
spdk_bdev_unregister(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
|
int
|
||||||
spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb,
|
spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb,
|
||||||
void *remove_ctx, struct spdk_bdev_desc **_desc)
|
void *remove_ctx, struct spdk_bdev_desc **_desc)
|
||||||
|
Loading…
Reference in New Issue
Block a user