xref: /spdk/lib/ftl/utils/ftl_conf.c (revision f8abbede89d30584d2a4f8427b13896f8591b873)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/ftl.h"
7 
8 #include "ftl_conf.h"
9 #include "ftl_core.h"
10 #include "ftl_utils.h"
11 
12 static const struct spdk_ftl_conf g_default_conf = {
13 	/* 2 free bands - compaction is blocked, gc only */
14 	.limits[SPDK_FTL_LIMIT_CRIT]	= 2,
15 	/* 3 free bands */
16 	.limits[SPDK_FTL_LIMIT_HIGH]	= 3,
17 	/* 4 free bands */
18 	.limits[SPDK_FTL_LIMIT_LOW]	= 4,
19 	/* 5 free bands - gc starts running */
20 	.limits[SPDK_FTL_LIMIT_START]	= 5,
21 	/* 20% spare blocks */
22 	.overprovisioning = 20,
23 	/* 2GiB of DRAM for l2p cache */
24 	.l2p_dram_limit = 2048,
25 	/* IO pool size per user thread (this should be adjusted to thread IO qdepth) */
26 	.user_io_pool_size = 2048,
27 	.nv_cache = {
28 		.chunk_compaction_threshold = 80,
29 		.chunk_free_target = 5,
30 	},
31 	.fast_shutdown = true,
32 };
33 
34 void
35 spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size)
36 {
37 	assert(conf_size > 0);
38 	assert(conf_size <= sizeof(struct spdk_ftl_conf));
39 
40 	memcpy(conf, &g_default_conf, conf_size);
41 	conf->conf_size = conf_size;
42 }
43 
44 void
45 spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, size_t conf_size)
46 {
47 	assert(conf_size > 0);
48 	assert(conf_size <= sizeof(struct spdk_ftl_conf));
49 
50 	memcpy(conf, &dev->conf, conf_size);
51 	conf->conf_size = conf_size;
52 }
53 
54 int
55 spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
56 {
57 	char *name = NULL;
58 	char *core_mask = NULL;
59 	char *base_bdev = NULL;
60 	char *cache_bdev = NULL;
61 
62 	if (!src->conf_size || src->conf_size > sizeof(struct spdk_ftl_conf)) {
63 		return -EINVAL;
64 	}
65 
66 	if (src->name) {
67 		name = strdup(src->name);
68 		if (!name) {
69 			goto error;
70 		}
71 	}
72 	if (src->core_mask) {
73 		core_mask = strdup(src->core_mask);
74 		if (!core_mask) {
75 			goto error;
76 		}
77 	}
78 	if (src->base_bdev) {
79 		base_bdev = strdup(src->base_bdev);
80 		if (!base_bdev) {
81 			goto error;
82 		}
83 	}
84 	if (src->cache_bdev) {
85 		cache_bdev = strdup(src->cache_bdev);
86 		if (!cache_bdev) {
87 			goto error;
88 		}
89 	}
90 
91 	memcpy(dst, src, src->conf_size);
92 
93 	dst->name = name;
94 	dst->core_mask = core_mask;
95 	dst->base_bdev = base_bdev;
96 	dst->cache_bdev = cache_bdev;
97 	return 0;
98 error:
99 	free(name);
100 	free(core_mask);
101 	free(base_bdev);
102 	free(cache_bdev);
103 	return -ENOMEM;
104 }
105 
106 void
107 spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
108 {
109 	free(conf->name);
110 	free(conf->core_mask);
111 	free(conf->base_bdev);
112 	free(conf->cache_bdev);
113 }
114 
115 int
116 ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
117 {
118 	int rc;
119 
120 	if (!conf->conf_size) {
121 		FTL_ERRLOG(dev, "FTL configuration is uninitialized\n");
122 		return -EINVAL;
123 	}
124 
125 	if (!conf->name) {
126 		FTL_ERRLOG(dev, "No FTL name in configuration\n");
127 		return -EINVAL;
128 	}
129 	if (!conf->base_bdev) {
130 		FTL_ERRLOG(dev, "No base device in configuration\n");
131 		return -EINVAL;
132 	}
133 	if (!conf->cache_bdev) {
134 		FTL_ERRLOG(dev, "No NV cache device in configuration\n");
135 		return -EINVAL;
136 	}
137 
138 	rc = spdk_ftl_conf_copy(&dev->conf, conf);
139 	if (rc) {
140 		return rc;
141 	}
142 
143 	dev->limit = SPDK_FTL_LIMIT_MAX;
144 
145 	ftl_property_register_bool_rw(dev, "prep_upgrade_on_shutdown", &dev->conf.prep_upgrade_on_shutdown,
146 				      "", "During shutdown, FTL executes all actions which "
147 				      "are needed for upgrade to a new version", false);
148 
149 	ftl_property_register_bool_rw(dev, "verbose_mode", &dev->conf.verbose_mode,
150 				      "", "In verbose mode, user is able to get access to additional "
151 				      "advanced FTL properties", false);
152 
153 	return 0;
154 }
155 
156 bool
157 ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
158 {
159 	if (conf->overprovisioning >= 100) {
160 		return false;
161 	}
162 	if (conf->overprovisioning == 0) {
163 		return false;
164 	}
165 
166 	if (conf->nv_cache.chunk_compaction_threshold == 0 ||
167 	    conf->nv_cache.chunk_compaction_threshold > 100) {
168 		return false;
169 	}
170 
171 	if (conf->nv_cache.chunk_free_target == 0 || conf->nv_cache.chunk_free_target > 100) {
172 		return false;
173 	}
174 
175 	if (conf->l2p_dram_limit == 0) {
176 		return false;
177 	}
178 
179 	return true;
180 }
181