Commit 42b287e6 authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Jim Harris
Browse files

lib/ftl: Make ANM device unregister asynchronous



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

Change-Id: I872297da98405f16804a6fa1eb1149f0ee55b00c
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468600


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent 984a11ad
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -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)) {
		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
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+26 −8
Original line number Diff line number Diff line
@@ -1306,16 +1306,11 @@ 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 int
ftl_halt_poller(void *ctx)
static void
_ftl_anm_unregister_cb(void *ctx)
{
	struct spdk_ftl_dev *dev = ctx;

	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);
	} else {
@@ -1324,6 +1319,29 @@ ftl_halt_poller(void *ctx)
	}
}

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) {
		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 {
			spdk_poller_unregister(&dev->fini_ctx.poller);
		}
	}

	return 0;
}