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_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 : : struct raid_params { 15 : : uint8_t num_base_bdevs; 16 : : uint64_t base_bdev_blockcnt; 17 : : uint32_t base_bdev_blocklen; 18 : : uint32_t strip_size; 19 : : uint32_t md_len; 20 : : }; 21 : : 22 : : struct raid_params *g_params; 23 : : size_t g_params_count; 24 : : size_t g_params_size; 25 : : 26 : : #define ARRAY_FOR_EACH(a, e) \ 27 : : for (e = a; e < a + SPDK_COUNTOF(a); e++) 28 : : 29 : : #define RAID_PARAMS_FOR_EACH(p) \ 30 : : for (p = g_params; p < g_params + g_params_count; p++) 31 : : 32 : : struct spdk_bdev * 33 : 5986 : spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 34 : : { 35 : 5986 : return desc->bdev; 36 : : } 37 : : 38 : : static int 39 : 9 : raid_test_params_alloc(size_t count) 40 : : { 41 [ - + ]: 9 : assert(g_params == NULL); 42 : : 43 : 9 : g_params_size = count; 44 : 9 : g_params_count = 0; 45 : 9 : g_params = calloc(count, sizeof(*g_params)); 46 : : 47 [ + - ]: 9 : return g_params ? 0 : -ENOMEM; 48 : : } 49 : : 50 : : static void 51 : 9 : raid_test_params_free(void) 52 : : { 53 : 9 : g_params_count = 0; 54 : 9 : g_params_size = 0; 55 : 9 : free(g_params); 56 : 9 : } 57 : : 58 : : static void 59 : 246 : raid_test_params_add(struct raid_params *params) 60 : : { 61 [ - + ]: 246 : assert(g_params_count < g_params_size); 62 : : 63 [ - + - + ]: 246 : memcpy(g_params + g_params_count, params, sizeof(*params)); 64 : 246 : g_params_count++; 65 : 246 : } 66 : : 67 : : static struct raid_bdev * 68 : 2076 : raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *module) 69 : : { 70 : : struct raid_bdev *raid_bdev; 71 : : struct raid_base_bdev_info *base_info; 72 : : 73 : 2076 : raid_bdev = calloc(1, sizeof(*raid_bdev)); 74 [ - + ]: 2076 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL); 75 : : 76 : 2076 : raid_bdev->module = module; 77 : 2076 : raid_bdev->level = module->level; 78 : 2076 : raid_bdev->num_base_bdevs = params->num_base_bdevs; 79 : : 80 [ + + + - ]: 2076 : switch (raid_bdev->module->base_bdevs_constraint.type) { 81 : 528 : case CONSTRAINT_MAX_BASE_BDEVS_REMOVED: 82 : 1056 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs - 83 : 528 : raid_bdev->module->base_bdevs_constraint.value; 84 : 528 : break; 85 : 96 : case CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL: 86 : 96 : raid_bdev->min_base_bdevs_operational = raid_bdev->module->base_bdevs_constraint.value; 87 : 96 : break; 88 : 1452 : case CONSTRAINT_UNSET: 89 : 1452 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs; 90 : 1452 : break; 91 : 0 : default: 92 : 0 : CU_FAIL_FATAL("unsupported raid constraint type"); 93 : : }; 94 : : 95 : 2076 : raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs, 96 : : sizeof(struct raid_base_bdev_info)); 97 [ - + ]: 2076 : SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL); 98 : : 99 [ + + ]: 10412 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 100 : : struct spdk_bdev *bdev; 101 : : struct spdk_bdev_desc *desc; 102 : : 103 : 8336 : bdev = calloc(1, sizeof(*bdev)); 104 [ - + ]: 8336 : SPDK_CU_ASSERT_FATAL(bdev != NULL); 105 : 8336 : bdev->blockcnt = params->base_bdev_blockcnt; 106 : 8336 : bdev->blocklen = params->base_bdev_blocklen; 107 : : 108 : 8336 : desc = calloc(1, sizeof(*desc)); 109 [ - + ]: 8336 : SPDK_CU_ASSERT_FATAL(desc != NULL); 110 : 8336 : desc->bdev = bdev; 111 : : 112 : 8336 : base_info->desc = desc; 113 : 8336 : base_info->data_offset = 0; 114 : 8336 : base_info->data_size = bdev->blockcnt; 115 : : } 116 : : 117 : 2076 : raid_bdev->strip_size = params->strip_size; 118 : 2076 : raid_bdev->strip_size_kb = params->strip_size * params->base_bdev_blocklen / 1024; 119 : 2076 : raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size); 120 : 2076 : raid_bdev->blocklen_shift = spdk_u32log2(params->base_bdev_blocklen); 121 : 2076 : raid_bdev->bdev.blocklen = params->base_bdev_blocklen; 122 : 2076 : raid_bdev->bdev.md_len = params->md_len; 123 : : 124 : 2076 : return raid_bdev; 125 : : } 126 : : 127 : : static void 128 : 2076 : raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev) 129 : : { 130 : : struct raid_base_bdev_info *base_info; 131 : : 132 [ + + ]: 10412 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 133 : 8336 : free(base_info->desc->bdev); 134 : 8336 : free(base_info->desc); 135 : : } 136 : 2076 : free(raid_bdev->base_bdev_info); 137 : 2076 : free(raid_bdev); 138 : 2076 : } 139 : : 140 : : struct raid_bdev_io_channel { 141 : : struct spdk_io_channel **_base_channels; 142 : : struct spdk_io_channel *_module_channel; 143 : : }; 144 : : 145 : : struct spdk_io_channel * 146 : 57788 : raid_bdev_channel_get_base_channel(struct raid_bdev_io_channel *raid_ch, uint8_t idx) 147 : : { 148 : 57788 : return raid_ch->_base_channels[idx]; 149 : : } 150 : : 151 : : void * 152 : 15978 : raid_bdev_channel_get_module_ctx(struct raid_bdev_io_channel *raid_ch) 153 : : { 154 : 15978 : return spdk_io_channel_get_ctx(raid_ch->_module_channel); 155 : : } 156 : : 157 : : static struct raid_bdev_io_channel * 158 : 1830 : raid_test_create_io_channel(struct raid_bdev *raid_bdev) 159 : : { 160 : : struct raid_bdev_io_channel *raid_ch; 161 : : uint8_t i; 162 : : 163 : 1830 : raid_ch = calloc(1, sizeof(*raid_ch)); 164 [ - + ]: 1830 : SPDK_CU_ASSERT_FATAL(raid_ch != NULL); 165 : : 166 : 1830 : raid_ch->_base_channels = calloc(raid_bdev->num_base_bdevs, sizeof(struct spdk_io_channel *)); 167 [ - + ]: 1830 : SPDK_CU_ASSERT_FATAL(raid_ch->_base_channels != NULL); 168 : : 169 [ + + ]: 9254 : for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 170 : 7424 : raid_ch->_base_channels[i] = (void *)1; 171 : : } 172 : : 173 [ + + ]: 1830 : if (raid_bdev->module->get_io_channel) { 174 : 510 : raid_ch->_module_channel = raid_bdev->module->get_io_channel(raid_bdev); 175 [ - + ]: 510 : SPDK_CU_ASSERT_FATAL(raid_ch->_module_channel != NULL); 176 : : } 177 : : 178 : 1830 : return raid_ch; 179 : : } 180 : : 181 : : static void 182 : 1830 : raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch) 183 : : { 184 : 1830 : free(raid_ch->_base_channels); 185 : : 186 [ + + ]: 1830 : if (raid_ch->_module_channel) { 187 : 510 : spdk_put_io_channel(raid_ch->_module_channel); 188 : 510 : poll_threads(); 189 : : } 190 : : 191 : 1830 : free(raid_ch); 192 : 1830 : } 193 : : 194 : : static void 195 : 16970 : raid_test_bdev_io_init(struct raid_bdev_io *raid_io, struct raid_bdev *raid_bdev, 196 : : struct raid_bdev_io_channel *raid_ch, 197 : : enum spdk_bdev_io_type type, uint64_t offset_blocks, 198 : : uint64_t num_blocks, struct iovec *iovs, int iovcnt, void *md_buf) 199 : : { 200 [ - + ]: 16970 : memset(raid_io, 0, sizeof(*raid_io)); 201 : : 202 : 16970 : raid_io->raid_bdev = raid_bdev; 203 : 16970 : raid_io->raid_ch = raid_ch; 204 : : 205 : 16970 : raid_io->type = type; 206 : 16970 : raid_io->offset_blocks = offset_blocks; 207 : 16970 : raid_io->num_blocks = num_blocks; 208 : 16970 : raid_io->iovs = iovs; 209 : 16970 : raid_io->iovcnt = iovcnt; 210 : 16970 : raid_io->md_buf = md_buf; 211 : : 212 : 16970 : raid_io->base_bdev_io_status = SPDK_BDEV_IO_STATUS_SUCCESS; 213 : 16970 : } 214 : : 215 : : /* needs to be implemented in module unit test files */ 216 : : static void raid_test_bdev_io_complete(struct raid_bdev_io *raid_io, 217 : : enum spdk_bdev_io_status status); 218 : : 219 : : void 220 : 12572 : raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status) 221 : : { 222 [ + + ]: 12572 : if (raid_io->completion_cb != NULL) { 223 : 666 : raid_io->completion_cb(raid_io, status); 224 : : } else { 225 : 11906 : raid_test_bdev_io_complete(raid_io, status); 226 : : } 227 : 12572 : } 228 : : 229 : : bool 230 : 23500 : raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed, 231 : : enum spdk_bdev_io_status status) 232 : : { 233 [ - + ]: 23500 : SPDK_CU_ASSERT_FATAL(raid_io->base_bdev_io_remaining >= completed); 234 : 23500 : raid_io->base_bdev_io_remaining -= completed; 235 : : 236 [ + + ]: 23500 : if (status != SPDK_BDEV_IO_STATUS_SUCCESS) { 237 : 3568 : raid_io->base_bdev_io_status = status; 238 : : } 239 : : 240 [ + + ]: 23500 : if (raid_io->base_bdev_io_remaining == 0) { 241 : 6000 : raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status); 242 : 6000 : return true; 243 : : } else { 244 : 17500 : return false; 245 : : } 246 : : }