bdev_nvme: Return memory domains of each controller

Signed-off-by: Alexey Marchuk <alexeymar@nvidia.com>
Change-Id: I7417dcf69bbb8a526308075459c5887283896823
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15087
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
Alexey Marchuk 2022-10-13 16:45:51 +02:00 committed by Tomasz Zawadzki
parent fa5e7d1b8d
commit 21db73f909
2 changed files with 95 additions and 15 deletions

View File

@ -2532,13 +2532,32 @@ _nvme_ana_state_str(enum spdk_nvme_ana_state ana_state)
static int
bdev_nvme_get_memory_domains(void *ctx, struct spdk_memory_domain **domains, int array_size)
{
struct spdk_memory_domain **_domains = NULL;
struct nvme_bdev *nbdev = ctx;
struct nvme_ns *nvme_ns;
int i = 0, _array_size = array_size;
int rc = 0;
nvme_ns = TAILQ_FIRST(&nbdev->nvme_ns_list);
assert(nvme_ns != NULL);
TAILQ_FOREACH(nvme_ns, &nbdev->nvme_ns_list, tailq) {
if (domains && array_size >= i) {
_domains = &domains[i];
} else {
_domains = NULL;
}
rc = spdk_nvme_ctrlr_get_memory_domains(nvme_ns->ctrlr->ctrlr, _domains, _array_size);
if (rc > 0) {
i += rc;
if (_array_size >= rc) {
_array_size -= rc;
} else {
_array_size = 0;
}
} else if (rc < 0) {
return rc;
}
}
return spdk_nvme_ctrlr_get_memory_domains(nvme_ns->ctrlr->ctrlr, domains, array_size);
return i;
}
static const char *

View File

@ -42,16 +42,23 @@ DEFINE_STUB(spdk_nvme_ctrlr_get_flags, uint64_t, (struct spdk_nvme_ctrlr *ctrlr)
DEFINE_STUB(accel_channel_create, int, (void *io_device, void *ctx_buf), 0);
DEFINE_STUB_V(accel_channel_destroy, (void *io_device, void *ctx_buf));
DEFINE_RETURN_MOCK(spdk_nvme_ctrlr_get_memory_domain, int);
DEFINE_STUB(spdk_nvme_ctrlr_get_discovery_log_page, int,
(struct spdk_nvme_ctrlr *ctrlr, spdk_nvme_discovery_cb cb_fn, void *cb_arg), 0);
DEFINE_RETURN_MOCK(spdk_nvme_ctrlr_get_memory_domains, int);
int
spdk_nvme_ctrlr_get_memory_domains(const struct spdk_nvme_ctrlr *ctrlr,
struct spdk_memory_domain **domains, int array_size)
{
HANDLE_RETURN_MOCK(spdk_nvme_ctrlr_get_memory_domain);
int i, min_array_size;
if (ut_spdk_nvme_ctrlr_get_memory_domains > 0 && domains && array_size > 0) {
min_array_size = spdk_min(ut_spdk_nvme_ctrlr_get_memory_domains, array_size);
for (i = 0; i < min_array_size; i++) {
domains[i] = (struct spdk_memory_domain *)0xf1f2f3f4f5;
}
}
HANDLE_RETURN_MOCK(spdk_nvme_ctrlr_get_memory_domains);
return 0;
}
@ -3015,24 +3022,78 @@ fini_accel(void)
static void
test_get_memory_domains(void)
{
struct nvme_ctrlr ctrlr = { .ctrlr = (struct spdk_nvme_ctrlr *) 0xbaadbeef };
struct nvme_ns ns = { .ctrlr = &ctrlr };
struct nvme_ctrlr ctrlr_1 = { .ctrlr = (struct spdk_nvme_ctrlr *) 0xbaadbeef };
struct nvme_ctrlr ctrlr_2 = { .ctrlr = (struct spdk_nvme_ctrlr *) 0xbaaadbeeef };
struct nvme_ns ns_1 = { .ctrlr = &ctrlr_1 };
struct nvme_ns ns_2 = { .ctrlr = &ctrlr_2 };
struct nvme_bdev nbdev = { .nvme_ns_list = TAILQ_HEAD_INITIALIZER(nbdev.nvme_ns_list) };
struct spdk_memory_domain *domains[2] = {};
struct spdk_memory_domain *domains[4] = {};
int rc = 0;
TAILQ_INSERT_TAIL(&nbdev.nvme_ns_list, &ns, tailq);
TAILQ_INSERT_TAIL(&nbdev.nvme_ns_list, &ns_1, tailq);
/* nvme controller doesn't have memory domainы */
MOCK_SET(spdk_nvme_ctrlr_get_memory_domain, 0);
/* nvme controller doesn't have memory domains */
MOCK_SET(spdk_nvme_ctrlr_get_memory_domains, 0);
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 2);
CU_ASSERT(rc == 0)
CU_ASSERT(rc == 0);
CU_ASSERT(domains[0] == NULL);
CU_ASSERT(domains[1] == NULL);
/* nvme controller has a memory domain */
MOCK_SET(spdk_nvme_ctrlr_get_memory_domain, 1);
MOCK_SET(spdk_nvme_ctrlr_get_memory_domains, 1);
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 2);
CU_ASSERT(rc == 1);
MOCK_CLEAR(spdk_nvme_ctrlr_get_memory_domain);
CU_ASSERT(domains[0] != NULL);
memset(domains, 0, sizeof(domains));
/* multipath, 2 controllers report 1 memory domain each */
TAILQ_INSERT_TAIL(&nbdev.nvme_ns_list, &ns_2, tailq);
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 2);
CU_ASSERT(rc == 2);
CU_ASSERT(domains[0] != NULL);
CU_ASSERT(domains[1] != NULL);
memset(domains, 0, sizeof(domains));
/* multipath, 2 controllers report 1 memory domain each, NULL domains ptr */
rc = bdev_nvme_get_memory_domains(&nbdev, NULL, 2);
CU_ASSERT(rc == 2);
/* multipath, 2 controllers report 1 memory domain each, array_size = 0 */
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 0);
CU_ASSERT(rc == 2);
CU_ASSERT(domains[0] == NULL);
CU_ASSERT(domains[1] == NULL);
/* multipath, 2 controllers report 1 memory domain each, array_size = 1 */
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 1);
CU_ASSERT(rc == 2);
CU_ASSERT(domains[0] != NULL);
CU_ASSERT(domains[1] == NULL);
memset(domains, 0, sizeof(domains));
/* multipath, 2 controllers report 2 memory domain each (not possible, just for test) */
MOCK_SET(spdk_nvme_ctrlr_get_memory_domains, 2);
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 4);
CU_ASSERT(rc == 4);
CU_ASSERT(domains[0] != NULL);
CU_ASSERT(domains[1] != NULL);
CU_ASSERT(domains[2] != NULL);
CU_ASSERT(domains[3] != NULL);
memset(domains, 0, sizeof(domains));
/* multipath, 2 controllers report 2 memory domain each (not possible, just for test)
* Array size is less than the number of memory domains */
MOCK_SET(spdk_nvme_ctrlr_get_memory_domains, 2);
rc = bdev_nvme_get_memory_domains(&nbdev, domains, 3);
CU_ASSERT(rc == 4);
CU_ASSERT(domains[0] != NULL);
CU_ASSERT(domains[1] != NULL);
CU_ASSERT(domains[2] != NULL);
CU_ASSERT(domains[3] == NULL);
memset(domains, 0, sizeof(domains));
MOCK_CLEAR(spdk_nvme_ctrlr_get_memory_domains);
}
static void