Spdk/lib/ftl/mngt/ftl_mngt_ioch.c
paul luse a6dbe3721e update Intel copyright notices
per Intel policy to include file commit date using git cmd
below.  The policy does not apply to non-Intel (C) notices.

git log --follow -C90% --format=%ad --date default <file> | tail -1

and then pull just the 4 digit year from the result.

Intel copyrights were not added to files where Intel either had
no contribution ot the contribution lacked substance (ie license
header updates, formatting changes, etc).  Contribution date used
"--follow -C95%" to get the most accurate date.

Note that several files in this patch didn't end the license/(c)
block with a blank comment line so these were added as the vast
majority of files do have this last blank line.  Simply there for
consistency.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: Id5b7ce4f658fe87132f14139ead58d6e285c04d4
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15192
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
2022-11-10 08:28:53 +00:00

203 lines
4.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C) 2022 Intel Corporation.
* All rights reserved.
*/
#include "spdk/thread.h"
#include "ftl_core.h"
#include "ftl_mngt.h"
#include "ftl_mngt_steps.h"
#include "ftl_band.h"
struct ftl_io_channel_ctx {
struct ftl_io_channel *ioch;
};
struct ftl_io_channel *
ftl_io_channel_get_ctx(struct spdk_io_channel *ioch)
{
struct ftl_io_channel_ctx *ctx = spdk_io_channel_get_ctx(ioch);
return ctx->ioch;
}
static void
ftl_dev_register_channel(void *ctx)
{
struct ftl_io_channel *ioch = ctx;
struct spdk_ftl_dev *dev = ioch->dev;
/* This only runs on the core thread, so it's safe to do this lockless */
TAILQ_INSERT_TAIL(&dev->ioch_queue, ioch, entry);
}
static void
io_channel_unregister(void *ctx)
{
struct ftl_io_channel *ioch = ctx;
struct spdk_ftl_dev *dev = ioch->dev;
TAILQ_REMOVE(&dev->ioch_queue, ioch, entry);
spdk_ring_free(ioch->cq);
spdk_ring_free(ioch->sq);
ftl_mempool_destroy(ioch->map_pool);
free(ioch);
}
static int
io_channel_create_cb(void *io_device, void *ctx)
{
struct spdk_ftl_dev *dev = io_device;
struct ftl_io_channel_ctx *_ioch = ctx;
struct ftl_io_channel *ioch;
char mempool_name[32];
int rc;
FTL_NOTICELOG(dev, "FTL IO channel created on %s\n",
spdk_thread_get_name(spdk_get_thread()));
/* This gets unregistered asynchronously with the device -
* we can't just use the ctx buffer passed by the thread library
*/
ioch = calloc(1, sizeof(*ioch));
if (ioch == NULL) {
FTL_ERRLOG(dev, "Failed to allocate IO channel\n");
return -1;
}
rc = snprintf(mempool_name, sizeof(mempool_name), "ftl_io_%p", ioch);
if (rc < 0 || rc >= (int)sizeof(mempool_name)) {
FTL_ERRLOG(dev, "Failed to create IO channel pool name\n");
free(ioch);
return -1;
}
ioch->dev = dev;
ioch->map_pool = ftl_mempool_create(
dev->conf.user_io_pool_size,
sizeof(ftl_addr) * dev->xfer_size,
64,
SPDK_ENV_SOCKET_ID_ANY);
if (!ioch->map_pool) {
FTL_ERRLOG(dev, "Failed to create IO channel's map IO pool\n");
goto fail_io_pool;
}
ioch->cq = spdk_ring_create(SPDK_RING_TYPE_SP_SC, spdk_align64pow2(dev->conf.user_io_pool_size + 1),
SPDK_ENV_SOCKET_ID_ANY);
if (!ioch->cq) {
FTL_ERRLOG(dev, "Failed to create IO channel completion queue\n");
goto fail_io_pool;
}
ioch->sq = spdk_ring_create(SPDK_RING_TYPE_SP_SC, spdk_align64pow2(dev->conf.user_io_pool_size + 1),
SPDK_ENV_SOCKET_ID_ANY);
if (!ioch->sq) {
FTL_ERRLOG(dev, "Failed to create IO channel submission queue\n");
goto fail_cq;
}
ioch->poller = SPDK_POLLER_REGISTER(ftl_io_channel_poll, ioch, 0);
if (!ioch->poller) {
FTL_ERRLOG(dev, "Failed to register IO channel poller\n");
goto fail_sq;
}
if (spdk_thread_send_msg(dev->core_thread, ftl_dev_register_channel, ioch)) {
FTL_ERRLOG(dev, "Failed to register IO channel\n");
goto fail_poller;
}
_ioch->ioch = ioch;
return 0;
fail_poller:
spdk_poller_unregister(&ioch->poller);
fail_cq:
spdk_ring_free(ioch->cq);
fail_sq:
spdk_ring_free(ioch->sq);
fail_io_pool:
ftl_mempool_destroy(ioch->map_pool);
free(ioch);
return -1;
}
static void
io_channel_destroy_cb(void *io_device, void *ctx)
{
struct ftl_io_channel_ctx *_ioch = ctx;
struct ftl_io_channel *ioch = _ioch->ioch;
struct spdk_ftl_dev *dev = ioch->dev;
FTL_NOTICELOG(dev, "FTL IO channel destroy on %s\n",
spdk_thread_get_name(spdk_get_thread()));
spdk_poller_unregister(&ioch->poller);
spdk_thread_send_msg(ftl_get_core_thread(dev),
io_channel_unregister, ioch);
}
void
ftl_mngt_register_io_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
dev->io_device_registered = true;
spdk_io_device_register(dev, io_channel_create_cb,
io_channel_destroy_cb,
sizeof(struct ftl_io_channel_ctx),
NULL);
ftl_mngt_next_step(mngt);
}
static void
unregister_cb(void *io_device)
{
struct spdk_ftl_dev *dev = io_device;
struct ftl_mngt_process *mngt = dev->unregister_process;
dev->io_device_registered = false;
dev->unregister_process = NULL;
ftl_mngt_next_step(mngt);
}
void
ftl_mngt_unregister_io_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
if (dev->io_device_registered) {
dev->unregister_process = mngt;
spdk_io_device_unregister(dev, unregister_cb);
} else {
ftl_mngt_skip_step(mngt);
}
}
void
ftl_mngt_init_io_channel(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
dev->ioch = spdk_get_io_channel(dev);
if (!dev->ioch) {
FTL_ERRLOG(dev, "Unable to get IO channel for core thread");
ftl_mngt_fail_step(mngt);
return;
}
ftl_mngt_next_step(mngt);
}
void
ftl_mngt_deinit_io_channel(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
if (dev->ioch) {
spdk_put_io_channel(dev->ioch);
dev->ioch = NULL;
}
ftl_mngt_next_step(mngt);
}