Line data Source code
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 0 : spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size)
36 : {
37 0 : assert(conf_size > 0);
38 0 : assert(conf_size <= sizeof(struct spdk_ftl_conf));
39 :
40 0 : memcpy(conf, &g_default_conf, conf_size);
41 0 : conf->conf_size = conf_size;
42 0 : }
43 :
44 : void
45 0 : spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, size_t conf_size)
46 : {
47 0 : assert(conf_size > 0);
48 0 : assert(conf_size <= sizeof(struct spdk_ftl_conf));
49 :
50 0 : memcpy(conf, &dev->conf, conf_size);
51 0 : conf->conf_size = conf_size;
52 0 : }
53 :
54 : int
55 0 : spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src)
56 : {
57 0 : char *name = NULL;
58 0 : char *core_mask = NULL;
59 0 : char *base_bdev = NULL;
60 0 : char *cache_bdev = NULL;
61 :
62 0 : if (!src->conf_size || src->conf_size > sizeof(struct spdk_ftl_conf)) {
63 0 : return -EINVAL;
64 : }
65 :
66 0 : if (src->name) {
67 0 : name = strdup(src->name);
68 0 : if (!name) {
69 0 : goto error;
70 : }
71 0 : }
72 0 : if (src->core_mask) {
73 0 : core_mask = strdup(src->core_mask);
74 0 : if (!core_mask) {
75 0 : goto error;
76 : }
77 0 : }
78 0 : if (src->base_bdev) {
79 0 : base_bdev = strdup(src->base_bdev);
80 0 : if (!base_bdev) {
81 0 : goto error;
82 : }
83 0 : }
84 0 : if (src->cache_bdev) {
85 0 : cache_bdev = strdup(src->cache_bdev);
86 0 : if (!cache_bdev) {
87 0 : goto error;
88 : }
89 0 : }
90 :
91 0 : memcpy(dst, src, src->conf_size);
92 :
93 0 : dst->name = name;
94 0 : dst->core_mask = core_mask;
95 0 : dst->base_bdev = base_bdev;
96 0 : dst->cache_bdev = cache_bdev;
97 0 : return 0;
98 : error:
99 0 : free(name);
100 0 : free(core_mask);
101 0 : free(base_bdev);
102 0 : free(cache_bdev);
103 0 : return -ENOMEM;
104 0 : }
105 :
106 : void
107 0 : spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf)
108 : {
109 0 : free(conf->name);
110 0 : free(conf->core_mask);
111 0 : free(conf->base_bdev);
112 0 : free(conf->cache_bdev);
113 0 : }
114 :
115 : int
116 0 : ftl_conf_init_dev(struct spdk_ftl_dev *dev, const struct spdk_ftl_conf *conf)
117 : {
118 0 : int rc;
119 :
120 0 : if (!conf->conf_size) {
121 0 : FTL_ERRLOG(dev, "FTL configuration is uninitialized\n");
122 0 : return -EINVAL;
123 : }
124 :
125 0 : if (!conf->name) {
126 0 : FTL_ERRLOG(dev, "No FTL name in configuration\n");
127 0 : return -EINVAL;
128 : }
129 0 : if (!conf->base_bdev) {
130 0 : FTL_ERRLOG(dev, "No base device in configuration\n");
131 0 : return -EINVAL;
132 : }
133 0 : if (!conf->cache_bdev) {
134 0 : FTL_ERRLOG(dev, "No NV cache device in configuration\n");
135 0 : return -EINVAL;
136 : }
137 :
138 0 : rc = spdk_ftl_conf_copy(&dev->conf, conf);
139 0 : if (rc) {
140 0 : return rc;
141 : }
142 :
143 0 : dev->limit = SPDK_FTL_LIMIT_MAX;
144 :
145 0 : 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 0 : 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 0 : return 0;
154 0 : }
155 :
156 : bool
157 0 : ftl_conf_is_valid(const struct spdk_ftl_conf *conf)
158 : {
159 0 : if (conf->overprovisioning >= 100) {
160 0 : return false;
161 : }
162 0 : if (conf->overprovisioning == 0) {
163 0 : return false;
164 : }
165 :
166 0 : if (conf->nv_cache.chunk_compaction_threshold == 0 ||
167 0 : conf->nv_cache.chunk_compaction_threshold > 100) {
168 0 : return false;
169 : }
170 :
171 0 : if (conf->nv_cache.chunk_free_target == 0 || conf->nv_cache.chunk_free_target > 100) {
172 0 : return false;
173 : }
174 :
175 0 : if (conf->l2p_dram_limit == 0) {
176 0 : return false;
177 : }
178 :
179 0 : return true;
180 0 : }
|