2022-06-21 13:31:54 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2022-11-01 20:26:26 +00:00
|
|
|
* Copyright (C) 2022 Intel Corporation.
|
2022-06-21 13:31:54 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*/
|
2022-11-01 20:26:26 +00:00
|
|
|
|
2022-06-21 13:31:54 +00:00
|
|
|
#include "spdk/ftl.h"
|
|
|
|
|
|
|
|
#include "ftl_conf.h"
|
|
|
|
#include "ftl_core.h"
|
|
|
|
|
2022-06-21 13:45:21 +00:00
|
|
|
static const struct spdk_ftl_conf g_default_conf = {
|
2022-06-14 10:01:11 +00:00
|
|
|
/* 2 free bands - compaction is blocked, gc only */
|
|
|
|
.limits[SPDK_FTL_LIMIT_CRIT] = 2,
|
|
|
|
/* 3 free bands */
|
|
|
|
.limits[SPDK_FTL_LIMIT_HIGH] = 3,
|
|
|
|
/* 4 free bands */
|
|
|
|
.limits[SPDK_FTL_LIMIT_LOW] = 4,
|
|
|
|
/* 5 free bands - gc starts running */
|
|
|
|
.limits[SPDK_FTL_LIMIT_START] = 5,
|
2022-06-21 13:45:21 +00:00
|
|
|
/* 20% spare blocks */
|
|
|
|
.overprovisioning = 20,
|
2022-06-15 12:35:46 +00:00
|
|
|
/* 2GiB of DRAM for l2p cache */
|
|
|
|
.l2p_dram_limit = 2048,
|
2022-06-21 13:45:21 +00:00
|
|
|
/* IO pool size per user thread (this should be adjusted to thread IO qdepth) */
|
|
|
|
.user_io_pool_size = 2048,
|
2022-06-03 10:59:17 +00:00
|
|
|
.nv_cache = {
|
|
|
|
.chunk_compaction_threshold = 80,
|
2022-05-27 11:57:30 +00:00
|
|
|
.chunk_free_target = 5,
|
2022-06-03 10:59:17 +00:00
|
|
|
},
|
2022-06-10 12:15:35 +00:00
|
|
|
.fast_shutdown = true,
|
2022-06-21 13:45:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
2022-07-14 17:22:00 +00:00
|
|
|
spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size)
|
2022-06-21 13:45:21 +00:00
|
|
|
{
|
2022-07-14 17:22:00 +00:00
|
|
|
assert(conf_size > 0);
|
|
|
|
assert(conf_size <= sizeof(struct spdk_ftl_conf));
|
|
|
|
|
|
|
|
memcpy(conf, &g_default_conf, conf_size);
|
|
|
|
conf->conf_size = conf_size;
|
2022-06-21 13:45:21 +00:00
|
|
|
}
|
|
|
|
|
2022-06-21 11:03:44 +00:00
|
|
|
void
|
2022-07-14 17:22:00 +00:00
|
|
|
spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, size_t conf_size)
|
2022-06-21 11:03:44 +00:00
|
|
|
{
|
2022-07-14 17:22:00 +00:00
|
|
|
assert(conf_size > 0);
|
|
|
|
assert(conf_size <= sizeof(struct spdk_ftl_conf));
|
|
|
|
|
|
|
|
memcpy(conf, &dev->conf, conf_size);
|
|
|
|
conf->conf_size = conf_size;
|
2022-06-21 11:03:44 +00:00
|
|
|
}
|
|
|
|
|
2022-06-21 13:31:54 +00:00
|
|
|
int
|
2022-06-21 09:20:47 +00:00
|
|
|
spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
|
2022-06-21 13:31:54 +00:00
|
|
|
{
|
2022-06-21 13:45:21 +00:00
|
|
|
char *name = NULL;
|
2022-06-21 13:31:54 +00:00
|
|
|
char *core_mask = NULL;
|
|
|
|
char *base_bdev = NULL;
|
|
|
|
char *cache_bdev = NULL;
|
|
|
|
|
2022-07-14 17:22:00 +00:00
|
|
|
if (!src->conf_size || src->conf_size > sizeof(struct spdk_ftl_conf)) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-06-21 13:45:21 +00:00
|
|
|
if (src->name) {
|
|
|
|
name = strdup(src->name);
|
|
|
|
if (!name) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
2022-06-21 13:31:54 +00:00
|
|
|
if (src->core_mask) {
|
|
|
|
core_mask = strdup(src->core_mask);
|
|
|
|
if (!core_mask) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (src->base_bdev) {
|
|
|
|
base_bdev = strdup(src->base_bdev);
|
|
|
|
if (!base_bdev) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (src->cache_bdev) {
|
|
|
|
cache_bdev = strdup(src->cache_bdev);
|
|
|
|
if (!cache_bdev) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-14 17:22:00 +00:00
|
|
|
memcpy(dst, src, src->conf_size);
|
|
|
|
|
2022-06-21 13:45:21 +00:00
|
|
|
dst->name = name;
|
2022-06-21 13:31:54 +00:00
|
|
|
dst->core_mask = core_mask;
|
|
|
|
dst->base_bdev = base_bdev;
|
|
|
|
dst->cache_bdev = cache_bdev;
|
|
|
|
return 0;
|
|
|
|
error:
|
2022-06-21 13:45:21 +00:00
|
|
|
free(name);
|
2022-06-21 13:31:54 +00:00
|
|
|
free(core_mask);
|
|
|
|
free(base_bdev);
|
|
|
|
free(cache_bdev);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-06-21 09:20:47 +00:00
|
|
|
spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
|
2022-06-21 13:31:54 +00:00
|
|
|
{
|
2022-06-21 13:45:21 +00:00
|
|
|
free(conf->name);
|
2022-06-21 13:31:54 +00:00
|
|
|
free(conf->core_mask);
|
|
|
|
free(conf->base_bdev);
|
|
|
|
free(conf->cache_bdev);
|
|
|
|
}
|
2022-06-21 13:45:21 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
2022-07-14 17:22:00 +00:00
|
|
|
if (!conf->conf_size) {
|
|
|
|
FTL_ERRLOG(dev, "FTL configuration is uninitialized\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-06-21 13:45:21 +00:00
|
|
|
if (!conf->name) {
|
|
|
|
FTL_ERRLOG(dev, "No FTL name in configuration\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (!conf->base_bdev) {
|
|
|
|
FTL_ERRLOG(dev, "No base device in configuration\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (!conf->cache_bdev) {
|
|
|
|
FTL_ERRLOG(dev, "No NV cache device in configuration\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-06-21 09:20:47 +00:00
|
|
|
rc = spdk_ftl_conf_copy(&dev->conf, conf);
|
2022-06-21 13:45:21 +00:00
|
|
|
if (rc) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2022-06-14 10:01:11 +00:00
|
|
|
dev->limit = SPDK_FTL_LIMIT_MAX;
|
2022-06-21 13:45:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2022-06-20 10:00:04 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
|
|
|
|
{
|
|
|
|
if (conf->overprovisioning >= 100) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (conf->overprovisioning == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-06-03 10:59:17 +00:00
|
|
|
if (conf->nv_cache.chunk_compaction_threshold == 0 ||
|
|
|
|
conf->nv_cache.chunk_compaction_threshold > 100) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-05-27 11:57:30 +00:00
|
|
|
if (conf->nv_cache.chunk_free_target == 0 || conf->nv_cache.chunk_free_target > 100) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-06-20 10:00:04 +00:00
|
|
|
return true;
|
|
|
|
}
|