169038a94SKrzysztof Smolinski /* SPDX-License-Identifier: BSD-3-Clause 269038a94SKrzysztof Smolinski * Copyright (C) 2022 Intel Corporation. 369038a94SKrzysztof Smolinski * All rights reserved. 469038a94SKrzysztof Smolinski */ 569038a94SKrzysztof Smolinski 669038a94SKrzysztof Smolinski #include "spdk/stdinc.h" 7ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 869038a94SKrzysztof Smolinski #include "spdk/env.h" 9a73acd9fSKrzysztof Smolinski 10a73acd9fSKrzysztof Smolinski #include "common/lib/ut_multithread.c" 1169038a94SKrzysztof Smolinski 1269038a94SKrzysztof Smolinski #include "bdev/raid/raid1.c" 1369038a94SKrzysztof Smolinski #include "../common.c" 1469038a94SKrzysztof Smolinski 15b0b0889eSArtur Paszkiewicz static enum spdk_bdev_io_status g_io_status; 16cc94f303SArtur Paszkiewicz static struct spdk_bdev_desc *g_last_io_desc; 17cc94f303SArtur Paszkiewicz static spdk_bdev_io_completion_cb g_last_io_cb; 18b0b0889eSArtur Paszkiewicz 1969038a94SKrzysztof Smolinski DEFINE_STUB_V(raid_bdev_module_list_add, (struct raid_bdev_module *raid_module)); 20a73acd9fSKrzysztof Smolinski DEFINE_STUB_V(raid_bdev_module_stop_done, (struct raid_bdev *raid_bdev)); 2169038a94SKrzysztof Smolinski DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 2269038a94SKrzysztof Smolinski DEFINE_STUB_V(raid_bdev_queue_io_wait, (struct raid_bdev_io *raid_io, struct spdk_bdev *bdev, 2369038a94SKrzysztof Smolinski struct spdk_io_channel *ch, spdk_bdev_io_wait_cb cb_fn)); 24aefa99f1SArtur Paszkiewicz DEFINE_STUB_V(raid_bdev_process_request_complete, (struct raid_bdev_process_request *process_req, 25aefa99f1SArtur Paszkiewicz int status)); 26aefa99f1SArtur Paszkiewicz DEFINE_STUB_V(raid_bdev_io_init, (struct raid_bdev_io *raid_io, 27aefa99f1SArtur Paszkiewicz struct raid_bdev_io_channel *raid_ch, 28aefa99f1SArtur Paszkiewicz enum spdk_bdev_io_type type, uint64_t offset_blocks, 29aefa99f1SArtur Paszkiewicz uint64_t num_blocks, struct iovec *iovs, int iovcnt, void *md_buf, 30aefa99f1SArtur Paszkiewicz struct spdk_memory_domain *memory_domain, void *memory_domain_ctx)); 311b9c5629SArtur Paszkiewicz DEFINE_STUB(raid_bdev_remap_dix_reftag, int, (void *md_buf, uint64_t num_blocks, 321b9c5629SArtur Paszkiewicz struct spdk_bdev *bdev, uint32_t remapped_offset), -1); 33*3b9baa5fSLoïc Yavercovski DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0); 3469038a94SKrzysztof Smolinski 35cc94f303SArtur Paszkiewicz int 36cc94f303SArtur Paszkiewicz spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, 37cc94f303SArtur Paszkiewicz struct spdk_io_channel *ch, 38cc94f303SArtur Paszkiewicz struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks, 39cc94f303SArtur Paszkiewicz spdk_bdev_io_completion_cb cb, void *cb_arg, struct spdk_bdev_ext_io_opts *opts) 40cc94f303SArtur Paszkiewicz { 41cc94f303SArtur Paszkiewicz g_last_io_desc = desc; 42cc94f303SArtur Paszkiewicz g_last_io_cb = cb; 43cc94f303SArtur Paszkiewicz 44cc94f303SArtur Paszkiewicz return 0; 45cc94f303SArtur Paszkiewicz } 46cc94f303SArtur Paszkiewicz 47cc94f303SArtur Paszkiewicz int 48cc94f303SArtur Paszkiewicz spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, 49cc94f303SArtur Paszkiewicz struct spdk_io_channel *ch, 50cc94f303SArtur Paszkiewicz struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks, 51cc94f303SArtur Paszkiewicz spdk_bdev_io_completion_cb cb, void *cb_arg, struct spdk_bdev_ext_io_opts *opts) 52cc94f303SArtur Paszkiewicz { 53cc94f303SArtur Paszkiewicz g_last_io_desc = desc; 54cc94f303SArtur Paszkiewicz g_last_io_cb = cb; 55cc94f303SArtur Paszkiewicz 56cc94f303SArtur Paszkiewicz return 0; 57cc94f303SArtur Paszkiewicz } 58cc94f303SArtur Paszkiewicz 59b0b0889eSArtur Paszkiewicz void 60b0b0889eSArtur Paszkiewicz raid_bdev_fail_base_bdev(struct raid_base_bdev_info *base_info) 61b0b0889eSArtur Paszkiewicz { 62b0b0889eSArtur Paszkiewicz base_info->is_failed = true; 63b0b0889eSArtur Paszkiewicz } 64b0b0889eSArtur Paszkiewicz 6569038a94SKrzysztof Smolinski static int 6669038a94SKrzysztof Smolinski test_setup(void) 6769038a94SKrzysztof Smolinski { 6869038a94SKrzysztof Smolinski uint8_t num_base_bdevs_values[] = { 2, 3 }; 6969038a94SKrzysztof Smolinski uint64_t base_bdev_blockcnt_values[] = { 1, 1024, 1024 * 1024 }; 7069038a94SKrzysztof Smolinski uint32_t base_bdev_blocklen_values[] = { 512, 4096 }; 7169038a94SKrzysztof Smolinski uint8_t *num_base_bdevs; 7269038a94SKrzysztof Smolinski uint64_t *base_bdev_blockcnt; 7369038a94SKrzysztof Smolinski uint32_t *base_bdev_blocklen; 7469038a94SKrzysztof Smolinski uint64_t params_count; 7569038a94SKrzysztof Smolinski int rc; 7669038a94SKrzysztof Smolinski 7769038a94SKrzysztof Smolinski params_count = SPDK_COUNTOF(num_base_bdevs_values) * 7869038a94SKrzysztof Smolinski SPDK_COUNTOF(base_bdev_blockcnt_values) * 7969038a94SKrzysztof Smolinski SPDK_COUNTOF(base_bdev_blocklen_values); 8069038a94SKrzysztof Smolinski rc = raid_test_params_alloc(params_count); 8169038a94SKrzysztof Smolinski if (rc) { 8269038a94SKrzysztof Smolinski return rc; 8369038a94SKrzysztof Smolinski } 8469038a94SKrzysztof Smolinski 8569038a94SKrzysztof Smolinski ARRAY_FOR_EACH(num_base_bdevs_values, num_base_bdevs) { 8669038a94SKrzysztof Smolinski ARRAY_FOR_EACH(base_bdev_blockcnt_values, base_bdev_blockcnt) { 8769038a94SKrzysztof Smolinski ARRAY_FOR_EACH(base_bdev_blocklen_values, base_bdev_blocklen) { 8899537401SArtur Paszkiewicz struct raid_params params = { 8999537401SArtur Paszkiewicz .num_base_bdevs = *num_base_bdevs, 9099537401SArtur Paszkiewicz .base_bdev_blockcnt = *base_bdev_blockcnt, 9199537401SArtur Paszkiewicz .base_bdev_blocklen = *base_bdev_blocklen, 9299537401SArtur Paszkiewicz }; 9369038a94SKrzysztof Smolinski raid_test_params_add(¶ms); 9469038a94SKrzysztof Smolinski } 9569038a94SKrzysztof Smolinski } 9669038a94SKrzysztof Smolinski } 9769038a94SKrzysztof Smolinski 9869038a94SKrzysztof Smolinski return 0; 9969038a94SKrzysztof Smolinski } 10069038a94SKrzysztof Smolinski 10169038a94SKrzysztof Smolinski static int 10269038a94SKrzysztof Smolinski test_cleanup(void) 10369038a94SKrzysztof Smolinski { 10469038a94SKrzysztof Smolinski raid_test_params_free(); 10569038a94SKrzysztof Smolinski return 0; 10669038a94SKrzysztof Smolinski } 10769038a94SKrzysztof Smolinski 10869038a94SKrzysztof Smolinski static struct raid1_info * 10969038a94SKrzysztof Smolinski create_raid1(struct raid_params *params) 11069038a94SKrzysztof Smolinski { 11169038a94SKrzysztof Smolinski struct raid_bdev *raid_bdev = raid_test_create_raid_bdev(params, &g_raid1_module); 11269038a94SKrzysztof Smolinski 11369038a94SKrzysztof Smolinski SPDK_CU_ASSERT_FATAL(raid1_start(raid_bdev) == 0); 11469038a94SKrzysztof Smolinski 11569038a94SKrzysztof Smolinski return raid_bdev->module_private; 11669038a94SKrzysztof Smolinski } 11769038a94SKrzysztof Smolinski 11869038a94SKrzysztof Smolinski static void 11969038a94SKrzysztof Smolinski delete_raid1(struct raid1_info *r1_info) 12069038a94SKrzysztof Smolinski { 12169038a94SKrzysztof Smolinski struct raid_bdev *raid_bdev = r1_info->raid_bdev; 12269038a94SKrzysztof Smolinski 12369038a94SKrzysztof Smolinski raid1_stop(raid_bdev); 12469038a94SKrzysztof Smolinski 12569038a94SKrzysztof Smolinski raid_test_delete_raid_bdev(raid_bdev); 12669038a94SKrzysztof Smolinski } 12769038a94SKrzysztof Smolinski 12869038a94SKrzysztof Smolinski static void 12969038a94SKrzysztof Smolinski test_raid1_start(void) 13069038a94SKrzysztof Smolinski { 13169038a94SKrzysztof Smolinski struct raid_params *params; 13269038a94SKrzysztof Smolinski 13369038a94SKrzysztof Smolinski RAID_PARAMS_FOR_EACH(params) { 13469038a94SKrzysztof Smolinski struct raid1_info *r1_info; 13569038a94SKrzysztof Smolinski 13669038a94SKrzysztof Smolinski r1_info = create_raid1(params); 13769038a94SKrzysztof Smolinski 13869038a94SKrzysztof Smolinski SPDK_CU_ASSERT_FATAL(r1_info != NULL); 13969038a94SKrzysztof Smolinski 14069038a94SKrzysztof Smolinski CU_ASSERT_EQUAL(r1_info->raid_bdev->level, RAID1); 14169038a94SKrzysztof Smolinski CU_ASSERT_EQUAL(r1_info->raid_bdev->bdev.blockcnt, params->base_bdev_blockcnt); 14269038a94SKrzysztof Smolinski CU_ASSERT_PTR_EQUAL(r1_info->raid_bdev->module, &g_raid1_module); 14369038a94SKrzysztof Smolinski 14469038a94SKrzysztof Smolinski delete_raid1(r1_info); 14569038a94SKrzysztof Smolinski } 14669038a94SKrzysztof Smolinski } 14769038a94SKrzysztof Smolinski 1485da1742bSKrzysztof Smolinski static struct raid_bdev_io * 1495da1742bSKrzysztof Smolinski get_raid_io(struct raid1_info *r1_info, struct raid_bdev_io_channel *raid_ch, 1505da1742bSKrzysztof Smolinski enum spdk_bdev_io_type io_type, uint64_t num_blocks) 1515da1742bSKrzysztof Smolinski { 1525da1742bSKrzysztof Smolinski struct raid_bdev_io *raid_io; 1535da1742bSKrzysztof Smolinski 154a4e1703eSArtur Paszkiewicz raid_io = calloc(1, sizeof(*raid_io)); 155a4e1703eSArtur Paszkiewicz SPDK_CU_ASSERT_FATAL(raid_io != NULL); 1565da1742bSKrzysztof Smolinski 157a4e1703eSArtur Paszkiewicz raid_test_bdev_io_init(raid_io, r1_info->raid_bdev, raid_ch, io_type, 0, num_blocks, NULL, 0, NULL); 1585da1742bSKrzysztof Smolinski 1595da1742bSKrzysztof Smolinski return raid_io; 1605da1742bSKrzysztof Smolinski } 1615da1742bSKrzysztof Smolinski 1625da1742bSKrzysztof Smolinski static void 1635da1742bSKrzysztof Smolinski put_raid_io(struct raid_bdev_io *raid_io) 1645da1742bSKrzysztof Smolinski { 165a4e1703eSArtur Paszkiewicz free(raid_io); 166a4e1703eSArtur Paszkiewicz } 167a4e1703eSArtur Paszkiewicz 168fc3c9b37SArtur Paszkiewicz void 169a4e1703eSArtur Paszkiewicz raid_test_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status) 170a4e1703eSArtur Paszkiewicz { 171b0b0889eSArtur Paszkiewicz g_io_status = status; 172a4e1703eSArtur Paszkiewicz 173a4e1703eSArtur Paszkiewicz put_raid_io(raid_io); 1745da1742bSKrzysztof Smolinski } 1755da1742bSKrzysztof Smolinski 1765da1742bSKrzysztof Smolinski static void 1775da1742bSKrzysztof Smolinski run_for_each_raid1_config(void (*test_fn)(struct raid_bdev *raid_bdev, 1785da1742bSKrzysztof Smolinski struct raid_bdev_io_channel *raid_ch)) 1795da1742bSKrzysztof Smolinski { 1805da1742bSKrzysztof Smolinski struct raid_params *params; 1815da1742bSKrzysztof Smolinski 1825da1742bSKrzysztof Smolinski RAID_PARAMS_FOR_EACH(params) { 1835da1742bSKrzysztof Smolinski struct raid1_info *r1_info; 18459d79ec5SArtur Paszkiewicz struct raid_bdev_io_channel *raid_ch; 1855da1742bSKrzysztof Smolinski 1865da1742bSKrzysztof Smolinski r1_info = create_raid1(params); 18759d79ec5SArtur Paszkiewicz raid_ch = raid_test_create_io_channel(r1_info->raid_bdev); 1885da1742bSKrzysztof Smolinski 18959d79ec5SArtur Paszkiewicz test_fn(r1_info->raid_bdev, raid_ch); 1905da1742bSKrzysztof Smolinski 19159d79ec5SArtur Paszkiewicz raid_test_destroy_io_channel(raid_ch); 1925da1742bSKrzysztof Smolinski delete_raid1(r1_info); 1935da1742bSKrzysztof Smolinski } 1945da1742bSKrzysztof Smolinski } 1955da1742bSKrzysztof Smolinski 1965da1742bSKrzysztof Smolinski static void 1975da1742bSKrzysztof Smolinski _test_raid1_read_balancing(struct raid_bdev *raid_bdev, struct raid_bdev_io_channel *raid_ch) 1985da1742bSKrzysztof Smolinski { 1995da1742bSKrzysztof Smolinski struct raid1_info *r1_info = raid_bdev->module_private; 2006e03e49bSArtur Paszkiewicz struct raid1_io_channel *raid1_ch = raid_bdev_channel_get_module_ctx(raid_ch); 2015da1742bSKrzysztof Smolinski uint8_t big_io_base_bdev_idx; 2025da1742bSKrzysztof Smolinski const uint64_t big_io_blocks = 256; 2035da1742bSKrzysztof Smolinski const uint64_t small_io_blocks = 4; 2045da1742bSKrzysztof Smolinski uint64_t blocks_remaining; 2055da1742bSKrzysztof Smolinski struct raid_bdev_io *raid_io; 2065da1742bSKrzysztof Smolinski uint8_t i; 2075da1742bSKrzysztof Smolinski int n; 2085da1742bSKrzysztof Smolinski 2095da1742bSKrzysztof Smolinski /* same sized IOs should be be spread evenly across all base bdevs */ 2105da1742bSKrzysztof Smolinski for (n = 0; n < 3; n++) { 2115da1742bSKrzysztof Smolinski for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 2125da1742bSKrzysztof Smolinski raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, small_io_blocks); 2135da1742bSKrzysztof Smolinski raid1_submit_read_request(raid_io); 2145da1742bSKrzysztof Smolinski CU_ASSERT(raid_io->base_bdev_io_submitted == i); 2155da1742bSKrzysztof Smolinski put_raid_io(raid_io); 2165da1742bSKrzysztof Smolinski } 2175da1742bSKrzysztof Smolinski } 2185da1742bSKrzysztof Smolinski 2195da1742bSKrzysztof Smolinski for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 2205da1742bSKrzysztof Smolinski CU_ASSERT(raid1_ch->read_blocks_outstanding[i] == n * small_io_blocks); 2215da1742bSKrzysztof Smolinski raid1_ch->read_blocks_outstanding[i] = 0; 2225da1742bSKrzysztof Smolinski } 2235da1742bSKrzysztof Smolinski 2245da1742bSKrzysztof Smolinski /* 2255da1742bSKrzysztof Smolinski * Submit one big and many small IOs. The small IOs should not land on the same base bdev 2265da1742bSKrzysztof Smolinski * as the big until the submitted block count is matched. 2275da1742bSKrzysztof Smolinski */ 2285da1742bSKrzysztof Smolinski raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, big_io_blocks); 2295da1742bSKrzysztof Smolinski raid1_submit_read_request(raid_io); 2305da1742bSKrzysztof Smolinski big_io_base_bdev_idx = raid_io->base_bdev_io_submitted; 2315da1742bSKrzysztof Smolinski put_raid_io(raid_io); 2325da1742bSKrzysztof Smolinski 2335da1742bSKrzysztof Smolinski blocks_remaining = big_io_blocks * (raid_bdev->num_base_bdevs - 1); 2345da1742bSKrzysztof Smolinski while (blocks_remaining > 0) { 2355da1742bSKrzysztof Smolinski raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, small_io_blocks); 2365da1742bSKrzysztof Smolinski raid1_submit_read_request(raid_io); 2375da1742bSKrzysztof Smolinski CU_ASSERT(raid_io->base_bdev_io_submitted != big_io_base_bdev_idx); 2385da1742bSKrzysztof Smolinski put_raid_io(raid_io); 2395da1742bSKrzysztof Smolinski blocks_remaining -= small_io_blocks; 2405da1742bSKrzysztof Smolinski } 2415da1742bSKrzysztof Smolinski 2425da1742bSKrzysztof Smolinski for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 2435da1742bSKrzysztof Smolinski CU_ASSERT(raid1_ch->read_blocks_outstanding[i] == big_io_blocks); 2445da1742bSKrzysztof Smolinski } 2455da1742bSKrzysztof Smolinski 2465da1742bSKrzysztof Smolinski raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, small_io_blocks); 2475da1742bSKrzysztof Smolinski raid1_submit_read_request(raid_io); 2485da1742bSKrzysztof Smolinski CU_ASSERT(raid_io->base_bdev_io_submitted == big_io_base_bdev_idx); 2495da1742bSKrzysztof Smolinski put_raid_io(raid_io); 2505da1742bSKrzysztof Smolinski } 2515da1742bSKrzysztof Smolinski 2525da1742bSKrzysztof Smolinski static void 2535da1742bSKrzysztof Smolinski test_raid1_read_balancing(void) 2545da1742bSKrzysztof Smolinski { 2555da1742bSKrzysztof Smolinski run_for_each_raid1_config(_test_raid1_read_balancing); 2565da1742bSKrzysztof Smolinski } 2575da1742bSKrzysztof Smolinski 258b0b0889eSArtur Paszkiewicz static void 259b0b0889eSArtur Paszkiewicz _test_raid1_write_error(struct raid_bdev *raid_bdev, struct raid_bdev_io_channel *raid_ch) 260b0b0889eSArtur Paszkiewicz { 261b0b0889eSArtur Paszkiewicz struct raid1_info *r1_info = raid_bdev->module_private; 262b0b0889eSArtur Paszkiewicz struct raid_bdev_io *raid_io; 263b0b0889eSArtur Paszkiewicz struct raid_base_bdev_info *base_info; 264b0b0889eSArtur Paszkiewicz struct spdk_bdev_io bdev_io = {}; 265b0b0889eSArtur Paszkiewicz bool bdev_io_success; 266b0b0889eSArtur Paszkiewicz 267b0b0889eSArtur Paszkiewicz /* first completion failed */ 268b0b0889eSArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 269b0b0889eSArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_WRITE, 64); 270b0b0889eSArtur Paszkiewicz raid1_submit_write_request(raid_io); 271b0b0889eSArtur Paszkiewicz 272b0b0889eSArtur Paszkiewicz RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 273b0b0889eSArtur Paszkiewicz base_info->is_failed = false; 274b0b0889eSArtur Paszkiewicz if (raid_bdev_base_bdev_slot(base_info) == 0) { 275b0b0889eSArtur Paszkiewicz bdev_io_success = false; 276b0b0889eSArtur Paszkiewicz } else { 277b0b0889eSArtur Paszkiewicz bdev_io_success = true; 278b0b0889eSArtur Paszkiewicz } 279b0b0889eSArtur Paszkiewicz bdev_io.bdev = base_info->desc->bdev; 280b0b0889eSArtur Paszkiewicz raid1_write_bdev_io_completion(&bdev_io, bdev_io_success, raid_io); 281b0b0889eSArtur Paszkiewicz CU_ASSERT(base_info->is_failed == !bdev_io_success); 282b0b0889eSArtur Paszkiewicz } 283b0b0889eSArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 284b0b0889eSArtur Paszkiewicz 285b0b0889eSArtur Paszkiewicz /* all except first completion failed */ 286b0b0889eSArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 287b0b0889eSArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_WRITE, 64); 288b0b0889eSArtur Paszkiewicz raid1_submit_write_request(raid_io); 289b0b0889eSArtur Paszkiewicz 290b0b0889eSArtur Paszkiewicz RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 291b0b0889eSArtur Paszkiewicz base_info->is_failed = false; 292b0b0889eSArtur Paszkiewicz if (raid_bdev_base_bdev_slot(base_info) != 0) { 293b0b0889eSArtur Paszkiewicz bdev_io_success = false; 294b0b0889eSArtur Paszkiewicz } else { 295b0b0889eSArtur Paszkiewicz bdev_io_success = true; 296b0b0889eSArtur Paszkiewicz } 297b0b0889eSArtur Paszkiewicz bdev_io.bdev = base_info->desc->bdev; 298b0b0889eSArtur Paszkiewicz raid1_write_bdev_io_completion(&bdev_io, bdev_io_success, raid_io); 299b0b0889eSArtur Paszkiewicz CU_ASSERT(base_info->is_failed == !bdev_io_success); 300b0b0889eSArtur Paszkiewicz } 301b0b0889eSArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 302b0b0889eSArtur Paszkiewicz 303b0b0889eSArtur Paszkiewicz /* all completions failed */ 304b0b0889eSArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 305b0b0889eSArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_WRITE, 64); 306b0b0889eSArtur Paszkiewicz raid1_submit_write_request(raid_io); 307b0b0889eSArtur Paszkiewicz 308b0b0889eSArtur Paszkiewicz bdev_io_success = false; 309b0b0889eSArtur Paszkiewicz RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 310b0b0889eSArtur Paszkiewicz base_info->is_failed = false; 311b0b0889eSArtur Paszkiewicz bdev_io.bdev = base_info->desc->bdev; 312b0b0889eSArtur Paszkiewicz raid1_write_bdev_io_completion(&bdev_io, bdev_io_success, raid_io); 313b0b0889eSArtur Paszkiewicz CU_ASSERT(base_info->is_failed == !bdev_io_success); 314b0b0889eSArtur Paszkiewicz } 315b0b0889eSArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 316b0b0889eSArtur Paszkiewicz } 317b0b0889eSArtur Paszkiewicz 318b0b0889eSArtur Paszkiewicz static void 319b0b0889eSArtur Paszkiewicz test_raid1_write_error(void) 320b0b0889eSArtur Paszkiewicz { 321b0b0889eSArtur Paszkiewicz run_for_each_raid1_config(_test_raid1_write_error); 322b0b0889eSArtur Paszkiewicz } 323b0b0889eSArtur Paszkiewicz 324cc94f303SArtur Paszkiewicz static void 325cc94f303SArtur Paszkiewicz _test_raid1_read_error(struct raid_bdev *raid_bdev, struct raid_bdev_io_channel *raid_ch) 326cc94f303SArtur Paszkiewicz { 327cc94f303SArtur Paszkiewicz struct raid1_info *r1_info = raid_bdev->module_private; 328cc94f303SArtur Paszkiewicz struct raid_base_bdev_info *base_info = &raid_bdev->base_bdev_info[0]; 329cc94f303SArtur Paszkiewicz struct raid1_io_channel *raid1_ch = raid_bdev_channel_get_module_ctx(raid_ch); 330cc94f303SArtur Paszkiewicz struct raid_bdev_io *raid_io; 331cc94f303SArtur Paszkiewicz struct spdk_bdev_io bdev_io = {}; 332cc94f303SArtur Paszkiewicz 333cc94f303SArtur Paszkiewicz /* first read fails, the second succeeds */ 334cc94f303SArtur Paszkiewicz base_info->is_failed = false; 335cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 336cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 337cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 338cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 0); 339cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 340cc94f303SArtur Paszkiewicz 341cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 342cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 343cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 344cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 345cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == (raid_bdev->num_base_bdevs - 1)); 346cc94f303SArtur Paszkiewicz 347cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[1].desc); 348cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 349cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, true, raid_io); 350cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 351cc94f303SArtur Paszkiewicz 352cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 353cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_correct_read_error_completion); 354cc94f303SArtur Paszkiewicz raid1_correct_read_error_completion(&bdev_io, true, raid_io); 355cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 356cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == false); 357cc94f303SArtur Paszkiewicz 358cc94f303SArtur Paszkiewicz /* rewrite fails */ 359cc94f303SArtur Paszkiewicz base_info->is_failed = false; 360cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 361cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 362cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 363cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 0); 364cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 365cc94f303SArtur Paszkiewicz 366cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 367cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 368cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 369cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 370cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == (raid_bdev->num_base_bdevs - 1)); 371cc94f303SArtur Paszkiewicz 372cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[1].desc); 373cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 374cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, true, raid_io); 375cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 376cc94f303SArtur Paszkiewicz 377cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 378cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_correct_read_error_completion); 379cc94f303SArtur Paszkiewicz raid1_correct_read_error_completion(&bdev_io, false, raid_io); 380cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 381cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == true); 382cc94f303SArtur Paszkiewicz 383cc94f303SArtur Paszkiewicz /* only the last read succeeds */ 384cc94f303SArtur Paszkiewicz base_info->is_failed = false; 385cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 386cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 387cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 388cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 0); 389cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 390cc94f303SArtur Paszkiewicz 391cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 392cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 393cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 394cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 395cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == (raid_bdev->num_base_bdevs - 1)); 396cc94f303SArtur Paszkiewicz 397cc94f303SArtur Paszkiewicz while (raid_io->base_bdev_io_remaining > 1) { 398cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 399cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, false, raid_io); 400cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 401cc94f303SArtur Paszkiewicz } 402cc94f303SArtur Paszkiewicz 403cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[raid_bdev->num_base_bdevs - 1].desc); 404cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 405cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, true, raid_io); 406cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 407cc94f303SArtur Paszkiewicz 408cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 409cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_correct_read_error_completion); 410cc94f303SArtur Paszkiewicz raid1_correct_read_error_completion(&bdev_io, true, raid_io); 411cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 412cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == false); 413cc94f303SArtur Paszkiewicz 414cc94f303SArtur Paszkiewicz /* all reads fail */ 415cc94f303SArtur Paszkiewicz base_info->is_failed = false; 416cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 417cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 418cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 419cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 0); 420cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 421cc94f303SArtur Paszkiewicz 422cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 423cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 424cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 425cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 426cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == (raid_bdev->num_base_bdevs - 1)); 427cc94f303SArtur Paszkiewicz 428cc94f303SArtur Paszkiewicz while (raid_io->base_bdev_io_remaining > 1) { 429cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 430cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, false, raid_io); 431cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 432cc94f303SArtur Paszkiewicz } 433cc94f303SArtur Paszkiewicz 434cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[raid_bdev->num_base_bdevs - 1].desc); 435cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 436cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, false, raid_io); 437cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 438cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == true); 439cc94f303SArtur Paszkiewicz 440cc94f303SArtur Paszkiewicz /* read from base bdev #1 fails, read from #0 succeeds */ 441cc94f303SArtur Paszkiewicz base_info->is_failed = false; 442cc94f303SArtur Paszkiewicz base_info = &raid_bdev->base_bdev_info[1]; 443cc94f303SArtur Paszkiewicz raid1_ch->read_blocks_outstanding[0] = 123; 444cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 445cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 446cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 447cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 1); 448cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 449cc94f303SArtur Paszkiewicz 450cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 451cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 452cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 453cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 454cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == raid_bdev->num_base_bdevs); 455cc94f303SArtur Paszkiewicz 456cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[0].desc); 457cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 458cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, true, raid_io); 459cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 460cc94f303SArtur Paszkiewicz 461cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 462cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_correct_read_error_completion); 463cc94f303SArtur Paszkiewicz raid1_correct_read_error_completion(&bdev_io, true, raid_io); 464cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 465cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == false); 466cc94f303SArtur Paszkiewicz 467cc94f303SArtur Paszkiewicz /* base bdev #0 is failed, read from #1 fails, read from next succeeds if N > 2 */ 468cc94f303SArtur Paszkiewicz base_info->is_failed = false; 469cc94f303SArtur Paszkiewicz raid_ch->_base_channels[0] = NULL; 470cc94f303SArtur Paszkiewicz g_io_status = SPDK_BDEV_IO_STATUS_PENDING; 471cc94f303SArtur Paszkiewicz raid_io = get_raid_io(r1_info, raid_ch, SPDK_BDEV_IO_TYPE_READ, 64); 472cc94f303SArtur Paszkiewicz raid1_submit_read_request(raid_io); 473cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_submitted == 1); 474cc94f303SArtur Paszkiewicz CU_ASSERT(raid_io->base_bdev_io_remaining == 0); 475cc94f303SArtur Paszkiewicz 476cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 477cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_bdev_io_completion); 478cc94f303SArtur Paszkiewicz raid1_read_bdev_io_completion(&bdev_io, false, raid_io); 479cc94f303SArtur Paszkiewicz if (raid_bdev->num_base_bdevs > 2) { 480cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 481cc94f303SArtur Paszkiewicz CU_ASSERT((uint8_t)raid_io->base_bdev_io_remaining == (raid_bdev->num_base_bdevs - 2)); 482cc94f303SArtur Paszkiewicz 483cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == raid_bdev->base_bdev_info[2].desc); 484cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_read_other_completion); 485cc94f303SArtur Paszkiewicz raid1_read_other_completion(&bdev_io, true, raid_io); 486cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_PENDING); 487cc94f303SArtur Paszkiewicz 488cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_desc == base_info->desc); 489cc94f303SArtur Paszkiewicz CU_ASSERT(g_last_io_cb == raid1_correct_read_error_completion); 490cc94f303SArtur Paszkiewicz raid1_correct_read_error_completion(&bdev_io, true, raid_io); 491cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 492cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == false); 493cc94f303SArtur Paszkiewicz } else { 494cc94f303SArtur Paszkiewicz CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 495cc94f303SArtur Paszkiewicz CU_ASSERT(base_info->is_failed == true); 496cc94f303SArtur Paszkiewicz } 497cc94f303SArtur Paszkiewicz } 498cc94f303SArtur Paszkiewicz 499cc94f303SArtur Paszkiewicz static void 500cc94f303SArtur Paszkiewicz test_raid1_read_error(void) 501cc94f303SArtur Paszkiewicz { 502cc94f303SArtur Paszkiewicz run_for_each_raid1_config(_test_raid1_read_error); 503cc94f303SArtur Paszkiewicz } 504cc94f303SArtur Paszkiewicz 50569038a94SKrzysztof Smolinski int 50669038a94SKrzysztof Smolinski main(int argc, char **argv) 50769038a94SKrzysztof Smolinski { 50869038a94SKrzysztof Smolinski CU_pSuite suite = NULL; 50969038a94SKrzysztof Smolinski unsigned int num_failures; 51069038a94SKrzysztof Smolinski 51169038a94SKrzysztof Smolinski CU_initialize_registry(); 51269038a94SKrzysztof Smolinski 51369038a94SKrzysztof Smolinski suite = CU_add_suite("raid1", test_setup, test_cleanup); 51469038a94SKrzysztof Smolinski CU_ADD_TEST(suite, test_raid1_start); 5155da1742bSKrzysztof Smolinski CU_ADD_TEST(suite, test_raid1_read_balancing); 516b0b0889eSArtur Paszkiewicz CU_ADD_TEST(suite, test_raid1_write_error); 517cc94f303SArtur Paszkiewicz CU_ADD_TEST(suite, test_raid1_read_error); 51869038a94SKrzysztof Smolinski 519a73acd9fSKrzysztof Smolinski allocate_threads(1); 520a73acd9fSKrzysztof Smolinski set_thread(0); 521a73acd9fSKrzysztof Smolinski 522ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 52369038a94SKrzysztof Smolinski CU_cleanup_registry(); 52459d79ec5SArtur Paszkiewicz 52559d79ec5SArtur Paszkiewicz free_threads(); 52659d79ec5SArtur Paszkiewicz 52769038a94SKrzysztof Smolinski return num_failures; 52869038a94SKrzysztof Smolinski } 529