]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "spdk/stdinc.h" | |
35 | ||
36 | #include "spdk_cunit.h" | |
37 | #include "common/lib/test_env.c" | |
38 | ||
39 | #include "ftl/ftl_core.c" | |
40 | #include "ftl/ftl_band.c" | |
f67539c2 | 41 | #include "ftl/ftl_init.c" |
9f95a23c TL |
42 | #include "../common/utils.c" |
43 | ||
f67539c2 TL |
44 | struct base_bdev_geometry g_geo = { |
45 | .write_unit_size = 16, | |
46 | .optimal_open_zones = 12, | |
47 | .zone_size = 128, | |
48 | .blockcnt = 20 * 128 * 12, | |
9f95a23c TL |
49 | }; |
50 | ||
51 | #if defined(DEBUG) | |
52 | DEFINE_STUB(ftl_band_validate_md, bool, (struct ftl_band *band), true); | |
f67539c2 TL |
53 | DEFINE_STUB_V(ftl_trace_limits, (struct spdk_ftl_dev *dev, int limit, size_t num_free)); |
54 | ||
55 | DEFINE_STUB_V(ftl_trace_completion, (struct spdk_ftl_dev *dev, const struct ftl_io *io, | |
56 | enum ftl_trace_completion completion)); | |
57 | DEFINE_STUB_V(ftl_trace_write_band, (struct spdk_ftl_dev *dev, const struct ftl_band *band)); | |
58 | DEFINE_STUB_V(ftl_trace_submission, (struct spdk_ftl_dev *dev, const struct ftl_io *io, | |
59 | struct ftl_addr addr, size_t addr_cnt)); | |
9f95a23c | 60 | #endif |
f67539c2 | 61 | DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); |
9f95a23c TL |
62 | DEFINE_STUB_V(ftl_io_dec_req, (struct ftl_io *io)); |
63 | DEFINE_STUB_V(ftl_io_inc_req, (struct ftl_io *io)); | |
64 | DEFINE_STUB_V(ftl_io_fail, (struct ftl_io *io, int status)); | |
9f95a23c | 65 | DEFINE_STUB_V(ftl_reloc_add, (struct ftl_reloc *reloc, struct ftl_band *band, size_t offset, |
f67539c2 | 66 | size_t num_blocks, int prio, bool defrag)); |
9f95a23c | 67 | DEFINE_STUB_V(ftl_io_process_error, (struct ftl_io *io, const struct spdk_nvme_cpl *status)); |
9f95a23c | 68 | DEFINE_STUB(spdk_bdev_get_num_blocks, uint64_t, (const struct spdk_bdev *bdev), 0); |
f67539c2 TL |
69 | DEFINE_STUB(spdk_bdev_zone_management, int, (struct spdk_bdev_desc *desc, |
70 | struct spdk_io_channel *ch, | |
71 | uint64_t zone_id, enum spdk_bdev_zone_action action, | |
72 | spdk_bdev_io_completion_cb cb, void *cb_arg), 0); | |
73 | DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0); | |
74 | ||
75 | struct spdk_io_channel * | |
76 | spdk_bdev_get_io_channel(struct spdk_bdev_desc *bdev_desc) | |
77 | { | |
78 | return spdk_get_io_channel(bdev_desc); | |
79 | } | |
9f95a23c TL |
80 | |
81 | struct ftl_io * | |
f67539c2 | 82 | ftl_io_erase_init(struct ftl_band *band, size_t num_blocks, ftl_io_fn cb) |
9f95a23c TL |
83 | { |
84 | struct ftl_io *io; | |
85 | ||
86 | io = calloc(1, sizeof(struct ftl_io)); | |
87 | SPDK_CU_ASSERT_FATAL(io != NULL); | |
88 | ||
89 | io->dev = band->dev; | |
90 | io->band = band; | |
91 | io->cb_fn = cb; | |
f67539c2 | 92 | io->num_blocks = 1; |
9f95a23c TL |
93 | |
94 | return io; | |
95 | } | |
96 | ||
97 | void | |
f67539c2 | 98 | ftl_io_advance(struct ftl_io *io, size_t num_blocks) |
9f95a23c | 99 | { |
f67539c2 | 100 | io->pos += num_blocks; |
9f95a23c TL |
101 | } |
102 | ||
103 | void | |
104 | ftl_io_complete(struct ftl_io *io) | |
105 | { | |
106 | io->cb_fn(io, NULL, 0); | |
107 | free(io); | |
108 | } | |
109 | ||
110 | static void | |
f67539c2 | 111 | setup_wptr_test(struct spdk_ftl_dev **dev, const struct base_bdev_geometry *geo) |
9f95a23c | 112 | { |
9f95a23c | 113 | struct spdk_ftl_dev *t_dev; |
f67539c2 TL |
114 | struct _ftl_io_channel *_ioch; |
115 | size_t i; | |
9f95a23c | 116 | |
f67539c2 TL |
117 | t_dev = test_init_ftl_dev(geo); |
118 | for (i = 0; i < ftl_get_num_bands(t_dev); ++i) { | |
119 | test_init_ftl_band(t_dev, i, geo->zone_size); | |
9f95a23c TL |
120 | t_dev->bands[i].state = FTL_BAND_STATE_CLOSED; |
121 | ftl_band_set_state(&t_dev->bands[i], FTL_BAND_STATE_FREE); | |
122 | } | |
123 | ||
f67539c2 TL |
124 | _ioch = (struct _ftl_io_channel *)(t_dev->ioch + 1); |
125 | _ioch->ioch = calloc(1, sizeof(*_ioch->ioch)); | |
126 | SPDK_CU_ASSERT_FATAL(_ioch->ioch != NULL); | |
127 | ||
9f95a23c TL |
128 | *dev = t_dev; |
129 | } | |
130 | ||
131 | static void | |
132 | cleanup_wptr_test(struct spdk_ftl_dev *dev) | |
133 | { | |
f67539c2 | 134 | struct _ftl_io_channel *_ioch; |
9f95a23c TL |
135 | size_t i; |
136 | ||
f67539c2 | 137 | for (i = 0; i < ftl_get_num_bands(dev); ++i) { |
9f95a23c TL |
138 | dev->bands[i].lba_map.segments = NULL; |
139 | test_free_ftl_band(&dev->bands[i]); | |
140 | } | |
141 | ||
f67539c2 TL |
142 | _ioch = (struct _ftl_io_channel *)(dev->ioch + 1); |
143 | free(_ioch->ioch); | |
144 | ||
9f95a23c TL |
145 | test_free_ftl_dev(dev); |
146 | } | |
147 | ||
148 | static void | |
149 | test_wptr(void) | |
150 | { | |
151 | struct spdk_ftl_dev *dev; | |
152 | struct ftl_wptr *wptr; | |
153 | struct ftl_band *band; | |
154 | struct ftl_io io = { 0 }; | |
155 | size_t xfer_size; | |
f67539c2 | 156 | size_t zone, block, offset, i; |
9f95a23c TL |
157 | int rc; |
158 | ||
f67539c2 | 159 | setup_wptr_test(&dev, &g_geo); |
9f95a23c TL |
160 | |
161 | xfer_size = dev->xfer_size; | |
162 | ftl_add_wptr(dev); | |
f67539c2 | 163 | for (i = 0; i < ftl_get_num_bands(dev); ++i) { |
9f95a23c TL |
164 | wptr = LIST_FIRST(&dev->wptr_list); |
165 | band = wptr->band; | |
166 | ftl_band_set_state(band, FTL_BAND_STATE_OPENING); | |
167 | ftl_band_set_state(band, FTL_BAND_STATE_OPEN); | |
168 | io.band = band; | |
169 | io.dev = dev; | |
170 | ||
f67539c2 TL |
171 | for (block = 0, offset = 0; block < ftl_get_num_blocks_in_zone(dev) / xfer_size; ++block) { |
172 | for (zone = 0; zone < band->num_zones; ++zone) { | |
9f95a23c TL |
173 | CU_ASSERT_EQUAL(wptr->offset, offset); |
174 | ftl_wptr_advance(wptr, xfer_size); | |
175 | offset += xfer_size; | |
176 | } | |
177 | } | |
178 | ||
179 | CU_ASSERT_EQUAL(band->state, FTL_BAND_STATE_FULL); | |
9f95a23c TL |
180 | |
181 | ftl_band_set_state(band, FTL_BAND_STATE_CLOSING); | |
182 | ||
183 | /* Call the metadata completion cb to force band state change */ | |
184 | /* and removal of the actual wptr */ | |
185 | ftl_md_write_cb(&io, NULL, 0); | |
186 | CU_ASSERT_EQUAL(band->state, FTL_BAND_STATE_CLOSED); | |
187 | CU_ASSERT_TRUE(LIST_EMPTY(&dev->wptr_list)); | |
188 | ||
189 | rc = ftl_add_wptr(dev); | |
190 | ||
191 | /* There are no free bands during the last iteration, so */ | |
192 | /* there'll be no new wptr allocation */ | |
f67539c2 | 193 | if (i == (ftl_get_num_bands(dev) - 1)) { |
9f95a23c TL |
194 | CU_ASSERT_EQUAL(rc, -1); |
195 | } else { | |
196 | CU_ASSERT_EQUAL(rc, 0); | |
197 | } | |
198 | } | |
199 | ||
200 | cleanup_wptr_test(dev); | |
201 | } | |
202 | ||
203 | int | |
204 | main(int argc, char **argv) | |
205 | { | |
206 | CU_pSuite suite = NULL; | |
207 | unsigned int num_failures; | |
208 | ||
f67539c2 TL |
209 | CU_set_error_action(CUEA_ABORT); |
210 | CU_initialize_registry(); | |
9f95a23c TL |
211 | |
212 | suite = CU_add_suite("ftl_wptr_suite", NULL, NULL); | |
9f95a23c | 213 | |
f67539c2 TL |
214 | |
215 | CU_ADD_TEST(suite, test_wptr); | |
9f95a23c TL |
216 | |
217 | CU_basic_set_mode(CU_BRM_VERBOSE); | |
218 | CU_basic_run_tests(); | |
219 | num_failures = CU_get_number_of_failures(); | |
220 | CU_cleanup_registry(); | |
221 | ||
222 | return num_failures; | |
223 | } |