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 : 20314 : spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
34 : : {
35 [ + - + - ]: 20314 : return desc->bdev;
36 : : }
37 : :
38 : : static int
39 : 14 : raid_test_params_alloc(size_t count)
40 : : {
41 [ + + # # ]: 14 : assert(g_params == NULL);
42 : :
43 : 14 : g_params_size = count;
44 : 14 : g_params_count = 0;
45 : 14 : g_params = calloc(count, sizeof(*g_params));
46 : :
47 [ + - ]: 14 : return g_params ? 0 : -ENOMEM;
48 : : }
49 : :
50 : : static void
51 : 14 : raid_test_params_free(void)
52 : : {
53 : 14 : g_params_count = 0;
54 : 14 : g_params_size = 0;
55 : 14 : free(g_params);
56 : 14 : }
57 : :
58 : : static void
59 : 489 : raid_test_params_add(struct raid_params *params)
60 : : {
61 [ + + # # ]: 489 : assert(g_params_count < g_params_size);
62 : :
63 [ + + + + : 489 : memcpy(g_params + g_params_count, params, sizeof(*params));
+ - ]
64 : 489 : g_params_count++;
65 : 489 : }
66 : :
67 : : static struct raid_bdev *
68 : 4047 : raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *module)
69 : : {
70 : 915 : struct raid_bdev *raid_bdev;
71 : 915 : struct raid_base_bdev_info *base_info;
72 : :
73 : 4047 : raid_bdev = calloc(1, sizeof(*raid_bdev));
74 [ + + # # ]: 4047 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
75 : :
76 [ + - + - ]: 4047 : raid_bdev->module = module;
77 [ + - + - : 4047 : raid_bdev->level = module->level;
+ - + - ]
78 [ + - + - : 4047 : raid_bdev->num_base_bdevs = params->num_base_bdevs;
+ - + - ]
79 : :
80 [ + + + - : 4047 : switch (raid_bdev->module->base_bdevs_constraint.type) {
+ - + - +
- + - +
+ ]
81 : 1584 : case CONSTRAINT_MAX_BASE_BDEVS_REMOVED:
82 [ + - + - : 4224 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs -
+ - + - ]
83 [ + - + - : 2112 : raid_bdev->module->base_bdevs_constraint.value;
+ - + - +
- ]
84 : 2112 : break;
85 : 96 : case CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL:
86 [ + - + - : 120 : raid_bdev->min_base_bdevs_operational = raid_bdev->module->base_bdevs_constraint.value;
+ - + - +
- + - +
- ]
87 : 120 : break;
88 : 1452 : case CONSTRAINT_UNSET:
89 [ + - + - : 1815 : raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs;
+ - + - ]
90 : 1815 : break;
91 : 0 : default:
92 : 0 : CU_FAIL_FATAL("unsupported raid constraint type");
93 : 0 : };
94 : :
95 [ + - + - : 4047 : raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs,
+ - + - ]
96 : : sizeof(struct raid_base_bdev_info));
97 [ + + + - : 4047 : SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL);
+ - # # ]
98 : :
99 [ + + + - : 20275 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
+ - + - +
- + - + -
+ + + - ]
100 : 3668 : struct spdk_bdev *bdev;
101 : 3668 : struct spdk_bdev_desc *desc;
102 : :
103 : 16228 : bdev = calloc(1, sizeof(*bdev));
104 [ + + # # ]: 16228 : SPDK_CU_ASSERT_FATAL(bdev != NULL);
105 [ + - + - : 16228 : bdev->blockcnt = params->base_bdev_blockcnt;
+ - + - ]
106 [ + - + - : 16228 : bdev->blocklen = params->base_bdev_blocklen;
+ - + - ]
107 : :
108 : 16228 : desc = calloc(1, sizeof(*desc));
109 [ + + # # ]: 16228 : SPDK_CU_ASSERT_FATAL(desc != NULL);
110 [ + - + - ]: 16228 : desc->bdev = bdev;
111 : :
112 [ + - + - ]: 16228 : base_info->desc = desc;
113 [ + - + - ]: 16228 : base_info->data_offset = 0;
114 [ + - + - : 16228 : base_info->data_size = bdev->blockcnt;
+ - + - ]
115 : 3668 : }
116 : :
117 [ + - + - : 4047 : raid_bdev->strip_size = params->strip_size;
+ - + - ]
118 [ + - + - : 4047 : raid_bdev->strip_size_kb = params->strip_size * params->base_bdev_blocklen / 1024;
+ - + - +
- + - +
- ]
119 [ + - + - : 4047 : raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size);
+ - + - ]
120 [ + - + - : 4047 : raid_bdev->blocklen_shift = spdk_u32log2(params->base_bdev_blocklen);
+ - + - ]
121 [ + - + - : 4047 : raid_bdev->bdev.blocklen = params->base_bdev_blocklen;
+ - + - +
- ]
122 [ + - + - : 4047 : raid_bdev->bdev.md_len = params->md_len;
+ - + - +
- ]
123 : :
124 : 4962 : return raid_bdev;
125 : 915 : }
126 : :
127 : : static void
128 : 4047 : raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev)
129 : : {
130 : 915 : struct raid_base_bdev_info *base_info;
131 : :
132 [ + + + - : 20275 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
+ - + - +
- + - + -
+ + + - ]
133 [ + - + - : 16228 : free(base_info->desc->bdev);
+ - + - ]
134 [ + - + - ]: 16228 : free(base_info->desc);
135 : 3668 : }
136 [ + - + - ]: 4047 : free(raid_bdev->base_bdev_info);
137 : 4047 : free(raid_bdev);
138 : 4047 : }
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 : 172236 : raid_bdev_channel_get_base_channel(struct raid_bdev_io_channel *raid_ch, uint8_t idx)
147 : : {
148 [ + - + - : 172236 : return raid_ch->_base_channels[idx];
+ - + - ]
149 : : }
150 : :
151 : : void *
152 : 35928 : raid_bdev_channel_get_module_ctx(struct raid_bdev_io_channel *raid_ch)
153 : : {
154 [ + - + - ]: 35928 : return spdk_io_channel_get_ctx(raid_ch->_module_channel);
155 : : }
156 : :
157 : : static struct raid_bdev_io_channel *
158 : 3558 : raid_test_create_io_channel(struct raid_bdev *raid_bdev)
159 : : {
160 : 804 : struct raid_bdev_io_channel *raid_ch;
161 : 804 : uint8_t i;
162 : :
163 : 3558 : raid_ch = calloc(1, sizeof(*raid_ch));
164 [ + + # # ]: 3558 : SPDK_CU_ASSERT_FATAL(raid_ch != NULL);
165 : :
166 [ + - + - : 3558 : raid_ch->_base_channels = calloc(raid_bdev->num_base_bdevs, sizeof(struct spdk_io_channel *));
+ - + - ]
167 [ + + + - : 3558 : SPDK_CU_ASSERT_FATAL(raid_ch->_base_channels != NULL);
+ - # # ]
168 : :
169 [ + + + - : 17920 : for (i = 0; i < raid_bdev->num_base_bdevs; i++) {
+ + ]
170 [ + - + - : 14362 : raid_ch->_base_channels[i] = (void *)1;
+ - + - ]
171 : 3242 : }
172 : :
173 [ + + + - : 3558 : if (raid_bdev->module->get_io_channel) {
+ - + - +
+ ]
174 [ + - + - : 1908 : raid_ch->_module_channel = raid_bdev->module->get_io_channel(raid_bdev);
+ - + - -
+ + - + -
+ - ]
175 [ + + + - : 1908 : SPDK_CU_ASSERT_FATAL(raid_ch->_module_channel != NULL);
+ - # # ]
176 : 474 : }
177 : :
178 : 4362 : return raid_ch;
179 : 804 : }
180 : :
181 : : static void
182 : 3558 : raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch)
183 : : {
184 [ + - + - ]: 3558 : free(raid_ch->_base_channels);
185 : :
186 [ + + + - : 3558 : if (raid_ch->_module_channel) {
+ + ]
187 [ + - + - ]: 1908 : spdk_put_io_channel(raid_ch->_module_channel);
188 : 1908 : poll_threads();
189 : 474 : }
190 : :
191 : 3558 : free(raid_ch);
192 : 3558 : }
193 : :
194 : : static void
195 : 50324 : 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 [ + + ]: 50324 : memset(raid_io, 0, sizeof(*raid_io));
201 : :
202 [ + - + - ]: 50324 : raid_io->raid_bdev = raid_bdev;
203 [ + - + - ]: 50324 : raid_io->raid_ch = raid_ch;
204 : :
205 [ + - + - ]: 50324 : raid_io->type = type;
206 [ + - + - ]: 50324 : raid_io->offset_blocks = offset_blocks;
207 [ + - + - ]: 50324 : raid_io->num_blocks = num_blocks;
208 [ + - + - ]: 50324 : raid_io->iovs = iovs;
209 [ + - + - ]: 50324 : raid_io->iovcnt = iovcnt;
210 [ + - + - ]: 50324 : raid_io->md_buf = md_buf;
211 : :
212 [ + - + - ]: 50324 : raid_io->base_bdev_io_status = SPDK_BDEV_IO_STATUS_SUCCESS;
213 : 50324 : }
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 : 46658 : raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status)
221 : : {
222 [ + + + - : 46658 : if (raid_io->completion_cb != NULL) {
+ + ]
223 [ + - + - : 2664 : raid_io->completion_cb(raid_io, status);
- + - + ]
224 : 666 : } else {
225 : 43994 : raid_test_bdev_io_complete(raid_io, status);
226 : : }
227 : 46658 : }
228 : :
229 : : bool
230 : 92570 : raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed,
231 : : enum spdk_bdev_io_status status)
232 : : {
233 [ + + + - : 92570 : SPDK_CU_ASSERT_FATAL(raid_io->base_bdev_io_remaining >= completed);
+ - # # ]
234 [ + - + - ]: 92570 : raid_io->base_bdev_io_remaining -= completed;
235 : :
236 [ + + ]: 92570 : if (status != SPDK_BDEV_IO_STATUS_SUCCESS) {
237 [ + - + - ]: 14272 : raid_io->base_bdev_io_status = status;
238 : 3568 : }
239 : :
240 [ + + + - : 92570 : if (raid_io->base_bdev_io_remaining == 0) {
+ + ]
241 [ + - + - ]: 23274 : raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status);
242 : 23274 : return true;
243 : : } else {
244 : 69296 : return false;
245 : : }
246 : 23110 : }
|