Commit ccee9a91 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

bdev/nvme: find_io_path() excludes io_path whose ANA state is not accessible



bdev_nvme_find_io_path() selects an io_path whose qpair is connected
and ANA state is optimized or non-optimized.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I79c978795562b606ee27aa43020684d8bcbf50c5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9405


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 56e2d632
Loading
Loading
Loading
Loading
+43 −5
Original line number Diff line number Diff line
@@ -657,26 +657,64 @@ bdev_nvme_io_type_is_admin(enum spdk_bdev_io_type io_type)
}

static inline bool
nvme_io_path_is_available(struct nvme_io_path *io_path)
nvme_ns_is_accessible(struct nvme_ns *nvme_ns)
{
	switch (nvme_ns->ana_state) {
	case SPDK_NVME_ANA_OPTIMIZED_STATE:
	case SPDK_NVME_ANA_NON_OPTIMIZED_STATE:
		return true;
	default:
		break;
	}

	return false;
}

static inline bool
nvme_io_path_is_connected(struct nvme_io_path *io_path)
{
	return io_path->ctrlr_ch->qpair != NULL;
}

static inline bool
nvme_io_path_is_available(struct nvme_io_path *io_path)
{
	if (spdk_unlikely(!nvme_io_path_is_connected(io_path))) {
		return false;
	}

	if (spdk_unlikely(!nvme_ns_is_accessible(io_path->nvme_ns))) {
		return false;
	}

	return true;
}

static inline struct nvme_io_path *
bdev_nvme_find_io_path(struct nvme_bdev_channel *nbdev_ch)
{
	struct nvme_io_path *io_path;
	struct nvme_io_path *io_path, *non_optimized = NULL;

	STAILQ_FOREACH(io_path, &nbdev_ch->io_path_list, stailq) {
		if (spdk_unlikely(!nvme_io_path_is_available(io_path))) {
		if (spdk_unlikely(!nvme_io_path_is_connected(io_path))) {
			/* The device is currently resetting. */
			continue;
		}

		switch (io_path->nvme_ns->ana_state) {
		case SPDK_NVME_ANA_OPTIMIZED_STATE:
			return io_path;
		case SPDK_NVME_ANA_NON_OPTIMIZED_STATE:
			if (non_optimized == NULL) {
				non_optimized = io_path;
			}
			break;
		default:
			break;
		}
	}

	return NULL;
	return non_optimized;
}

static inline void
+53 −0
Original line number Diff line number Diff line
@@ -3747,6 +3747,58 @@ test_reset_bdev_ctrlr(void)
	free(second_bdev_io);
}

static void
test_find_io_path(void)
{
	struct nvme_bdev_channel nbdev_ch = {
		.io_path_list = STAILQ_HEAD_INITIALIZER(nbdev_ch.io_path_list),
	};
	struct nvme_ctrlr_channel ctrlr_ch1 = {}, ctrlr_ch2 = {};
	struct nvme_ns nvme_ns1 = {}, nvme_ns2 = {};
	struct nvme_io_path io_path1 = { .ctrlr_ch = &ctrlr_ch1, .nvme_ns = &nvme_ns1, };
	struct nvme_io_path io_path2 = { .ctrlr_ch = &ctrlr_ch2, .nvme_ns = &nvme_ns2, };

	STAILQ_INSERT_TAIL(&nbdev_ch.io_path_list, &io_path1, stailq);

	/* Test if io_path whose ANA state is not accessible is excluded. */

	ctrlr_ch1.qpair = (struct spdk_nvme_qpair *)0x1;
	nvme_ns1.ana_state = SPDK_NVME_ANA_INACCESSIBLE_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == NULL);

	nvme_ns1.ana_state = SPDK_NVME_ANA_PERSISTENT_LOSS_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == NULL);

	nvme_ns1.ana_state = SPDK_NVME_ANA_CHANGE_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == NULL);

	nvme_ns1.ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == &io_path1);

	nvme_ns1.ana_state = SPDK_NVME_ANA_NON_OPTIMIZED_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == &io_path1);

	/* Test if io_path whose qpair is resetting is excluced. */

	ctrlr_ch1.qpair = NULL;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == NULL);

	STAILQ_INSERT_TAIL(&nbdev_ch.io_path_list, &io_path2, stailq);

	/* Test if ANA optimized state or the first found ANA non-optimized state
	 * is prioritized.
	 */

	ctrlr_ch1.qpair = (struct spdk_nvme_qpair *)0x1;
	nvme_ns1.ana_state = SPDK_NVME_ANA_NON_OPTIMIZED_STATE;
	ctrlr_ch2.qpair = (struct spdk_nvme_qpair *)0x1;
	nvme_ns2.ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == &io_path2);

	nvme_ns2.ana_state = SPDK_NVME_ANA_NON_OPTIMIZED_STATE;
	CU_ASSERT(bdev_nvme_find_io_path(&nbdev_ch) == &io_path1);
}

int
main(int argc, const char **argv)
{
@@ -3779,6 +3831,7 @@ main(int argc, const char **argv)
	CU_ADD_TEST(suite, test_add_multi_io_paths_to_nbdev_ch);
	CU_ADD_TEST(suite, test_admin_path);
	CU_ADD_TEST(suite, test_reset_bdev_ctrlr);
	CU_ADD_TEST(suite, test_find_io_path);

	CU_basic_set_mode(CU_BRM_VERBOSE);