lib/ftl: notify init/fini callbacks on proper threads
This patch makes sure we're on the thread that requested creation / deletion of the device when calling the notification callback. Change-Id: Ia11a8054692874f6b57d4ebe3e3cb290c58e83b6 Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459618 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com> Reviewed-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
0f7080e779
commit
78097953f7
@ -216,7 +216,7 @@ int spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *opts, spdk_ftl_init_f
|
|||||||
*
|
*
|
||||||
* \return 0 if successfully scheduled free, negative errno otherwise.
|
* \return 0 if successfully scheduled free, negative errno otherwise.
|
||||||
*/
|
*/
|
||||||
int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg);
|
int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb, void *cb_arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize FTL configuration structure with default values.
|
* Initialize FTL configuration structure with default values.
|
||||||
|
@ -181,7 +181,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bdev_ftl_free_cb(void *ctx, int status)
|
bdev_ftl_free_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
|
||||||
{
|
{
|
||||||
struct ftl_bdev *ftl_bdev = ctx;
|
struct ftl_bdev *ftl_bdev = ctx;
|
||||||
bool finish_done;
|
bool finish_done;
|
||||||
|
@ -130,6 +130,17 @@ struct ftl_nv_cache {
|
|||||||
pthread_spinlock_t lock;
|
pthread_spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ftl_init_context {
|
||||||
|
/* User's callback */
|
||||||
|
spdk_ftl_init_fn cb_fn;
|
||||||
|
/* Callback's argument */
|
||||||
|
void *cb_arg;
|
||||||
|
/* Thread to call the callback on */
|
||||||
|
struct spdk_thread *thread;
|
||||||
|
/* Poller to check if the device has been destroyed/initialized */
|
||||||
|
struct spdk_poller *poller;
|
||||||
|
};
|
||||||
|
|
||||||
struct spdk_ftl_dev {
|
struct spdk_ftl_dev {
|
||||||
/* Device instance */
|
/* Device instance */
|
||||||
struct spdk_uuid uuid;
|
struct spdk_uuid uuid;
|
||||||
@ -143,17 +154,10 @@ struct spdk_ftl_dev {
|
|||||||
/* Indicates the device is about to be stopped */
|
/* Indicates the device is about to be stopped */
|
||||||
int halt;
|
int halt;
|
||||||
|
|
||||||
/* Init callback */
|
/* Initializaton context */
|
||||||
spdk_ftl_init_fn init_cb;
|
struct ftl_init_context init_ctx;
|
||||||
/* Init callback's context */
|
/* Destruction context */
|
||||||
void *init_arg;
|
struct ftl_init_context fini_ctx;
|
||||||
|
|
||||||
/* Halt callback */
|
|
||||||
spdk_ftl_fn halt_cb;
|
|
||||||
/* Halt callback's context */
|
|
||||||
void *halt_arg;
|
|
||||||
/* Halt poller, checks if the device has been halted */
|
|
||||||
struct spdk_poller *halt_poller;
|
|
||||||
|
|
||||||
/* IO channel */
|
/* IO channel */
|
||||||
struct spdk_io_channel *ioch;
|
struct spdk_io_channel *ioch;
|
||||||
|
@ -811,6 +811,17 @@ ftl_dev_l2p_alloc(struct spdk_ftl_dev *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ftl_call_init_complete_cb(void *_ctx)
|
||||||
|
{
|
||||||
|
struct ftl_init_context *ctx = _ctx;
|
||||||
|
struct spdk_ftl_dev *dev = SPDK_CONTAINEROF(ctx, struct spdk_ftl_dev, init_ctx);
|
||||||
|
|
||||||
|
if (ctx->cb_fn != NULL) {
|
||||||
|
ctx->cb_fn(dev, ctx->cb_arg, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftl_init_complete(struct spdk_ftl_dev *dev)
|
ftl_init_complete(struct spdk_ftl_dev *dev)
|
||||||
{
|
{
|
||||||
@ -820,44 +831,37 @@ ftl_init_complete(struct spdk_ftl_dev *dev)
|
|||||||
|
|
||||||
dev->initialized = 1;
|
dev->initialized = 1;
|
||||||
|
|
||||||
if (dev->init_cb) {
|
spdk_thread_send_msg(dev->init_ctx.thread, ftl_call_init_complete_cb, &dev->init_ctx);
|
||||||
dev->init_cb(dev, dev->init_arg, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->init_cb = NULL;
|
|
||||||
dev->init_arg = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ftl_init_fail_ctx {
|
|
||||||
spdk_ftl_init_fn cb;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftl_init_fail_cb(void *ctx, int status)
|
ftl_init_fail_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
|
||||||
{
|
{
|
||||||
struct ftl_init_fail_ctx *fail_cb = ctx;
|
struct ftl_init_context *ctx = _ctx;
|
||||||
|
|
||||||
fail_cb->cb(NULL, fail_cb->arg, -ENODEV);
|
if (ctx->cb_fn != NULL) {
|
||||||
free(fail_cb);
|
ctx->cb_fn(NULL, ctx->cb_arg, -ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb_fn, void *cb_arg,
|
||||||
|
struct spdk_thread *thread);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftl_init_fail(struct spdk_ftl_dev *dev)
|
ftl_init_fail(struct spdk_ftl_dev *dev)
|
||||||
{
|
{
|
||||||
struct ftl_init_fail_ctx *fail_cb;
|
struct ftl_init_context *ctx;
|
||||||
|
|
||||||
fail_cb = malloc(sizeof(*fail_cb));
|
ctx = malloc(sizeof(*ctx));
|
||||||
if (!fail_cb) {
|
if (!ctx) {
|
||||||
SPDK_ERRLOG("Unable to allocate context to free the device\n");
|
SPDK_ERRLOG("Unable to allocate context to free the device\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail_cb->cb = dev->init_cb;
|
*ctx = dev->init_ctx;
|
||||||
fail_cb->arg = dev->init_arg;
|
if (_spdk_ftl_dev_free(dev, ftl_init_fail_cb, ctx, ctx->thread)) {
|
||||||
dev->halt_cb = NULL;
|
|
||||||
|
|
||||||
if (spdk_ftl_dev_free(dev, ftl_init_fail_cb, fail_cb)) {
|
|
||||||
SPDK_ERRLOG("Unable to free the device\n");
|
SPDK_ERRLOG("Unable to free the device\n");
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@ -1108,7 +1112,7 @@ ftl_dev_init_io_channel(struct spdk_ftl_dev *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn cb, void *cb_arg)
|
spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn cb_fn, void *cb_arg)
|
||||||
{
|
{
|
||||||
struct spdk_ftl_dev *dev;
|
struct spdk_ftl_dev *dev;
|
||||||
struct spdk_ftl_dev_init_opts opts = *_opts;
|
struct spdk_ftl_dev_init_opts opts = *_opts;
|
||||||
@ -1124,8 +1128,9 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
|
|||||||
|
|
||||||
TAILQ_INIT(&dev->retry_queue);
|
TAILQ_INIT(&dev->retry_queue);
|
||||||
dev->conf = *opts.conf;
|
dev->conf = *opts.conf;
|
||||||
dev->init_cb = cb;
|
dev->init_ctx.cb_fn = cb_fn;
|
||||||
dev->init_arg = cb_arg;
|
dev->init_ctx.cb_arg = cb_arg;
|
||||||
|
dev->init_ctx.thread = spdk_get_thread();
|
||||||
dev->range = opts.range;
|
dev->range = opts.range;
|
||||||
dev->limit = SPDK_FTL_LIMIT_MAX;
|
dev->limit = SPDK_FTL_LIMIT_MAX;
|
||||||
|
|
||||||
@ -1287,25 +1292,33 @@ ftl_dev_free_sync(struct spdk_ftl_dev *dev)
|
|||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ftl_call_fini_complete_cb(void *_ctx)
|
||||||
|
{
|
||||||
|
struct spdk_ftl_dev *dev = _ctx;
|
||||||
|
struct ftl_init_context ctx = dev->fini_ctx;
|
||||||
|
|
||||||
|
ftl_dev_free_sync(dev);
|
||||||
|
|
||||||
|
if (ctx.cb_fn != NULL) {
|
||||||
|
ctx.cb_fn(NULL, ctx.cb_arg, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ftl_halt_poller(void *ctx)
|
ftl_halt_poller(void *ctx)
|
||||||
{
|
{
|
||||||
struct spdk_ftl_dev *dev = ctx;
|
struct spdk_ftl_dev *dev = ctx;
|
||||||
spdk_ftl_fn halt_cb = dev->halt_cb;
|
|
||||||
void *halt_arg = dev->halt_arg;
|
|
||||||
|
|
||||||
if (!dev->core_thread.poller && !dev->read_thread.poller) {
|
if (!dev->core_thread.poller && !dev->read_thread.poller) {
|
||||||
spdk_poller_unregister(&dev->halt_poller);
|
spdk_poller_unregister(&dev->fini_ctx.poller);
|
||||||
|
|
||||||
ftl_dev_free_thread(dev, &dev->read_thread);
|
ftl_dev_free_thread(dev, &dev->read_thread);
|
||||||
ftl_dev_free_thread(dev, &dev->core_thread);
|
ftl_dev_free_thread(dev, &dev->core_thread);
|
||||||
|
|
||||||
ftl_anm_unregister_device(dev);
|
ftl_anm_unregister_device(dev);
|
||||||
ftl_dev_free_sync(dev);
|
|
||||||
|
|
||||||
if (halt_cb) {
|
spdk_thread_send_msg(dev->fini_ctx.thread, ftl_call_fini_complete_cb, dev);
|
||||||
halt_cb(halt_arg, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1318,19 +1331,21 @@ ftl_add_halt_poller(void *ctx)
|
|||||||
|
|
||||||
_ftl_halt_defrag(dev);
|
_ftl_halt_defrag(dev);
|
||||||
|
|
||||||
assert(!dev->halt_poller);
|
assert(!dev->fini_ctx.poller);
|
||||||
dev->halt_poller = spdk_poller_register(ftl_halt_poller, dev, 100);
|
dev->fini_ctx.poller = spdk_poller_register(ftl_halt_poller, dev, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg)
|
_spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb_fn, void *cb_arg,
|
||||||
|
struct spdk_thread *thread)
|
||||||
{
|
{
|
||||||
if (dev->halt_cb) {
|
if (dev->fini_ctx.cb_fn != NULL) {
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->halt_cb = cb;
|
dev->fini_ctx.cb_fn = cb_fn;
|
||||||
dev->halt_arg = cb_arg;
|
dev->fini_ctx.cb_arg = cb_arg;
|
||||||
|
dev->fini_ctx.thread = thread;
|
||||||
dev->halt = 1;
|
dev->halt = 1;
|
||||||
|
|
||||||
ftl_rwb_disable_interleaving(dev->rwb);
|
ftl_rwb_disable_interleaving(dev->rwb);
|
||||||
@ -1339,6 +1354,12 @@ spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb_fn, void *cb_arg)
|
||||||
|
{
|
||||||
|
return _spdk_ftl_dev_free(dev, cb_fn, cb_arg, spdk_get_thread());
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_ftl_module_init(const struct ftl_module_init_opts *opts, spdk_ftl_fn cb, void *cb_arg)
|
spdk_ftl_module_init(const struct ftl_module_init_opts *opts, spdk_ftl_fn cb, void *cb_arg)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user