1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2022 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk_internal/cunit.h" 7 #include "spdk/stdinc.h" 8 #include "bdev/raid/bdev_raid.h" 9 10 struct spdk_bdev_desc { 11 struct spdk_bdev *bdev; 12 }; 13 14 typedef enum spdk_dif_type spdk_dif_type_t; 15 16 spdk_dif_type_t 17 spdk_bdev_get_dif_type(const struct spdk_bdev *bdev) 18 { 19 if (bdev->md_len != 0) { 20 return bdev->dif_type; 21 } else { 22 return SPDK_DIF_DISABLE; 23 } 24 } 25 26 enum raid_params_md_type { 27 RAID_PARAMS_MD_NONE, 28 RAID_PARAMS_MD_SEPARATE, 29 RAID_PARAMS_MD_INTERLEAVED, 30 }; 31 32 struct raid_params { 33 uint8_t num_base_bdevs; 34 uint64_t base_bdev_blockcnt; 35 uint32_t base_bdev_blocklen; 36 uint32_t strip_size; 37 enum raid_params_md_type md_type; 38 }; 39 40 int raid_test_params_alloc(size_t count); 41 void raid_test_params_free(void); 42 void raid_test_params_add(struct raid_params *params); 43 struct raid_bdev *raid_test_create_raid_bdev(struct raid_params *params, 44 struct raid_bdev_module *module); 45 void raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev); 46 struct raid_bdev_io_channel *raid_test_create_io_channel(struct raid_bdev *raid_bdev); 47 void raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch); 48 void raid_test_bdev_io_init(struct raid_bdev_io *raid_io, struct raid_bdev *raid_bdev, 49 struct raid_bdev_io_channel *raid_ch, 50 enum spdk_bdev_io_type type, uint64_t offset_blocks, 51 uint64_t num_blocks, struct iovec *iovs, int iovcnt, void *md_buf); 52 53 /* needs to be implemented in module unit test files */ 54 void raid_test_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status); 55 56 struct raid_params *g_params; 57 size_t g_params_count; 58 size_t g_params_size; 59 60 #define ARRAY_FOR_EACH(a, e) \ 61 for (e = a; e < a + SPDK_COUNTOF(a); e++) 62 63 #define RAID_PARAMS_FOR_EACH(p) \ 64 for (p = g_params; p < g_params + g_params_count; p++) 65 66 struct spdk_bdev * 67 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 68 { 69 return desc->bdev; 70 } 71 72 int 73 raid_test_params_alloc(size_t count) 74 { 75 assert(g_params == NULL); 76 77 g_params_size = count; 78 g_params_count = 0; 79 g_params = calloc(count, sizeof(*g_params)); 80 81 return g_params ? 0 : -ENOMEM; 82 } 83 84 void 85 raid_test_params_free(void) 86 { 87 g_params_count = 0; 88 g_params_size = 0; 89 free(g_params); 90 } 91 92 void 93 raid_test_params_add(struct raid_params *params) 94 { 95 assert(g_params_count < g_params_size); 96 97 memcpy(g_params + g_params_count, params, sizeof(*params)); 98 g_params_count++; 99 } 100 101 struct raid_bdev * 102 raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *module) 103 { 104 struct raid_bdev *raid_bdev; 105 struct raid_base_bdev_info *base_info; 106 107 SPDK_CU_ASSERT_FATAL(spdk_u32_is_pow2(params->base_bdev_blocklen)); 108 109 raid_bdev = calloc(1, sizeof(*raid_bdev)); 110 SPDK_CU_ASSERT_FATAL(raid_bdev != NULL); 111 112 raid_bdev->module = module; 113 raid_bdev->level = module->level; 114 raid_bdev->num_base_bdevs = params->num_base_bdevs; 115 116 switch (raid_bdev->module->base_bdevs_constraint.type) { 117 case CONSTRAINT_MAX_BASE_BDEVS_REMOVED: 118 raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs - 119 raid_bdev->module->base_bdevs_constraint.value; 120 break; 121 case CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL: 122 raid_bdev->min_base_bdevs_operational = raid_bdev->module->base_bdevs_constraint.value; 123 break; 124 case CONSTRAINT_UNSET: 125 raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs; 126 break; 127 default: 128 CU_FAIL_FATAL("unsupported raid constraint type"); 129 }; 130 131 raid_bdev->bdev.blocklen = params->base_bdev_blocklen; 132 raid_bdev->bdev.md_len = (params->md_type == RAID_PARAMS_MD_NONE ? 0 : 16); 133 raid_bdev->bdev.md_interleave = (params->md_type == RAID_PARAMS_MD_INTERLEAVED); 134 if (raid_bdev->bdev.md_interleave) { 135 raid_bdev->bdev.blocklen += raid_bdev->bdev.md_len; 136 } 137 138 raid_bdev->strip_size = params->strip_size; 139 raid_bdev->strip_size_kb = params->strip_size * params->base_bdev_blocklen / 1024; 140 raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size); 141 142 raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs, 143 sizeof(struct raid_base_bdev_info)); 144 SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL); 145 146 RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 147 struct spdk_bdev *bdev; 148 struct spdk_bdev_desc *desc; 149 150 bdev = calloc(1, sizeof(*bdev)); 151 SPDK_CU_ASSERT_FATAL(bdev != NULL); 152 bdev->ctxt = base_info; 153 bdev->blockcnt = params->base_bdev_blockcnt; 154 bdev->blocklen = raid_bdev->bdev.blocklen; 155 bdev->md_len = raid_bdev->bdev.md_len; 156 bdev->md_interleave = raid_bdev->bdev.md_interleave; 157 158 desc = calloc(1, sizeof(*desc)); 159 SPDK_CU_ASSERT_FATAL(desc != NULL); 160 desc->bdev = bdev; 161 162 base_info->raid_bdev = raid_bdev; 163 base_info->desc = desc; 164 base_info->data_offset = 0; 165 base_info->data_size = bdev->blockcnt; 166 } 167 168 return raid_bdev; 169 } 170 171 void 172 raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev) 173 { 174 struct raid_base_bdev_info *base_info; 175 176 RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 177 free(base_info->desc->bdev); 178 free(base_info->desc); 179 } 180 free(raid_bdev->base_bdev_info); 181 free(raid_bdev); 182 } 183 184 struct raid_bdev_io_channel { 185 struct spdk_io_channel **_base_channels; 186 struct spdk_io_channel *_module_channel; 187 }; 188 189 struct spdk_io_channel * 190 raid_bdev_channel_get_base_channel(struct raid_bdev_io_channel *raid_ch, uint8_t idx) 191 { 192 return raid_ch->_base_channels[idx]; 193 } 194 195 void * 196 raid_bdev_channel_get_module_ctx(struct raid_bdev_io_channel *raid_ch) 197 { 198 return spdk_io_channel_get_ctx(raid_ch->_module_channel); 199 } 200 201 struct raid_bdev_io_channel * 202 raid_test_create_io_channel(struct raid_bdev *raid_bdev) 203 { 204 struct raid_bdev_io_channel *raid_ch; 205 uint8_t i; 206 207 raid_ch = calloc(1, sizeof(*raid_ch)); 208 SPDK_CU_ASSERT_FATAL(raid_ch != NULL); 209 210 raid_ch->_base_channels = calloc(raid_bdev->num_base_bdevs, sizeof(struct spdk_io_channel *)); 211 SPDK_CU_ASSERT_FATAL(raid_ch->_base_channels != NULL); 212 213 for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 214 raid_ch->_base_channels[i] = (void *)1; 215 } 216 217 if (raid_bdev->module->get_io_channel) { 218 raid_ch->_module_channel = raid_bdev->module->get_io_channel(raid_bdev); 219 SPDK_CU_ASSERT_FATAL(raid_ch->_module_channel != NULL); 220 } 221 222 return raid_ch; 223 } 224 225 void 226 raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch) 227 { 228 free(raid_ch->_base_channels); 229 230 if (raid_ch->_module_channel) { 231 spdk_put_io_channel(raid_ch->_module_channel); 232 poll_threads(); 233 } 234 235 free(raid_ch); 236 } 237 238 void 239 raid_test_bdev_io_init(struct raid_bdev_io *raid_io, struct raid_bdev *raid_bdev, 240 struct raid_bdev_io_channel *raid_ch, 241 enum spdk_bdev_io_type type, uint64_t offset_blocks, 242 uint64_t num_blocks, struct iovec *iovs, int iovcnt, void *md_buf) 243 { 244 memset(raid_io, 0, sizeof(*raid_io)); 245 246 raid_io->raid_bdev = raid_bdev; 247 raid_io->raid_ch = raid_ch; 248 249 raid_io->type = type; 250 raid_io->offset_blocks = offset_blocks; 251 raid_io->num_blocks = num_blocks; 252 raid_io->iovs = iovs; 253 raid_io->iovcnt = iovcnt; 254 raid_io->md_buf = md_buf; 255 256 raid_bdev_io_set_default_status(raid_io, SPDK_BDEV_IO_STATUS_SUCCESS); 257 } 258 259 void 260 raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status) 261 { 262 if (raid_io->completion_cb != NULL) { 263 raid_io->completion_cb(raid_io, status); 264 } else { 265 raid_test_bdev_io_complete(raid_io, status); 266 } 267 } 268 269 bool 270 raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed, 271 enum spdk_bdev_io_status status) 272 { 273 SPDK_CU_ASSERT_FATAL(raid_io->base_bdev_io_remaining >= completed); 274 raid_io->base_bdev_io_remaining -= completed; 275 276 if (status != raid_io->base_bdev_io_status_default) { 277 raid_io->base_bdev_io_status = status; 278 } 279 280 if (raid_io->base_bdev_io_remaining == 0) { 281 raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status); 282 return true; 283 } else { 284 return false; 285 } 286 } 287 288 struct raid_base_bdev_info * 289 raid_bdev_channel_get_base_info(struct raid_bdev_io_channel *raid_ch, struct spdk_bdev *base_bdev) 290 { 291 return base_bdev->ctxt; 292 } 293