xref: /spdk/test/unit/lib/ftl/common/utils.c (revision 186b109dd3a723612e3df79bb3d97699173d39e3)
1a05d3047SArtur Paszkiewicz /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2018 Intel Corporation.
3a05d3047SArtur Paszkiewicz  *   All rights reserved.
4a05d3047SArtur Paszkiewicz  */
5a05d3047SArtur Paszkiewicz 
6a05d3047SArtur Paszkiewicz #include "spdk/ftl.h"
7a05d3047SArtur Paszkiewicz #include "ftl/ftl_core.h"
8a05d3047SArtur Paszkiewicz 
9a05d3047SArtur Paszkiewicz #include "ftl/mngt/ftl_mngt_bdev.c"
10a05d3047SArtur Paszkiewicz 
11a05d3047SArtur Paszkiewicz struct base_bdev_geometry {
12a05d3047SArtur Paszkiewicz 	size_t write_unit_size;
13a05d3047SArtur Paszkiewicz 	size_t zone_size;
14a05d3047SArtur Paszkiewicz 	size_t optimal_open_zones;
15a05d3047SArtur Paszkiewicz 	size_t blockcnt;
16a05d3047SArtur Paszkiewicz };
17a05d3047SArtur Paszkiewicz 
18a05d3047SArtur Paszkiewicz extern struct base_bdev_geometry g_geo;
19a05d3047SArtur Paszkiewicz 
20a05d3047SArtur Paszkiewicz struct spdk_ftl_dev *test_init_ftl_dev(const struct base_bdev_geometry *geo);
21a05d3047SArtur Paszkiewicz struct ftl_band *test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id, size_t zone_size);
22a05d3047SArtur Paszkiewicz void test_free_ftl_dev(struct spdk_ftl_dev *dev);
23a05d3047SArtur Paszkiewicz void test_free_ftl_band(struct ftl_band *band);
24a05d3047SArtur Paszkiewicz uint64_t test_offset_from_addr(ftl_addr addr, struct ftl_band *band);
25a05d3047SArtur Paszkiewicz 
26a05d3047SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *, (struct spdk_bdev_desc *desc), NULL);
27a05d3047SArtur Paszkiewicz 
2826f3b551SMateusz Kozlowski DEFINE_STUB(ftl_nv_cache_device_get_type_by_bdev, const struct ftl_nv_cache_device_type *,
2920c3c166SMateusz Kozlowski 	    (struct spdk_ftl_dev *dev, struct spdk_bdev *bdev), NULL);
3020c3c166SMateusz Kozlowski 
31a05d3047SArtur Paszkiewicz uint64_t
32a05d3047SArtur Paszkiewicz spdk_bdev_get_zone_size(const struct spdk_bdev *bdev)
33a05d3047SArtur Paszkiewicz {
34a05d3047SArtur Paszkiewicz 	return g_geo.zone_size;
35a05d3047SArtur Paszkiewicz }
36a05d3047SArtur Paszkiewicz 
37a05d3047SArtur Paszkiewicz uint32_t
38a05d3047SArtur Paszkiewicz spdk_bdev_get_optimal_open_zones(const struct spdk_bdev *bdev)
39a05d3047SArtur Paszkiewicz {
40a05d3047SArtur Paszkiewicz 	return g_geo.optimal_open_zones;
41a05d3047SArtur Paszkiewicz }
42a05d3047SArtur Paszkiewicz 
43a05d3047SArtur Paszkiewicz DEFINE_RETURN_MOCK(ftl_mempool_get, void *);
44a05d3047SArtur Paszkiewicz void *
45a05d3047SArtur Paszkiewicz ftl_mempool_get(struct ftl_mempool *mpool)
46a05d3047SArtur Paszkiewicz {
47a05d3047SArtur Paszkiewicz 	return spdk_mempool_get((struct spdk_mempool *)mpool);
48a05d3047SArtur Paszkiewicz }
49a05d3047SArtur Paszkiewicz 
50a05d3047SArtur Paszkiewicz void
51a05d3047SArtur Paszkiewicz ftl_mempool_put(struct ftl_mempool *mpool, void *element)
52a05d3047SArtur Paszkiewicz {
53a05d3047SArtur Paszkiewicz 	spdk_mempool_put((struct spdk_mempool *)mpool, element);
54a05d3047SArtur Paszkiewicz }
55a05d3047SArtur Paszkiewicz 
56101a0399SKozlowski Mateusz ftl_df_obj_id
57101a0399SKozlowski Mateusz ftl_mempool_get_df_obj_id(struct ftl_mempool *mpool, void *df_obj_ptr)
58101a0399SKozlowski Mateusz {
59101a0399SKozlowski Mateusz 	return (ftl_df_obj_id)df_obj_ptr;
60101a0399SKozlowski Mateusz }
61101a0399SKozlowski Mateusz 
62a05d3047SArtur Paszkiewicz struct spdk_ftl_dev *
63a05d3047SArtur Paszkiewicz test_init_ftl_dev(const struct base_bdev_geometry *geo)
64a05d3047SArtur Paszkiewicz {
65a05d3047SArtur Paszkiewicz 	struct spdk_ftl_dev *dev;
66a05d3047SArtur Paszkiewicz 
67a05d3047SArtur Paszkiewicz 	dev = calloc(1, sizeof(*dev));
68a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(dev != NULL);
69a05d3047SArtur Paszkiewicz 
70a05d3047SArtur Paszkiewicz 	dev->xfer_size = geo->write_unit_size;
71a05d3047SArtur Paszkiewicz 	dev->core_thread = spdk_thread_create("unit_test_thread", NULL);
72a05d3047SArtur Paszkiewicz 	spdk_set_thread(dev->core_thread);
73a05d3047SArtur Paszkiewicz 	dev->ioch = calloc(1, SPDK_IO_CHANNEL_STRUCT_SIZE
74a05d3047SArtur Paszkiewicz 			   + sizeof(struct ftl_io_channel *));
75a05d3047SArtur Paszkiewicz 	dev->num_bands = geo->blockcnt / (geo->zone_size * geo->optimal_open_zones);
76a05d3047SArtur Paszkiewicz 	dev->bands = calloc(dev->num_bands, sizeof(*dev->bands));
77a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(dev->bands != NULL);
78a05d3047SArtur Paszkiewicz 
79a05d3047SArtur Paszkiewicz 	dev->layout.base.total_blocks = UINT64_MAX;
80a05d3047SArtur Paszkiewicz 
81a05d3047SArtur Paszkiewicz 	for (size_t i = 0; i < dev->num_bands; i++) {
82a05d3047SArtur Paszkiewicz 		struct ftl_band_md *md;
83a05d3047SArtur Paszkiewicz 		int ret;
84a05d3047SArtur Paszkiewicz 
85a05d3047SArtur Paszkiewicz 		ret = posix_memalign((void **)&md, FTL_BLOCK_SIZE, sizeof(*md));
86a05d3047SArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(ret == 0);
87a05d3047SArtur Paszkiewicz 		memset(md, 0, sizeof(*md));
88a05d3047SArtur Paszkiewicz 		dev->bands[i].md = md;
89a05d3047SArtur Paszkiewicz 	}
90a05d3047SArtur Paszkiewicz 
9130ef80cdSMateusz Kozlowski 	for (int i = 0; i < FTL_LAYOUT_REGION_TYPE_MAX; i++) {
9230ef80cdSMateusz Kozlowski 		dev->layout.region[i].type = i;
9330ef80cdSMateusz Kozlowski 	}
9430ef80cdSMateusz Kozlowski 
95a05d3047SArtur Paszkiewicz 	dev->p2l_pool = (struct ftl_mempool *)spdk_mempool_create("ftl_ut", 2, 0x210200,
96a05d3047SArtur Paszkiewicz 			SPDK_MEMPOOL_DEFAULT_CACHE_SIZE,
97*186b109dSJim Harris 			SPDK_ENV_NUMA_ID_ANY);
98a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(dev->p2l_pool != NULL);
99a05d3047SArtur Paszkiewicz 
100a05d3047SArtur Paszkiewicz 	TAILQ_INIT(&dev->free_bands);
101a05d3047SArtur Paszkiewicz 	TAILQ_INIT(&dev->shut_bands);
102a05d3047SArtur Paszkiewicz 
103a05d3047SArtur Paszkiewicz 	/* Cache frequently used values */
104a05d3047SArtur Paszkiewicz 	dev->num_blocks_in_band = ftl_calculate_num_blocks_in_band(dev->base_bdev_desc);
105a05d3047SArtur Paszkiewicz 	dev->is_zoned = spdk_bdev_is_zoned(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
106a05d3047SArtur Paszkiewicz 
107a05d3047SArtur Paszkiewicz 	return dev;
108a05d3047SArtur Paszkiewicz }
109a05d3047SArtur Paszkiewicz 
110a05d3047SArtur Paszkiewicz struct ftl_band *
111a05d3047SArtur Paszkiewicz test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id, size_t zone_size)
112a05d3047SArtur Paszkiewicz {
113a05d3047SArtur Paszkiewicz 	struct ftl_band *band;
114a05d3047SArtur Paszkiewicz 
115a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(dev != NULL);
116a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(id < dev->num_bands);
117a05d3047SArtur Paszkiewicz 
118a05d3047SArtur Paszkiewicz 	band = &dev->bands[id];
119a05d3047SArtur Paszkiewicz 	band->dev = dev;
120a05d3047SArtur Paszkiewicz 	band->id = id;
121a05d3047SArtur Paszkiewicz 
122a05d3047SArtur Paszkiewicz 	band->md->state = FTL_BAND_STATE_CLOSED;
123101a0399SKozlowski Mateusz 	band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
124a05d3047SArtur Paszkiewicz 	TAILQ_INSERT_HEAD(&dev->shut_bands, band, queue_entry);
125a05d3047SArtur Paszkiewicz 
126cea8dadeSArtur Paszkiewicz 	band->p2l_map.valid = (struct ftl_bitmap *)spdk_bit_array_create(ftl_get_num_blocks_in_band(dev));
127cea8dadeSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(band->p2l_map.valid != NULL);
128cea8dadeSArtur Paszkiewicz 
129a05d3047SArtur Paszkiewicz 	band->start_addr = zone_size * id;
130a05d3047SArtur Paszkiewicz 
131a05d3047SArtur Paszkiewicz 	return band;
132a05d3047SArtur Paszkiewicz }
133a05d3047SArtur Paszkiewicz 
134a05d3047SArtur Paszkiewicz void
135a05d3047SArtur Paszkiewicz test_free_ftl_dev(struct spdk_ftl_dev *dev)
136a05d3047SArtur Paszkiewicz {
137a05d3047SArtur Paszkiewicz 	struct spdk_thread *thread;
138a05d3047SArtur Paszkiewicz 
139a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(dev != NULL);
140a05d3047SArtur Paszkiewicz 	free(dev->ioch);
141a05d3047SArtur Paszkiewicz 
142a05d3047SArtur Paszkiewicz 	thread = dev->core_thread;
143a05d3047SArtur Paszkiewicz 
144a05d3047SArtur Paszkiewicz 	spdk_set_thread(thread);
145a05d3047SArtur Paszkiewicz 	spdk_thread_exit(thread);
146a05d3047SArtur Paszkiewicz 	while (!spdk_thread_is_exited(thread)) {
147a05d3047SArtur Paszkiewicz 		spdk_thread_poll(thread, 0, 0);
148a05d3047SArtur Paszkiewicz 	}
149a05d3047SArtur Paszkiewicz 	spdk_thread_destroy(thread);
150a05d3047SArtur Paszkiewicz 	spdk_mempool_free((struct spdk_mempool *)dev->p2l_pool);
151a05d3047SArtur Paszkiewicz 	for (size_t i = 0; i < dev->num_bands; i++) {
152a05d3047SArtur Paszkiewicz 		free(dev->bands[i].md);
153a05d3047SArtur Paszkiewicz 	}
154a05d3047SArtur Paszkiewicz 	free(dev->bands);
155a05d3047SArtur Paszkiewicz 	free(dev);
156a05d3047SArtur Paszkiewicz }
157a05d3047SArtur Paszkiewicz 
158a05d3047SArtur Paszkiewicz void
159a05d3047SArtur Paszkiewicz test_free_ftl_band(struct ftl_band *band)
160a05d3047SArtur Paszkiewicz {
161a05d3047SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(band != NULL);
162cea8dadeSArtur Paszkiewicz 	spdk_bit_array_free((struct spdk_bit_array **)&band->p2l_map.valid);
163a05d3047SArtur Paszkiewicz 	spdk_dma_free(band->p2l_map.band_dma_md);
164a05d3047SArtur Paszkiewicz 
165a05d3047SArtur Paszkiewicz 	band->p2l_map.band_dma_md = NULL;
166a05d3047SArtur Paszkiewicz }
167a05d3047SArtur Paszkiewicz 
168a05d3047SArtur Paszkiewicz uint64_t
169a05d3047SArtur Paszkiewicz test_offset_from_addr(ftl_addr addr, struct ftl_band *band)
170a05d3047SArtur Paszkiewicz {
171a05d3047SArtur Paszkiewicz 	struct spdk_ftl_dev *dev = band->dev;
172a05d3047SArtur Paszkiewicz 
173a05d3047SArtur Paszkiewicz 	CU_ASSERT_EQUAL(ftl_addr_get_band(dev, addr), band->id);
174a05d3047SArtur Paszkiewicz 
175a05d3047SArtur Paszkiewicz 	return addr - band->id * ftl_get_num_blocks_in_band(dev);
176a05d3047SArtur Paszkiewicz }
177