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 : : typedef enum spdk_dif_type spdk_dif_type_t;
15 : :
16 : : spdk_dif_type_t
17 : 103429 : spdk_bdev_get_dif_type(const struct spdk_bdev *bdev)
18 : : {
19 [ + + ]: 103429 : if (bdev->md_len != 0) {
20 : 67576 : return bdev->dif_type;
21 : : } else {
22 : 35853 : 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 : 200417 : spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
68 : : {
69 : 200417 : return desc->bdev;
70 : : }
71 : :
72 : : int
73 : 13 : raid_test_params_alloc(size_t count)
74 : : {
75 [ - + ]: 13 : assert(g_params == NULL);
76 : :
77 : 13 : g_params_size = count;
78 : 13 : g_params_count = 0;
79 : 13 : g_params = calloc(count, sizeof(*g_params));
80 : :
81 [ + - ]: 13 : return g_params ? 0 : -ENOMEM;
82 : : }
83 : :
84 : : void
85 : 13 : raid_test_params_free(void)
86 : : {
87 : 13 : g_params_count = 0;
88 : 13 : g_params_size = 0;
89 : 13 : free(g_params);
90 : 13 : }
91 : :
92 : : void
93 : 522 : raid_test_params_add(struct raid_params *params)
94 : : {
95 [ - + ]: 522 : assert(g_params_count < g_params_size);
96 : :
97 [ - + - + ]: 522 : memcpy(g_params + g_params_count, params, sizeof(*params));
98 : 522 : g_params_count++;
99 : 522 : }
100 : :
101 : : struct raid_bdev *
102 : 4471 : 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 [ - + ]: 4471 : SPDK_CU_ASSERT_FATAL(spdk_u32_is_pow2(params->base_bdev_blocklen));
108 : :
109 : 4471 : raid_bdev = calloc(1, sizeof(*raid_bdev));
110 [ - + ]: 4471 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
111 : :
112 : 4471 : raid_bdev->module = module;
113 : 4471 : raid_bdev->level = module->level;
114 : 4471 : raid_bdev->num_base_bdevs = params->num_base_bdevs;
115 : :
116 [ + + + - ]: 4471 : switch (raid_bdev->module->base_bdevs_constraint.type) {
117 : 2376 : case CONSTRAINT_MAX_BASE_BDEVS_REMOVED:
118 : 4752 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs -
119 : 2376 : raid_bdev->module->base_bdevs_constraint.value;
120 : 2376 : break;
121 : 240 : case CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL:
122 : 240 : raid_bdev->min_base_bdevs_operational = raid_bdev->module->base_bdevs_constraint.value;
123 : 240 : break;
124 : 1855 : case CONSTRAINT_UNSET:
125 : 1855 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs;
126 : 1855 : break;
127 : 0 : default:
128 : 0 : CU_FAIL_FATAL("unsupported raid constraint type");
129 : : };
130 : :
131 : 4471 : raid_bdev->bdev.blocklen = params->base_bdev_blocklen;
132 [ + + ]: 4471 : raid_bdev->bdev.md_len = (params->md_type == RAID_PARAMS_MD_NONE ? 0 : 16);
133 : 4471 : raid_bdev->bdev.md_interleave = (params->md_type == RAID_PARAMS_MD_INTERLEAVED);
134 [ - + + + ]: 4471 : if (raid_bdev->bdev.md_interleave) {
135 : 792 : raid_bdev->bdev.blocklen += raid_bdev->bdev.md_len;
136 : : }
137 : :
138 : 4471 : raid_bdev->strip_size = params->strip_size;
139 : 4471 : raid_bdev->strip_size_kb = params->strip_size * params->base_bdev_blocklen / 1024;
140 : 4471 : raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size);
141 : :
142 : 4471 : raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs,
143 : : sizeof(struct raid_base_bdev_info));
144 [ - + ]: 4471 : SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL);
145 : :
146 [ + + ]: 23335 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
147 : : struct spdk_bdev *bdev;
148 : : struct spdk_bdev_desc *desc;
149 : :
150 : 18864 : bdev = calloc(1, sizeof(*bdev));
151 [ - + ]: 18864 : SPDK_CU_ASSERT_FATAL(bdev != NULL);
152 : 18864 : bdev->ctxt = base_info;
153 : 18864 : bdev->blockcnt = params->base_bdev_blockcnt;
154 : 18864 : bdev->blocklen = raid_bdev->bdev.blocklen;
155 : 18864 : bdev->md_len = raid_bdev->bdev.md_len;
156 [ - + ]: 18864 : bdev->md_interleave = raid_bdev->bdev.md_interleave;
157 : :
158 : 18864 : desc = calloc(1, sizeof(*desc));
159 [ - + ]: 18864 : SPDK_CU_ASSERT_FATAL(desc != NULL);
160 : 18864 : desc->bdev = bdev;
161 : :
162 : 18864 : base_info->raid_bdev = raid_bdev;
163 : 18864 : base_info->desc = desc;
164 : 18864 : base_info->data_offset = 0;
165 : 18864 : base_info->data_size = bdev->blockcnt;
166 : : }
167 : :
168 : 4471 : return raid_bdev;
169 : : }
170 : :
171 : : void
172 : 4471 : raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev)
173 : : {
174 : : struct raid_base_bdev_info *base_info;
175 : :
176 [ + + ]: 23335 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
177 : 18864 : free(base_info->desc->bdev);
178 : 18864 : free(base_info->desc);
179 : : }
180 : 4471 : free(raid_bdev->base_bdev_info);
181 : 4471 : free(raid_bdev);
182 : 4471 : }
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 : 547308 : raid_bdev_channel_get_base_channel(struct raid_bdev_io_channel *raid_ch, uint8_t idx)
191 : : {
192 : 547308 : return raid_ch->_base_channels[idx];
193 : : }
194 : :
195 : : void *
196 : 39969 : raid_bdev_channel_get_module_ctx(struct raid_bdev_io_channel *raid_ch)
197 : : {
198 : 39969 : return spdk_io_channel_get_ctx(raid_ch->_module_channel);
199 : : }
200 : :
201 : : struct raid_bdev_io_channel *
202 : 3949 : 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 : 3949 : raid_ch = calloc(1, sizeof(*raid_ch));
208 [ - + ]: 3949 : SPDK_CU_ASSERT_FATAL(raid_ch != NULL);
209 : :
210 : 3949 : raid_ch->_base_channels = calloc(raid_bdev->num_base_bdevs, sizeof(struct spdk_io_channel *));
211 [ - + ]: 3949 : SPDK_CU_ASSERT_FATAL(raid_ch->_base_channels != NULL);
212 : :
213 [ + + ]: 20815 : for (i = 0; i < raid_bdev->num_base_bdevs; i++) {
214 : 16866 : raid_ch->_base_channels[i] = (void *)1;
215 : : }
216 : :
217 [ + + ]: 3949 : if (raid_bdev->module->get_io_channel) {
218 : 2259 : raid_ch->_module_channel = raid_bdev->module->get_io_channel(raid_bdev);
219 [ - + ]: 2259 : SPDK_CU_ASSERT_FATAL(raid_ch->_module_channel != NULL);
220 : : }
221 : :
222 : 3949 : return raid_ch;
223 : : }
224 : :
225 : : void
226 : 3949 : raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch)
227 : : {
228 : 3949 : free(raid_ch->_base_channels);
229 : :
230 [ + + ]: 3949 : if (raid_ch->_module_channel) {
231 : 2259 : spdk_put_io_channel(raid_ch->_module_channel);
232 : 2259 : poll_threads();
233 : : }
234 : :
235 : 3949 : free(raid_ch);
236 : 3949 : }
237 : :
238 : : void
239 : 65837 : 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 [ - + ]: 65837 : memset(raid_io, 0, sizeof(*raid_io));
245 : :
246 : 65837 : raid_io->raid_bdev = raid_bdev;
247 : 65837 : raid_io->raid_ch = raid_ch;
248 : :
249 : 65837 : raid_io->type = type;
250 : 65837 : raid_io->offset_blocks = offset_blocks;
251 : 65837 : raid_io->num_blocks = num_blocks;
252 : 65837 : raid_io->iovs = iovs;
253 : 65837 : raid_io->iovcnt = iovcnt;
254 : 65837 : raid_io->md_buf = md_buf;
255 : :
256 : 65837 : raid_bdev_io_set_default_status(raid_io, SPDK_BDEV_IO_STATUS_SUCCESS);
257 : 65837 : }
258 : :
259 : : void
260 : 62504 : raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status)
261 : : {
262 [ + + ]: 62504 : if (raid_io->completion_cb != NULL) {
263 : 2997 : raid_io->completion_cb(raid_io, status);
264 : : } else {
265 : 59507 : raid_test_bdev_io_complete(raid_io, status);
266 : : }
267 : 62504 : }
268 : :
269 : : bool
270 : 281540 : raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed,
271 : : enum spdk_bdev_io_status status)
272 : : {
273 [ - + ]: 281540 : SPDK_CU_ASSERT_FATAL(raid_io->base_bdev_io_remaining >= completed);
274 : 281540 : raid_io->base_bdev_io_remaining -= completed;
275 : :
276 [ + + ]: 281540 : if (status != raid_io->base_bdev_io_status_default) {
277 : 16206 : raid_io->base_bdev_io_status = status;
278 : : }
279 : :
280 [ + + ]: 281540 : if (raid_io->base_bdev_io_remaining == 0) {
281 : 35952 : raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status);
282 : 35952 : return true;
283 : : } else {
284 : 245588 : return false;
285 : : }
286 : : }
287 : :
288 : : struct raid_base_bdev_info *
289 : 300 : raid_bdev_channel_get_base_info(struct raid_bdev_io_channel *raid_ch, struct spdk_bdev *base_bdev)
290 : : {
291 : 300 : return base_bdev->ctxt;
292 : : }
|