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
203 lines
4.7 KiB
C
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);
|
|
}
|