xref: /spdk/lib/ftl/utils/ftl_conf.c (revision ffa823557a7c4c580cec5fb46c6c424c11b45458)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 #include "spdk/ftl.h"
6 
7 #include "ftl_conf.h"
8 #include "ftl_core.h"
9 
10 static const struct spdk_ftl_conf g_default_conf = {
11 	/* 2 free bands - compaction is blocked, gc only */
12 	.limits[SPDK_FTL_LIMIT_CRIT]	= 2,
13 	/* 3 free bands */
14 	.limits[SPDK_FTL_LIMIT_HIGH]	= 3,
15 	/* 4 free bands */
16 	.limits[SPDK_FTL_LIMIT_LOW]	= 4,
17 	/* 5 free bands - gc starts running */
18 	.limits[SPDK_FTL_LIMIT_START]	= 5,
19 	/* 20% spare blocks */
20 	.overprovisioning = 20,
21 	/* IO pool size per user thread (this should be adjusted to thread IO qdepth) */
22 	.user_io_pool_size = 2048,
23 	.nv_cache = {
24 		.chunk_compaction_threshold = 80,
25 	},
26 };
27 
28 void
29 spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf)
30 {
31 	*conf = g_default_conf;
32 }
33 
34 void
35 spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf)
36 {
37 	*conf = dev->conf;
38 }
39 
40 int
41 spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
42 {
43 	char *name = NULL;
44 	char *core_mask = NULL;
45 	char *base_bdev = NULL;
46 	char *cache_bdev = NULL;
47 
48 	if (src->name) {
49 		name = strdup(src->name);
50 		if (!name) {
51 			goto error;
52 		}
53 	}
54 	if (src->core_mask) {
55 		core_mask = strdup(src->core_mask);
56 		if (!core_mask) {
57 			goto error;
58 		}
59 	}
60 	if (src->base_bdev) {
61 		base_bdev = strdup(src->base_bdev);
62 		if (!base_bdev) {
63 			goto error;
64 		}
65 	}
66 	if (src->cache_bdev) {
67 		cache_bdev = strdup(src->cache_bdev);
68 		if (!cache_bdev) {
69 			goto error;
70 		}
71 	}
72 
73 	*dst = *src;
74 	dst->name = name;
75 	dst->core_mask = core_mask;
76 	dst->base_bdev = base_bdev;
77 	dst->cache_bdev = cache_bdev;
78 	return 0;
79 error:
80 	free(name);
81 	free(core_mask);
82 	free(base_bdev);
83 	free(cache_bdev);
84 	return -ENOMEM;
85 }
86 
87 void
88 spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
89 {
90 	free(conf->name);
91 	free(conf->core_mask);
92 	free(conf->base_bdev);
93 	free(conf->cache_bdev);
94 }
95 
96 int
97 ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
98 {
99 	int rc;
100 
101 	if (!conf->name) {
102 		FTL_ERRLOG(dev, "No FTL name in configuration\n");
103 		return -EINVAL;
104 	}
105 	if (!conf->base_bdev) {
106 		FTL_ERRLOG(dev, "No base device in configuration\n");
107 		return -EINVAL;
108 	}
109 	if (!conf->cache_bdev) {
110 		FTL_ERRLOG(dev, "No NV cache device in configuration\n");
111 		return -EINVAL;
112 	}
113 
114 	rc = spdk_ftl_conf_copy(&dev->conf, conf);
115 	if (rc) {
116 		return rc;
117 	}
118 
119 	dev->limit = SPDK_FTL_LIMIT_MAX;
120 	return 0;
121 }
122 
123 bool
124 ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
125 {
126 	if (conf->overprovisioning >= 100) {
127 		return false;
128 	}
129 	if (conf->overprovisioning == 0) {
130 		return false;
131 	}
132 
133 	if (conf->nv_cache.chunk_compaction_threshold == 0 ||
134 	    conf->nv_cache.chunk_compaction_threshold > 100) {
135 		return false;
136 	}
137 
138 	return true;
139 }
140