xref: /spdk/lib/ftl/utils/ftl_conf.c (revision ea8f5b27612fa03698a9ce3ad4bd37765d9cdfa5)
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 	/* 2GiB of DRAM for l2p cache */
22 	.l2p_dram_limit = 2048,
23 	/* IO pool size per user thread (this should be adjusted to thread IO qdepth) */
24 	.user_io_pool_size = 2048,
25 	.nv_cache = {
26 		.chunk_compaction_threshold = 80,
27 	},
28 	.fast_shutdown = true,
29 };
30 
31 void
32 spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf)
33 {
34 	*conf = g_default_conf;
35 }
36 
37 void
38 spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf)
39 {
40 	*conf = dev->conf;
41 }
42 
43 int
44 spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
45 {
46 	char *name = NULL;
47 	char *core_mask = NULL;
48 	char *base_bdev = NULL;
49 	char *cache_bdev = NULL;
50 
51 	if (src->name) {
52 		name = strdup(src->name);
53 		if (!name) {
54 			goto error;
55 		}
56 	}
57 	if (src->core_mask) {
58 		core_mask = strdup(src->core_mask);
59 		if (!core_mask) {
60 			goto error;
61 		}
62 	}
63 	if (src->base_bdev) {
64 		base_bdev = strdup(src->base_bdev);
65 		if (!base_bdev) {
66 			goto error;
67 		}
68 	}
69 	if (src->cache_bdev) {
70 		cache_bdev = strdup(src->cache_bdev);
71 		if (!cache_bdev) {
72 			goto error;
73 		}
74 	}
75 
76 	*dst = *src;
77 	dst->name = name;
78 	dst->core_mask = core_mask;
79 	dst->base_bdev = base_bdev;
80 	dst->cache_bdev = cache_bdev;
81 	return 0;
82 error:
83 	free(name);
84 	free(core_mask);
85 	free(base_bdev);
86 	free(cache_bdev);
87 	return -ENOMEM;
88 }
89 
90 void
91 spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
92 {
93 	free(conf->name);
94 	free(conf->core_mask);
95 	free(conf->base_bdev);
96 	free(conf->cache_bdev);
97 }
98 
99 int
100 ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
101 {
102 	int rc;
103 
104 	if (!conf->name) {
105 		FTL_ERRLOG(dev, "No FTL name in configuration\n");
106 		return -EINVAL;
107 	}
108 	if (!conf->base_bdev) {
109 		FTL_ERRLOG(dev, "No base device in configuration\n");
110 		return -EINVAL;
111 	}
112 	if (!conf->cache_bdev) {
113 		FTL_ERRLOG(dev, "No NV cache device in configuration\n");
114 		return -EINVAL;
115 	}
116 
117 	rc = spdk_ftl_conf_copy(&dev->conf, conf);
118 	if (rc) {
119 		return rc;
120 	}
121 
122 	dev->limit = SPDK_FTL_LIMIT_MAX;
123 	return 0;
124 }
125 
126 bool
127 ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
128 {
129 	if (conf->overprovisioning >= 100) {
130 		return false;
131 	}
132 	if (conf->overprovisioning == 0) {
133 		return false;
134 	}
135 
136 	if (conf->nv_cache.chunk_compaction_threshold == 0 ||
137 	    conf->nv_cache.chunk_compaction_threshold > 100) {
138 		return false;
139 	}
140 
141 	return true;
142 }
143