lib/ftl: Make ANM device unregister asynchronous

We need to wait for ANV event completions when
unregistering device.

Change-Id: I872297da98405f16804a6fa1eb1149f0ee55b00c
Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468600
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Wojciech Malikowski 2019-09-17 09:45:13 -04:00 committed by Jim Harris
parent 984a11ad65
commit 42b287e661
3 changed files with 59 additions and 13 deletions

View File

@ -450,9 +450,11 @@ out:
return rc;
}
void
ftl_anm_unregister_device(struct spdk_ftl_dev *dev)
static void
ftl_anm_unregister_device_cb(void *ctx)
{
struct ftl_anm_init_ctx *init_ctx = ctx;
struct spdk_ftl_dev *dev = init_ctx->cb_arg;
struct ftl_anm_ctrlr *ctrlr;
struct ftl_anm_poller *poller, *temp_poller;
@ -472,11 +474,37 @@ ftl_anm_unregister_device(struct spdk_ftl_dev *dev)
/* Release the controller if there are no more pollers */
if (LIST_EMPTY(&ctrlr->pollers)) {
LIST_REMOVE(ctrlr, list_entry);
ftl_anm_ctrlr_free(ctrlr);
if (!ctrlr->processing) {
LIST_REMOVE(ctrlr, list_entry);
ftl_anm_ctrlr_free(ctrlr);
} else {
pthread_mutex_unlock(&g_anm.lock);
spdk_thread_send_msg(g_anm.thread, ftl_anm_unregister_device_cb, ctx);
return;
}
}
pthread_mutex_unlock(&g_anm.lock);
init_ctx->cb(init_ctx->cb_arg, 0);
free(init_ctx);
}
int
ftl_anm_unregister_device(struct spdk_ftl_dev *dev, spdk_ftl_fn cb)
{
struct ftl_anm_init_ctx *ctx;
ctx = malloc(sizeof(*ctx));
if (!ctx) {
return -ENOMEM;
}
ctx->cb = cb;
ctx->cb_arg = dev;
spdk_thread_send_msg(g_anm.thread, ftl_anm_unregister_device_cb, ctx);
return 0;
}
static void

View File

@ -64,7 +64,7 @@ struct ftl_anm_event {
int ftl_anm_init(struct spdk_thread *thread, spdk_ftl_fn cb, void *cb_arg);
int ftl_anm_free(spdk_ftl_fn cb, void *cb_arg);
int ftl_anm_register_device(struct spdk_ftl_dev *dev, ftl_anm_fn fn);
void ftl_anm_unregister_device(struct spdk_ftl_dev *dev);
int ftl_anm_unregister_device(struct spdk_ftl_dev *dev, spdk_ftl_fn cb);
void ftl_anm_event_complete(struct ftl_anm_event *event);
#endif /* FTL_ANM_H */

View File

@ -1306,21 +1306,39 @@ ftl_nv_cache_header_fini_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb
spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev);
}
static void
_ftl_anm_unregister_cb(void *ctx)
{
struct spdk_ftl_dev *dev = ctx;
if (ftl_dev_has_nv_cache(dev)) {
ftl_nv_cache_write_header(&dev->nv_cache, true, ftl_nv_cache_header_fini_cb, dev);
} else {
dev->halt_complete_status = 0;
spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev);
}
}
static void
ftl_anm_unregister_cb(void *ctx, int status)
{
struct spdk_ftl_dev *dev = ctx;
spdk_thread_send_msg(ftl_get_core_thread(dev), _ftl_anm_unregister_cb, dev);
}
static int
ftl_halt_poller(void *ctx)
{
struct spdk_ftl_dev *dev = ctx;
int rc;
if (!dev->core_thread.poller && !dev->read_thread.poller) {
spdk_poller_unregister(&dev->fini_ctx.poller);
ftl_anm_unregister_device(dev);
if (ftl_dev_has_nv_cache(dev)) {
ftl_nv_cache_write_header(&dev->nv_cache, true, ftl_nv_cache_header_fini_cb, dev);
rc = ftl_anm_unregister_device(dev, ftl_anm_unregister_cb);
if (spdk_unlikely(rc != 0)) {
SPDK_ERRLOG("Failed to unregister ANM device, will retry later\n");
} else {
dev->halt_complete_status = 0;
spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev);
spdk_poller_unregister(&dev->fini_ctx.poller);
}
}