1950cce2cSKozlowski Mateusz /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2019 Intel Corporation. 3950cce2cSKozlowski Mateusz * All rights reserved. 4950cce2cSKozlowski Mateusz */ 5950cce2cSKozlowski Mateusz 6950cce2cSKozlowski Mateusz #include "spdk/stdinc.h" 7950cce2cSKozlowski Mateusz 8ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 9950cce2cSKozlowski Mateusz #include "common/lib/ut_multithread.c" 10950cce2cSKozlowski Mateusz 11950cce2cSKozlowski Mateusz #include "ftl/ftl_io.c" 12950cce2cSKozlowski Mateusz #include "ftl/utils/ftl_conf.c" 13950cce2cSKozlowski Mateusz 14950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0); 15950cce2cSKozlowski Mateusz DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc)); 16950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *, (struct spdk_bdev_desc *desc), NULL); 17950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_optimal_open_zones, uint32_t, (const struct spdk_bdev *b), 1); 18950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_by_name, struct spdk_bdev *, (const char *bdev_name), NULL); 19950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_is_md_separate, bool, (const struct spdk_bdev *bdev), false); 20950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_is_zoned, bool, (const struct spdk_bdev *bdev), false); 21950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_zone_appendv, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 22950cce2cSKozlowski Mateusz struct iovec *iov, int iovcnt, uint64_t zone_id, uint64_t num_blocks, 23950cce2cSKozlowski Mateusz spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 24950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_zone_size, uint64_t, (const struct spdk_bdev *b), 1024); 25950cce2cSKozlowski Mateusz DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 26950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_buf_align, size_t, (const struct spdk_bdev *bdev), 64); 27950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, 28950cce2cSKozlowski Mateusz (const struct spdk_bdev *bdev), 0); 29950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test"); 30950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_write_unit_size, uint32_t, 31950cce2cSKozlowski Mateusz (const struct spdk_bdev *bdev), 0); 32950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev, 33950cce2cSKozlowski Mateusz enum spdk_bdev_io_type io_type), true); 34950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_open_ext, int, 35950cce2cSKozlowski Mateusz (const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 36950cce2cSKozlowski Mateusz void *event_ctx, struct spdk_bdev_desc **desc), 0); 37950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_read_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 38950cce2cSKozlowski Mateusz void *buf, uint64_t offset_blocks, uint64_t num_blocks, 39950cce2cSKozlowski Mateusz spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 40950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_write_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 41950cce2cSKozlowski Mateusz void *buf, uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 42950cce2cSKozlowski Mateusz void *cb_arg), 0); 43950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_write_blocks_with_md, int, (struct spdk_bdev_desc *desc, 44950cce2cSKozlowski Mateusz struct spdk_io_channel *ch, void *buf, void *md, uint64_t offset_blocks, 45950cce2cSKozlowski Mateusz uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 46950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_writev_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 47950cce2cSKozlowski Mateusz struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks, 48950cce2cSKozlowski Mateusz spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 49950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_num_blocks, uint64_t, (const struct spdk_bdev *bdev), 1024); 50950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, (const struct spdk_bdev *bdev), 0); 51950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, (const struct spdk_bdev *bdev), 4096); 52950cce2cSKozlowski Mateusz DEFINE_STUB_V(spdk_bdev_module_release_bdev, (struct spdk_bdev *bdev)); 53950cce2cSKozlowski Mateusz DEFINE_STUB(spdk_bdev_write_zeroes_blocks, int, 54950cce2cSKozlowski Mateusz (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 55950cce2cSKozlowski Mateusz uint64_t offset_blocks, uint64_t num_blocks, 56950cce2cSKozlowski Mateusz spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 5743a4d47aSKozlowski Mateusz DEFINE_STUB_V(ftl_reloc, (struct ftl_reloc *reloc)); 5843a4d47aSKozlowski Mateusz DEFINE_STUB_V(ftl_reloc_free, (struct ftl_reloc *reloc)); 5943a4d47aSKozlowski Mateusz DEFINE_STUB_V(ftl_reloc_halt, (struct ftl_reloc *reloc)); 6043a4d47aSKozlowski Mateusz DEFINE_STUB(ftl_reloc_init, struct ftl_reloc *, (struct spdk_ftl_dev *dev), NULL); 6143a4d47aSKozlowski Mateusz DEFINE_STUB(ftl_reloc_is_halted, bool, (const struct ftl_reloc *reloc), false); 6243a4d47aSKozlowski Mateusz DEFINE_STUB_V(ftl_reloc_resume, (struct ftl_reloc *reloc)); 63950cce2cSKozlowski Mateusz DEFINE_STUB_V(ftl_l2p_unpin, (struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count)); 641738488eSArtur Paszkiewicz DEFINE_STUB(ftl_p2l_ckpt_acquire, struct ftl_p2l_ckpt *, (struct spdk_ftl_dev *dev), NULL); 651738488eSArtur Paszkiewicz DEFINE_STUB_V(ftl_p2l_ckpt_release, (struct spdk_ftl_dev *dev, struct ftl_p2l_ckpt *ckpt)); 66950cce2cSKozlowski Mateusz DEFINE_STUB(ftl_l2p_get, ftl_addr, (struct spdk_ftl_dev *dev, uint64_t lba), 0); 67950cce2cSKozlowski Mateusz DEFINE_STUB_V(ftl_mempool_put, (struct ftl_mempool *mpool, void *element)); 68119935ccSMateusz Kozlowski DEFINE_STUB_V(ftl_property_dump_bool, (struct spdk_ftl_dev *dev, 69119935ccSMateusz Kozlowski const struct ftl_property *property, 70119935ccSMateusz Kozlowski struct spdk_json_write_ctx *w)); 71217332a9SMateusz Kozlowski DEFINE_STUB(ftl_property_decode_bool, int, (struct spdk_ftl_dev *dev, struct ftl_property *property, 72217332a9SMateusz Kozlowski const char *value, size_t value_size, void *output, size_t output_size), 0); 73217332a9SMateusz Kozlowski DEFINE_STUB_V(ftl_property_set_generic, (struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt, 74217332a9SMateusz Kozlowski const struct ftl_property *property, void *new_value, size_t new_value_size)); 75217332a9SMateusz Kozlowski DEFINE_STUB_V(ftl_property_register, (struct spdk_ftl_dev *dev, 76217332a9SMateusz Kozlowski const char *name, void *value, size_t size, 77217332a9SMateusz Kozlowski const char *unit, const char *desc, 78217332a9SMateusz Kozlowski ftl_property_dump_fn dump, 79217332a9SMateusz Kozlowski ftl_property_decode_fn decode, 80*ebcb0d71SMateusz Kozlowski ftl_property_set_fn set, 81*ebcb0d71SMateusz Kozlowski bool verbose_mode)); 82950cce2cSKozlowski Mateusz 838a76d550SArtur Paszkiewicz #if defined(DEBUG) 848a76d550SArtur Paszkiewicz DEFINE_STUB_V(ftl_trace_submission, (struct spdk_ftl_dev *dev, const struct ftl_io *io, 858a76d550SArtur Paszkiewicz ftl_addr addr, size_t addr_cnt)); 868a76d550SArtur Paszkiewicz DEFINE_STUB_V(ftl_trace_lba_io_init, (struct spdk_ftl_dev *dev, const struct ftl_io *io)); 878a76d550SArtur Paszkiewicz DEFINE_STUB_V(ftl_trace_limits, (struct spdk_ftl_dev *dev, int limit, size_t num_free)); 888a76d550SArtur Paszkiewicz DEFINE_STUB(ftl_trace_alloc_id, uint64_t, (struct spdk_ftl_dev *dev), 0); 898a76d550SArtur Paszkiewicz DEFINE_STUB_V(ftl_trace_completion, (struct spdk_ftl_dev *dev, const struct ftl_io *io, 908a76d550SArtur Paszkiewicz enum ftl_trace_completion type)); 918a76d550SArtur Paszkiewicz DEFINE_STUB_V(ftl_trace_write_band, (struct spdk_ftl_dev *dev, const struct ftl_band *band)); 928a76d550SArtur Paszkiewicz #endif 938a76d550SArtur Paszkiewicz 94950cce2cSKozlowski Mateusz #if defined(FTL_DUMP_STATS) 95950cce2cSKozlowski Mateusz DEFINE_STUB_V(ftl_dev_dump_stats, (const struct spdk_ftl_dev *dev)); 96950cce2cSKozlowski Mateusz #endif 97950cce2cSKozlowski Mateusz 98950cce2cSKozlowski Mateusz struct ftl_io_channel_ctx { 99950cce2cSKozlowski Mateusz struct ftl_io_channel *ioch; 100950cce2cSKozlowski Mateusz }; 101950cce2cSKozlowski Mateusz 102950cce2cSKozlowski Mateusz struct ftl_io_channel * 103950cce2cSKozlowski Mateusz ftl_io_channel_get_ctx(struct spdk_io_channel *ioch) 104950cce2cSKozlowski Mateusz { 105950cce2cSKozlowski Mateusz struct ftl_io_channel_ctx *ctx = spdk_io_channel_get_ctx(ioch); 106950cce2cSKozlowski Mateusz 107950cce2cSKozlowski Mateusz return ctx->ioch; 108950cce2cSKozlowski Mateusz } 109950cce2cSKozlowski Mateusz 110950cce2cSKozlowski Mateusz struct spdk_io_channel * 111950cce2cSKozlowski Mateusz spdk_bdev_get_io_channel(struct spdk_bdev_desc *bdev_desc) 112950cce2cSKozlowski Mateusz { 113950cce2cSKozlowski Mateusz return spdk_get_io_channel(bdev_desc); 114950cce2cSKozlowski Mateusz } 115950cce2cSKozlowski Mateusz 116950cce2cSKozlowski Mateusz static int 117950cce2cSKozlowski Mateusz channel_create_cb(void *io_device, void *ctx) 118950cce2cSKozlowski Mateusz { 119950cce2cSKozlowski Mateusz return 0; 120950cce2cSKozlowski Mateusz } 121950cce2cSKozlowski Mateusz 122950cce2cSKozlowski Mateusz static void 123950cce2cSKozlowski Mateusz channel_destroy_cb(void *io_device, void *ctx) 124950cce2cSKozlowski Mateusz { 125950cce2cSKozlowski Mateusz } 126950cce2cSKozlowski Mateusz 127950cce2cSKozlowski Mateusz static struct spdk_ftl_dev * 128950cce2cSKozlowski Mateusz setup_device(uint32_t num_threads, uint32_t xfer_size) 129950cce2cSKozlowski Mateusz { 130950cce2cSKozlowski Mateusz struct spdk_ftl_dev *dev; 131950cce2cSKozlowski Mateusz struct ftl_io_channel *ioch; 132950cce2cSKozlowski Mateusz struct ftl_io_channel_ctx *ctx; 133950cce2cSKozlowski Mateusz 134950cce2cSKozlowski Mateusz allocate_threads(num_threads); 135950cce2cSKozlowski Mateusz set_thread(0); 136950cce2cSKozlowski Mateusz 137950cce2cSKozlowski Mateusz dev = calloc(1, sizeof(*dev)); 138950cce2cSKozlowski Mateusz SPDK_CU_ASSERT_FATAL(dev != NULL); 139950cce2cSKozlowski Mateusz 140950cce2cSKozlowski Mateusz dev->core_thread = spdk_get_thread(); 141950cce2cSKozlowski Mateusz dev->ioch = calloc(1, SPDK_IO_CHANNEL_STRUCT_SIZE + sizeof(struct ftl_io_channel_ctx)); 142950cce2cSKozlowski Mateusz SPDK_CU_ASSERT_FATAL(dev->ioch != NULL); 143950cce2cSKozlowski Mateusz 144950cce2cSKozlowski Mateusz ctx = spdk_io_channel_get_ctx(dev->ioch); 145950cce2cSKozlowski Mateusz ctx->ioch = calloc(1, sizeof(*ctx->ioch)); 146950cce2cSKozlowski Mateusz 147950cce2cSKozlowski Mateusz ioch = ftl_io_channel_get_ctx(dev->ioch); 148950cce2cSKozlowski Mateusz SPDK_CU_ASSERT_FATAL(ioch != NULL); 149950cce2cSKozlowski Mateusz 150950cce2cSKozlowski Mateusz ioch->cq = spdk_ring_create(0, 1024, 0); 151950cce2cSKozlowski Mateusz 152950cce2cSKozlowski Mateusz dev->conf = g_default_conf; 153950cce2cSKozlowski Mateusz dev->xfer_size = xfer_size; 154950cce2cSKozlowski Mateusz dev->base_bdev_desc = (struct spdk_bdev_desc *)0xdeadbeef; 155a68a12a4SKozlowski Mateusz dev->nv_cache.bdev_desc = (struct spdk_bdev_desc *)0xdead1234; 156950cce2cSKozlowski Mateusz spdk_io_device_register(dev, channel_create_cb, channel_destroy_cb, 0, NULL); 157950cce2cSKozlowski Mateusz spdk_io_device_register(dev->base_bdev_desc, channel_create_cb, channel_destroy_cb, 0, NULL); 158a68a12a4SKozlowski Mateusz spdk_io_device_register(dev->nv_cache.bdev_desc, channel_create_cb, channel_destroy_cb, 0, NULL); 159950cce2cSKozlowski Mateusz 160950cce2cSKozlowski Mateusz TAILQ_INIT(&dev->ioch_queue); 161950cce2cSKozlowski Mateusz 162950cce2cSKozlowski Mateusz return dev; 163950cce2cSKozlowski Mateusz } 164950cce2cSKozlowski Mateusz 165950cce2cSKozlowski Mateusz static void 166950cce2cSKozlowski Mateusz free_device(struct spdk_ftl_dev *dev) 167950cce2cSKozlowski Mateusz { 168950cce2cSKozlowski Mateusz struct ftl_io_channel *ioch; 169950cce2cSKozlowski Mateusz 170950cce2cSKozlowski Mateusz ioch = ftl_io_channel_get_ctx(dev->ioch); 171950cce2cSKozlowski Mateusz spdk_ring_free(ioch->cq); 172950cce2cSKozlowski Mateusz free(ioch); 173950cce2cSKozlowski Mateusz 174950cce2cSKozlowski Mateusz spdk_io_device_unregister(dev, NULL); 175950cce2cSKozlowski Mateusz spdk_io_device_unregister(dev->base_bdev_desc, NULL); 176a68a12a4SKozlowski Mateusz spdk_io_device_unregister(dev->nv_cache.bdev_desc, NULL); 177950cce2cSKozlowski Mateusz 178950cce2cSKozlowski Mateusz while (!TAILQ_EMPTY(&dev->ioch_queue)) { 179950cce2cSKozlowski Mateusz TAILQ_REMOVE(&dev->ioch_queue, TAILQ_FIRST(&dev->ioch_queue), entry); 180950cce2cSKozlowski Mateusz } 181950cce2cSKozlowski Mateusz 182950cce2cSKozlowski Mateusz free_threads(); 183950cce2cSKozlowski Mateusz 184950cce2cSKozlowski Mateusz free(dev->ioch); 185c6880a39SArtur Paszkiewicz free(dev->sb); 186950cce2cSKozlowski Mateusz free(dev); 187950cce2cSKozlowski Mateusz } 188950cce2cSKozlowski Mateusz 189950cce2cSKozlowski Mateusz static void 190950cce2cSKozlowski Mateusz setup_io(struct ftl_io *io, struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *ctx) 191950cce2cSKozlowski Mateusz { 192950cce2cSKozlowski Mateusz io->dev = dev; 193950cce2cSKozlowski Mateusz io->user_fn = cb; 194950cce2cSKozlowski Mateusz io->cb_ctx = ctx; 195950cce2cSKozlowski Mateusz io->flags = 0; 196950cce2cSKozlowski Mateusz io->ioch = dev->ioch; 197950cce2cSKozlowski Mateusz } 198950cce2cSKozlowski Mateusz 199950cce2cSKozlowski Mateusz static void 200950cce2cSKozlowski Mateusz io_complete_cb(void *ctx, int status) 201950cce2cSKozlowski Mateusz { 202950cce2cSKozlowski Mateusz *(int *)ctx = status; 203950cce2cSKozlowski Mateusz } 204950cce2cSKozlowski Mateusz 205950cce2cSKozlowski Mateusz static void 206950cce2cSKozlowski Mateusz test_completion(void) 207950cce2cSKozlowski Mateusz { 208950cce2cSKozlowski Mateusz struct spdk_ftl_dev *dev; 209950cce2cSKozlowski Mateusz struct ftl_io_channel *ioch; 210950cce2cSKozlowski Mateusz struct ftl_io io = { 0 }, *io_ring; 211950cce2cSKozlowski Mateusz int req, status = 0; 212950cce2cSKozlowski Mateusz 213950cce2cSKozlowski Mateusz dev = setup_device(1, FTL_NUM_LBA_IN_BLOCK); 214950cce2cSKozlowski Mateusz ioch = ftl_io_channel_get_ctx(dev->ioch); 215950cce2cSKozlowski Mateusz 216950cce2cSKozlowski Mateusz /* Setup IO and 'send' NUM_REQUESTS subrequests */ 217950cce2cSKozlowski Mateusz setup_io(&io, dev, io_complete_cb, &status); 218950cce2cSKozlowski Mateusz io.status = -EIO; 219950cce2cSKozlowski Mateusz 220950cce2cSKozlowski Mateusz #define NUM_REQUESTS 16 221950cce2cSKozlowski Mateusz for (req = 0; req < NUM_REQUESTS; ++req) { 222950cce2cSKozlowski Mateusz ftl_io_inc_req(&io); 223950cce2cSKozlowski Mateusz CU_ASSERT_FALSE(ftl_io_done(&io)); 224950cce2cSKozlowski Mateusz } 225950cce2cSKozlowski Mateusz 226950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(io.req_cnt, NUM_REQUESTS); 227950cce2cSKozlowski Mateusz 228950cce2cSKozlowski Mateusz /* Complete all but one subrequest, make sure io still not marked as done */ 229950cce2cSKozlowski Mateusz for (req = 0; req < (NUM_REQUESTS - 1); ++req) { 230950cce2cSKozlowski Mateusz ftl_io_dec_req(&io); 231950cce2cSKozlowski Mateusz CU_ASSERT_FALSE(ftl_io_done(&io)); 232950cce2cSKozlowski Mateusz } 233950cce2cSKozlowski Mateusz 234950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(io.req_cnt, 1); 235950cce2cSKozlowski Mateusz 236950cce2cSKozlowski Mateusz /* Complete last subrequest, make sure it appears on the completion queue */ 237950cce2cSKozlowski Mateusz ftl_io_dec_req(&io); 238950cce2cSKozlowski Mateusz CU_ASSERT_TRUE(ftl_io_done(&io)); 239950cce2cSKozlowski Mateusz 240950cce2cSKozlowski Mateusz ftl_io_complete(&io); 241950cce2cSKozlowski Mateusz 242950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(spdk_ring_count(ioch->cq), 1); 243950cce2cSKozlowski Mateusz 244950cce2cSKozlowski Mateusz /* Dequeue and check if the completion callback changes the status, this is usually done via poller */ 245950cce2cSKozlowski Mateusz spdk_ring_dequeue(ioch->cq, (void **)&io_ring, 1); 246950cce2cSKozlowski Mateusz io_ring->user_fn(io_ring->cb_ctx, io_ring->status); 247950cce2cSKozlowski Mateusz 248950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(status, -EIO); 249950cce2cSKozlowski Mateusz 250950cce2cSKozlowski Mateusz free_device(dev); 251950cce2cSKozlowski Mateusz } 252950cce2cSKozlowski Mateusz 253950cce2cSKozlowski Mateusz static void 254950cce2cSKozlowski Mateusz test_multiple_ios(void) 255950cce2cSKozlowski Mateusz { 256950cce2cSKozlowski Mateusz struct spdk_ftl_dev *dev; 257950cce2cSKozlowski Mateusz struct ftl_io_channel *ioch; 258950cce2cSKozlowski Mateusz struct ftl_io io[2] = { 0 }, *io_ring[2]; 259950cce2cSKozlowski Mateusz int status = -1; 260950cce2cSKozlowski Mateusz 261950cce2cSKozlowski Mateusz dev = setup_device(1, FTL_NUM_LBA_IN_BLOCK); 262950cce2cSKozlowski Mateusz ioch = ftl_io_channel_get_ctx(dev->ioch); 263950cce2cSKozlowski Mateusz 264950cce2cSKozlowski Mateusz /* Send t2o IOs and check if both are in the completion queue */ 265950cce2cSKozlowski Mateusz setup_io(&io[0], dev, io_complete_cb, &status); 266950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(spdk_ring_count(ioch->cq), 0); 267950cce2cSKozlowski Mateusz 268950cce2cSKozlowski Mateusz ftl_io_complete(io); 269950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(spdk_ring_count(ioch->cq), 1); 270950cce2cSKozlowski Mateusz 271950cce2cSKozlowski Mateusz setup_io(&io[1], dev, io_complete_cb, &status); 272950cce2cSKozlowski Mateusz 273950cce2cSKozlowski Mateusz ftl_io_complete(&io[1]); 274950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(spdk_ring_count(ioch->cq), 2); 275950cce2cSKozlowski Mateusz 276950cce2cSKozlowski Mateusz /* Dequeue and check if the completion callback changes the status, this is usually done via poller */ 277950cce2cSKozlowski Mateusz spdk_ring_dequeue(ioch->cq, (void **)io_ring, 2); 278950cce2cSKozlowski Mateusz status = -1; 279950cce2cSKozlowski Mateusz io_ring[0]->user_fn(io_ring[0]->cb_ctx, io_ring[0]->status); 280950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(status, 0); 281950cce2cSKozlowski Mateusz status = -1; 282950cce2cSKozlowski Mateusz io_ring[1]->user_fn(io_ring[1]->cb_ctx, io_ring[1]->status); 283950cce2cSKozlowski Mateusz CU_ASSERT_EQUAL(status, 0); 284950cce2cSKozlowski Mateusz 285950cce2cSKozlowski Mateusz free_device(dev); 286950cce2cSKozlowski Mateusz } 287950cce2cSKozlowski Mateusz 288950cce2cSKozlowski Mateusz int 289950cce2cSKozlowski Mateusz main(int argc, char **argv) 290950cce2cSKozlowski Mateusz { 291950cce2cSKozlowski Mateusz CU_pSuite suite; 292950cce2cSKozlowski Mateusz unsigned int num_failures; 293950cce2cSKozlowski Mateusz 294950cce2cSKozlowski Mateusz CU_initialize_registry(); 295950cce2cSKozlowski Mateusz 296950cce2cSKozlowski Mateusz suite = CU_add_suite("ftl_io_suite", NULL, NULL); 297950cce2cSKozlowski Mateusz 298950cce2cSKozlowski Mateusz 299950cce2cSKozlowski Mateusz CU_ADD_TEST(suite, test_completion); 300950cce2cSKozlowski Mateusz CU_ADD_TEST(suite, test_multiple_ios); 301950cce2cSKozlowski Mateusz 302ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 303950cce2cSKozlowski Mateusz CU_cleanup_registry(); 304950cce2cSKozlowski Mateusz 305950cce2cSKozlowski Mateusz return num_failures; 306950cce2cSKozlowski Mateusz } 307