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