xref: /spdk/lib/ftl/utils/ftl_conf.c (revision ebcb0d71f74e28057761784512446b8a4ac70a5c)
1310836b9SArtur Paszkiewicz /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2022 Intel Corporation.
3310836b9SArtur Paszkiewicz  *   All rights reserved.
4310836b9SArtur Paszkiewicz  */
5a6dbe372Spaul luse 
6310836b9SArtur Paszkiewicz #include "spdk/ftl.h"
7310836b9SArtur Paszkiewicz 
8310836b9SArtur Paszkiewicz #include "ftl_conf.h"
9310836b9SArtur Paszkiewicz #include "ftl_core.h"
10217332a9SMateusz Kozlowski #include "ftl_utils.h"
11310836b9SArtur Paszkiewicz 
12e49ccfc8SArtur Paszkiewicz static const struct spdk_ftl_conf g_default_conf = {
130f99700dSArtur Paszkiewicz 	/* 2 free bands - compaction is blocked, gc only */
140f99700dSArtur Paszkiewicz 	.limits[SPDK_FTL_LIMIT_CRIT]	= 2,
150f99700dSArtur Paszkiewicz 	/* 3 free bands */
160f99700dSArtur Paszkiewicz 	.limits[SPDK_FTL_LIMIT_HIGH]	= 3,
170f99700dSArtur Paszkiewicz 	/* 4 free bands */
180f99700dSArtur Paszkiewicz 	.limits[SPDK_FTL_LIMIT_LOW]	= 4,
190f99700dSArtur Paszkiewicz 	/* 5 free bands - gc starts running */
200f99700dSArtur Paszkiewicz 	.limits[SPDK_FTL_LIMIT_START]	= 5,
21e49ccfc8SArtur Paszkiewicz 	/* 20% spare blocks */
22e49ccfc8SArtur Paszkiewicz 	.overprovisioning = 20,
23e7e5bc07SKozlowski Mateusz 	/* 2GiB of DRAM for l2p cache */
24e7e5bc07SKozlowski Mateusz 	.l2p_dram_limit = 2048,
25e49ccfc8SArtur Paszkiewicz 	/* IO pool size per user thread (this should be adjusted to thread IO qdepth) */
26e49ccfc8SArtur Paszkiewicz 	.user_io_pool_size = 2048,
2771f20c9aSKozlowski Mateusz 	.nv_cache = {
2871f20c9aSKozlowski Mateusz 		.chunk_compaction_threshold = 80,
2963b2fecbSArtur Paszkiewicz 		.chunk_free_target = 5,
3071f20c9aSKozlowski Mateusz 	},
310e33da49SKozlowski Mateusz 	.fast_shutdown = true,
32e49ccfc8SArtur Paszkiewicz };
33e49ccfc8SArtur Paszkiewicz 
34e49ccfc8SArtur Paszkiewicz void
spdk_ftl_get_default_conf(struct spdk_ftl_conf * conf,size_t conf_size)35d1dd6ca8SArtur Paszkiewicz spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size)
36e49ccfc8SArtur Paszkiewicz {
37d1dd6ca8SArtur Paszkiewicz 	assert(conf_size > 0);
38d1dd6ca8SArtur Paszkiewicz 	assert(conf_size <= sizeof(struct spdk_ftl_conf));
39d1dd6ca8SArtur Paszkiewicz 
40d1dd6ca8SArtur Paszkiewicz 	memcpy(conf, &g_default_conf, conf_size);
41d1dd6ca8SArtur Paszkiewicz 	conf->conf_size = conf_size;
42e49ccfc8SArtur Paszkiewicz }
43e49ccfc8SArtur Paszkiewicz 
44d974bad6SArtur Paszkiewicz void
spdk_ftl_dev_get_conf(const struct spdk_ftl_dev * dev,struct spdk_ftl_conf * conf,size_t conf_size)45d1dd6ca8SArtur Paszkiewicz spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, size_t conf_size)
46d974bad6SArtur Paszkiewicz {
47d1dd6ca8SArtur Paszkiewicz 	assert(conf_size > 0);
48d1dd6ca8SArtur Paszkiewicz 	assert(conf_size <= sizeof(struct spdk_ftl_conf));
49d1dd6ca8SArtur Paszkiewicz 
50d1dd6ca8SArtur Paszkiewicz 	memcpy(conf, &dev->conf, conf_size);
51d1dd6ca8SArtur Paszkiewicz 	conf->conf_size = conf_size;
52d974bad6SArtur Paszkiewicz }
53d974bad6SArtur Paszkiewicz 
54310836b9SArtur Paszkiewicz int
spdk_ftl_conf_copy(struct spdk_ftl_conf * dst,const struct spdk_ftl_conf * src)55c682c789SArtur Paszkiewicz spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
56310836b9SArtur Paszkiewicz {
57e49ccfc8SArtur Paszkiewicz 	char *name = NULL;
58310836b9SArtur Paszkiewicz 	char *core_mask = NULL;
59310836b9SArtur Paszkiewicz 	char *base_bdev = NULL;
60310836b9SArtur Paszkiewicz 	char *cache_bdev = NULL;
61310836b9SArtur Paszkiewicz 
62d1dd6ca8SArtur Paszkiewicz 	if (!src->conf_size || src->conf_size > sizeof(struct spdk_ftl_conf)) {
63d1dd6ca8SArtur Paszkiewicz 		return -EINVAL;
64d1dd6ca8SArtur Paszkiewicz 	}
65d1dd6ca8SArtur Paszkiewicz 
66e49ccfc8SArtur Paszkiewicz 	if (src->name) {
67e49ccfc8SArtur Paszkiewicz 		name = strdup(src->name);
68e49ccfc8SArtur Paszkiewicz 		if (!name) {
69e49ccfc8SArtur Paszkiewicz 			goto error;
70e49ccfc8SArtur Paszkiewicz 		}
71e49ccfc8SArtur Paszkiewicz 	}
72310836b9SArtur Paszkiewicz 	if (src->core_mask) {
73310836b9SArtur Paszkiewicz 		core_mask = strdup(src->core_mask);
74310836b9SArtur Paszkiewicz 		if (!core_mask) {
75310836b9SArtur Paszkiewicz 			goto error;
76310836b9SArtur Paszkiewicz 		}
77310836b9SArtur Paszkiewicz 	}
78310836b9SArtur Paszkiewicz 	if (src->base_bdev) {
79310836b9SArtur Paszkiewicz 		base_bdev = strdup(src->base_bdev);
80310836b9SArtur Paszkiewicz 		if (!base_bdev) {
81310836b9SArtur Paszkiewicz 			goto error;
82310836b9SArtur Paszkiewicz 		}
83310836b9SArtur Paszkiewicz 	}
84310836b9SArtur Paszkiewicz 	if (src->cache_bdev) {
85310836b9SArtur Paszkiewicz 		cache_bdev = strdup(src->cache_bdev);
86310836b9SArtur Paszkiewicz 		if (!cache_bdev) {
87310836b9SArtur Paszkiewicz 			goto error;
88310836b9SArtur Paszkiewicz 		}
89310836b9SArtur Paszkiewicz 	}
90310836b9SArtur Paszkiewicz 
91d1dd6ca8SArtur Paszkiewicz 	memcpy(dst, src, src->conf_size);
92d1dd6ca8SArtur Paszkiewicz 
93e49ccfc8SArtur Paszkiewicz 	dst->name = name;
94310836b9SArtur Paszkiewicz 	dst->core_mask = core_mask;
95310836b9SArtur Paszkiewicz 	dst->base_bdev = base_bdev;
96310836b9SArtur Paszkiewicz 	dst->cache_bdev = cache_bdev;
97310836b9SArtur Paszkiewicz 	return 0;
98310836b9SArtur Paszkiewicz error:
99e49ccfc8SArtur Paszkiewicz 	free(name);
100310836b9SArtur Paszkiewicz 	free(core_mask);
101310836b9SArtur Paszkiewicz 	free(base_bdev);
102310836b9SArtur Paszkiewicz 	free(cache_bdev);
103310836b9SArtur Paszkiewicz 	return -ENOMEM;
104310836b9SArtur Paszkiewicz }
105310836b9SArtur Paszkiewicz 
106310836b9SArtur Paszkiewicz void
spdk_ftl_conf_deinit(struct spdk_ftl_conf * conf)107c682c789SArtur Paszkiewicz spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
108310836b9SArtur Paszkiewicz {
109e49ccfc8SArtur Paszkiewicz 	free(conf->name);
110310836b9SArtur Paszkiewicz 	free(conf->core_mask);
111310836b9SArtur Paszkiewicz 	free(conf->base_bdev);
112310836b9SArtur Paszkiewicz 	free(conf->cache_bdev);
113310836b9SArtur Paszkiewicz }
114e49ccfc8SArtur Paszkiewicz 
115e49ccfc8SArtur Paszkiewicz int
ftl_conf_init_dev(struct spdk_ftl_dev * dev,const struct spdk_ftl_conf * conf)116e49ccfc8SArtur Paszkiewicz ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
117e49ccfc8SArtur Paszkiewicz {
118e49ccfc8SArtur Paszkiewicz 	int rc;
119e49ccfc8SArtur Paszkiewicz 
120d1dd6ca8SArtur Paszkiewicz 	if (!conf->conf_size) {
121d1dd6ca8SArtur Paszkiewicz 		FTL_ERRLOG(dev, "FTL configuration is uninitialized\n");
122d1dd6ca8SArtur Paszkiewicz 		return -EINVAL;
123d1dd6ca8SArtur Paszkiewicz 	}
124d1dd6ca8SArtur Paszkiewicz 
125e49ccfc8SArtur Paszkiewicz 	if (!conf->name) {
126e49ccfc8SArtur Paszkiewicz 		FTL_ERRLOG(dev, "No FTL name in configuration\n");
127e49ccfc8SArtur Paszkiewicz 		return -EINVAL;
128e49ccfc8SArtur Paszkiewicz 	}
129e49ccfc8SArtur Paszkiewicz 	if (!conf->base_bdev) {
130e49ccfc8SArtur Paszkiewicz 		FTL_ERRLOG(dev, "No base device in configuration\n");
131e49ccfc8SArtur Paszkiewicz 		return -EINVAL;
132e49ccfc8SArtur Paszkiewicz 	}
133e49ccfc8SArtur Paszkiewicz 	if (!conf->cache_bdev) {
134e49ccfc8SArtur Paszkiewicz 		FTL_ERRLOG(dev, "No NV cache device in configuration\n");
135e49ccfc8SArtur Paszkiewicz 		return -EINVAL;
136e49ccfc8SArtur Paszkiewicz 	}
137e49ccfc8SArtur Paszkiewicz 
138c682c789SArtur Paszkiewicz 	rc = spdk_ftl_conf_copy(&dev->conf, conf);
139e49ccfc8SArtur Paszkiewicz 	if (rc) {
140e49ccfc8SArtur Paszkiewicz 		return rc;
141e49ccfc8SArtur Paszkiewicz 	}
142e49ccfc8SArtur Paszkiewicz 
1430f99700dSArtur Paszkiewicz 	dev->limit = SPDK_FTL_LIMIT_MAX;
144217332a9SMateusz Kozlowski 
145217332a9SMateusz Kozlowski 	ftl_property_register_bool_rw(dev, "prep_upgrade_on_shutdown", &dev->conf.prep_upgrade_on_shutdown,
146217332a9SMateusz Kozlowski 				      "", "During shutdown, FTL executes all actions which "
147*ebcb0d71SMateusz Kozlowski 				      "are needed for upgrade to a new version", false);
148*ebcb0d71SMateusz Kozlowski 
149*ebcb0d71SMateusz Kozlowski 	ftl_property_register_bool_rw(dev, "verbose_mode", &dev->conf.verbose_mode,
150*ebcb0d71SMateusz Kozlowski 				      "", "In verbose mode, user is able to get access to additional "
151*ebcb0d71SMateusz Kozlowski 				      "advanced FTL properties", false);
152217332a9SMateusz Kozlowski 
153e49ccfc8SArtur Paszkiewicz 	return 0;
154e49ccfc8SArtur Paszkiewicz }
155b872e29fSKozlowski Mateusz 
156b872e29fSKozlowski Mateusz bool
ftl_conf_is_valid(const struct spdk_ftl_conf * conf)157b872e29fSKozlowski Mateusz ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
158b872e29fSKozlowski Mateusz {
159b872e29fSKozlowski Mateusz 	if (conf->overprovisioning >= 100) {
160b872e29fSKozlowski Mateusz 		return false;
161b872e29fSKozlowski Mateusz 	}
162b872e29fSKozlowski Mateusz 	if (conf->overprovisioning == 0) {
163b872e29fSKozlowski Mateusz 		return false;
164b872e29fSKozlowski Mateusz 	}
165b872e29fSKozlowski Mateusz 
16671f20c9aSKozlowski Mateusz 	if (conf->nv_cache.chunk_compaction_threshold == 0 ||
16771f20c9aSKozlowski Mateusz 	    conf->nv_cache.chunk_compaction_threshold > 100) {
16871f20c9aSKozlowski Mateusz 		return false;
16971f20c9aSKozlowski Mateusz 	}
17071f20c9aSKozlowski Mateusz 
17163b2fecbSArtur Paszkiewicz 	if (conf->nv_cache.chunk_free_target == 0 || conf->nv_cache.chunk_free_target > 100) {
17263b2fecbSArtur Paszkiewicz 		return false;
17363b2fecbSArtur Paszkiewicz 	}
17463b2fecbSArtur Paszkiewicz 
175a7f4a2dbSKozlowski Mateusz 	if (conf->l2p_dram_limit == 0) {
176a7f4a2dbSKozlowski Mateusz 		return false;
177a7f4a2dbSKozlowski Mateusz 	}
178a7f4a2dbSKozlowski Mateusz 
179b872e29fSKozlowski Mateusz 	return true;
180b872e29fSKozlowski Mateusz }
181