]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / test / unit / lib / ftl / ftl_wptr / ftl_wptr_ut.c
CommitLineData
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
44struct 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)
52DEFINE_STUB(ftl_band_validate_md, bool, (struct ftl_band *band), true);
f67539c2
TL
53DEFINE_STUB_V(ftl_trace_limits, (struct spdk_ftl_dev *dev, int limit, size_t num_free));
54
55DEFINE_STUB_V(ftl_trace_completion, (struct spdk_ftl_dev *dev, const struct ftl_io *io,
56 enum ftl_trace_completion completion));
57DEFINE_STUB_V(ftl_trace_write_band, (struct spdk_ftl_dev *dev, const struct ftl_band *band));
58DEFINE_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 61DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
9f95a23c
TL
62DEFINE_STUB_V(ftl_io_dec_req, (struct ftl_io *io));
63DEFINE_STUB_V(ftl_io_inc_req, (struct ftl_io *io));
64DEFINE_STUB_V(ftl_io_fail, (struct ftl_io *io, int status));
9f95a23c 65DEFINE_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 67DEFINE_STUB_V(ftl_io_process_error, (struct ftl_io *io, const struct spdk_nvme_cpl *status));
9f95a23c 68DEFINE_STUB(spdk_bdev_get_num_blocks, uint64_t, (const struct spdk_bdev *bdev), 0);
f67539c2
TL
69DEFINE_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);
73DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0);
74
75struct spdk_io_channel *
76spdk_bdev_get_io_channel(struct spdk_bdev_desc *bdev_desc)
77{
78 return spdk_get_io_channel(bdev_desc);
79}
9f95a23c
TL
80
81struct ftl_io *
f67539c2 82ftl_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
97void
f67539c2 98ftl_io_advance(struct ftl_io *io, size_t num_blocks)
9f95a23c 99{
f67539c2 100 io->pos += num_blocks;
9f95a23c
TL
101}
102
103void
104ftl_io_complete(struct ftl_io *io)
105{
106 io->cb_fn(io, NULL, 0);
107 free(io);
108}
109
110static void
f67539c2 111setup_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
131static void
132cleanup_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
148static void
149test_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
203int
204main(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}