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