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