Repository navigation
UCS/SYS/TOPO: Allow multiple sibling devices per memory device #12126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
8e80252
7ad0252
13342ad
c165850
c48b959
49c469b
aa7b843
f3bbfd1
faef0d4
31862a2
e7a9875
548e94f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -510,18 +510,18 @@ ucs_topo_find_device_by_bus_id_value(const ucs_sys_bus_id_t *bus_id, | |||||||||||||||||||||
| *sys_dev_p = ucs_topo_global_ctx.num_devices++; | ||||||||||||||||||||||
| device = &ucs_topo_global_ctx.devices[*sys_dev_p]; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| device->bus_id = *bus_id; | ||||||||||||||||||||||
| device->name = name; | ||||||||||||||||||||||
| device->name_priority = 0; | ||||||||||||||||||||||
| device->numa_node = numa_node; | ||||||||||||||||||||||
| device->pci_id = pci_id; | ||||||||||||||||||||||
| device->user_value = user_value; | ||||||||||||||||||||||
| device->device_class = UCS_TOPO_DEVICE_CLASS_UNKNOWN; | ||||||||||||||||||||||
| device->flags = 0; | ||||||||||||||||||||||
| device->class_ordinal = UCS_SYS_DEVICE_ORDINAL_INVALID; | ||||||||||||||||||||||
| device->sibling_role = UCS_TOPO_SIBLING_ROLE_NONE; | ||||||||||||||||||||||
| device->sibling_sys_dev = UCS_SYS_DEVICE_ID_UNKNOWN; | ||||||||||||||||||||||
| device->sys_dev_aux = UCS_SYS_DEVICE_ID_UNKNOWN; | ||||||||||||||||||||||
| device->bus_id = *bus_id; | ||||||||||||||||||||||
| device->name = name; | ||||||||||||||||||||||
| device->name_priority = 0; | ||||||||||||||||||||||
| device->numa_node = numa_node; | ||||||||||||||||||||||
| device->pci_id = pci_id; | ||||||||||||||||||||||
| device->user_value = user_value; | ||||||||||||||||||||||
| device->device_class = UCS_TOPO_DEVICE_CLASS_UNKNOWN; | ||||||||||||||||||||||
| device->flags = 0; | ||||||||||||||||||||||
| device->class_ordinal = UCS_SYS_DEVICE_ORDINAL_INVALID; | ||||||||||||||||||||||
| device->sibling_role = UCS_TOPO_SIBLING_ROLE_NONE; | ||||||||||||||||||||||
| device->sys_dev_aux = UCS_SYS_DEVICE_ID_UNKNOWN; | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_RESET_ALL(&device->siblings); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (user_value == UCS_SYS_DEVICE_USER_VALUE_EMPTY) { | ||||||||||||||||||||||
| ucs_debug( | ||||||||||||||||||||||
|
|
@@ -803,22 +803,23 @@ ucs_topo_is_reachable(ucs_sys_device_t sys_dev, ucs_sys_device_t sys_dev_mem) | |||||||||||||||||||||
| result = | ||||||||||||||||||||||
| (sys_dev >= ucs_topo_global_ctx.num_devices) || | ||||||||||||||||||||||
| (sys_dev_mem >= ucs_topo_global_ctx.num_devices) || | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * Memory device was never matched with a sibling, it does not | ||||||||||||||||||||||
| * mandate an auxiliary path. | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev_mem].sibling_sys_dev == | ||||||||||||||||||||||
| UCS_SYS_DEVICE_ID_UNKNOWN) || | ||||||||||||||||||||||
| /* The device itself never uses auxiliary path */ | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev].sibling_role != | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_DEV) || | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * MPS MLOParts create multiple MEM aliases for one DEV. Each MEM | ||||||||||||||||||||||
| * alias records its matched DEV; the DEV stores only one | ||||||||||||||||||||||
| * representative MEM sibling. | ||||||||||||||||||||||
| * MPS MLOParts create multiple MEM aliases for one DEV, and | ||||||||||||||||||||||
| * multiplane NICs create multiple DEVs for one MEM. Each MEM | ||||||||||||||||||||||
| * records all of its matched DEVs. | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_GET( | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev_mem].siblings, | ||||||||||||||||||||||
| sys_dev) || | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * Memory device was never matched with a sibling, it does not | ||||||||||||||||||||||
| * mandate an auxiliary path. | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev_mem].sibling_sys_dev == | ||||||||||||||||||||||
| sys_dev); | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_IS_ZERO( | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev_mem].siblings); | ||||||||||||||||||||||
| ucs_spin_unlock(&ucs_topo_global_ctx.lock); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return result; | ||||||||||||||||||||||
|
|
@@ -836,11 +837,12 @@ int ucs_topo_is_sibling(ucs_sys_device_t sys_dev, ucs_sys_device_t sys_dev_mem) | |||||||||||||||||||||
| (sys_dev_mem != UCS_SYS_DEVICE_ID_UNKNOWN) && | ||||||||||||||||||||||
| (sys_dev_mem < ucs_topo_global_ctx.num_devices) && | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * MLOPart allows multiple MEM devices to point at one DEV, so | ||||||||||||||||||||||
| * the MEM-side sibling is the canonical relationship. | ||||||||||||||||||||||
| * The MEM side holds every matched DEV, including all planes | ||||||||||||||||||||||
| * of a multiplane NIC. | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The bitmap is symmetric, so swapped arguments also return true and trip the assert. Please gate on the role, like
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev_mem].sibling_sys_dev == | ||||||||||||||||||||||
| sys_dev); | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_GET( | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the siblings bitmap is symmetric now, so is_sibling(mem, dev) also returns true and then trips the assert below (and silently returns 1 in release builds). pls make the role part of the condition instead of only asserting it: Swapped calls do exist in the tree ( |
||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev_mem].siblings, | ||||||||||||||||||||||
| sys_dev); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (is_sibling) { | ||||||||||||||||||||||
| role_dev = ucs_topo_global_ctx.devices[sys_dev].sibling_role; | ||||||||||||||||||||||
|
|
@@ -1372,28 +1374,40 @@ ucs_topo_is_pci_bridge(ucs_sys_device_t sys_dev1, ucs_sys_device_t sys_dev2) | |||||||||||||||||||||
| return result; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static int ucs_topo_sys_device_sibling_match(ucs_sys_device_t sys_dev, | ||||||||||||||||||||||
| ucs_sys_device_t sys_dev_mem) | ||||||||||||||||||||||
| static void ucs_topo_sys_device_sibling_match(ucs_sys_device_t sys_dev, | ||||||||||||||||||||||
| ucs_sys_device_t sys_dev_mem) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| ucs_sys_device_t sys_dev_aux; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if ((ucs_topo_global_ctx.devices[sys_dev_mem].sibling_role != | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_MEM) || | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev].sibling_role != | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_DEV)) { | ||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||
| return; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| sys_dev_aux = ucs_topo_global_ctx.devices[sys_dev].sys_dev_aux; | ||||||||||||||||||||||
| if (ucs_topo_is_pci_bridge(sys_dev_mem, sys_dev_aux)) { | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev_mem].sibling_sys_dev = sys_dev; | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev].sibling_sys_dev = sys_dev_mem; | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_SET( | ||||||||||||||||||||||
| &ucs_topo_global_ctx.devices[sys_dev_mem].siblings, sys_dev); | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_SET(&ucs_topo_global_ctx.devices[sys_dev].siblings, | ||||||||||||||||||||||
| sys_dev_mem); | ||||||||||||||||||||||
| ucs_trace("sys_dev=%u with sys_dev_aux=%u matched with sys_dev_mem=%u", | ||||||||||||||||||||||
| sys_dev, sys_dev_aux, sys_dev_mem); | ||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static void ucs_topo_sys_device_clear_siblings(ucs_sys_device_t sys_dev) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| ucs_topo_sys_device_info_t *device = &ucs_topo_global_ctx.devices[sys_dev]; | ||||||||||||||||||||||
| unsigned peer; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| UCS_STATIC_BITMAP_FOR_EACH_BIT(peer, &device->siblings) { | ||||||||||||||||||||||
|
tomerg-nvidia marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
| UCS_STATIC_BITMAP_RESET(&ucs_topo_global_ctx.devices[peer].siblings, | ||||||||||||||||||||||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
| sys_dev); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||
| UCS_STATIC_BITMAP_RESET_ALL(&device->siblings); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* Memory device supports auxiliary path if a sibling is found */ | ||||||||||||||||||||||
|
|
@@ -1410,13 +1424,19 @@ ucs_status_t ucs_topo_sys_device_enable_aux_path(ucs_sys_device_t sys_dev) | |||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (ucs_topo_global_ctx.devices[sys_dev].sibling_role == | ||||||||||||||||||||||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_MEM) { | ||||||||||||||||||||||
| status = UCS_OK; | ||||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ucs_topo_sys_device_clear_siblings(sys_dev); | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev].sibling_role = | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_MEM; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* All devices sharing the auxiliary device match the memory device */ | ||||||||||||||||||||||
| for (dev = 0; dev < ucs_topo_global_ctx.num_devices; dev++) { | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor: is_pci_bridge() does 2 realpath() + 3 PATH_MAX allocations per candidate under the global spinlock, so now every memory device pays it for all DEVs. With MPS aliases this becomes |
||||||||||||||||||||||
| if (ucs_topo_sys_device_sibling_match(dev, sys_dev)) { | ||||||||||||||||||||||
| break; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ucs_topo_sys_device_sibling_match(dev, sys_dev); | ||||||||||||||||||||||
|
tomerg-nvidia marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| status = UCS_OK; | ||||||||||||||||||||||
|
|
@@ -1440,6 +1460,14 @@ ucs_status_t ucs_topo_sys_device_set_sys_dev_aux(ucs_sys_device_t sys_dev, | |||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if ((ucs_topo_global_ctx.devices[sys_dev].sibling_role == | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_DEV) && | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev].sys_dev_aux == sys_dev_aux)) { | ||||||||||||||||||||||
| status = UCS_OK; | ||||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ucs_topo_sys_device_clear_siblings(sys_dev); | ||||||||||||||||||||||
|
tomerg-nvidia marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev].sys_dev_aux = sys_dev_aux; | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev].sibling_role = | ||||||||||||||||||||||
| UCS_TOPO_SIBLING_ROLE_DEV; | ||||||||||||||||||||||
|
|
@@ -1462,8 +1490,8 @@ int ucs_topo_device_has_sibling(ucs_sys_device_t sys_dev) | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| ucs_spin_lock(&ucs_topo_global_ctx.lock); | ||||||||||||||||||||||
| result = (sys_dev < ucs_topo_global_ctx.num_devices) && | ||||||||||||||||||||||
| (ucs_topo_global_ctx.devices[sys_dev].sibling_sys_dev != | ||||||||||||||||||||||
| UCS_SYS_DEVICE_ID_UNKNOWN); | ||||||||||||||||||||||
| !UCS_STATIC_BITMAP_IS_ZERO( | ||||||||||||||||||||||
| ucs_topo_global_ctx.devices[sys_dev].siblings); | ||||||||||||||||||||||
| ucs_spin_unlock(&ucs_topo_global_ctx.lock); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return result; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1001,3 +1001,163 @@ UCS_TEST_F(test_topo, sibling_multiple_memory_devices) { | |
| expect_sibling(gpu_dev1); | ||
| expect_sibling(gpu_dev2); | ||
| } | ||
|
|
||
| // Multiple network devices sharing a single auxiliary device, with multiple | ||
| // memory devices behind it. | ||
| class test_topo_multi_dev_sibling : public test_topo { | ||
| protected: | ||
| static constexpr int num_planes = 3; | ||
| static constexpr int num_mems = 2; | ||
|
|
||
| // Test both registration orders: memory devices first (matched by | ||
| // set_sys_dev_aux), or network devices first (matched by enable_aux_path) | ||
| void run_test(bool mem_first) | ||
| { | ||
| read_pcie_devices(); | ||
| if ((m_hcas.size() < (num_planes + 1)) || m_gpus.empty() || | ||
| m_dmas.empty()) { | ||
| UCS_TEST_SKIP_R("Not enough HCA, GPU and DMA PCIe device"); | ||
| } | ||
|
|
||
| std::string sibling_gpu, sibling_dma; | ||
| get_siblings(m_hcas[0], sibling_gpu, sibling_dma); | ||
| if (sibling_dma.empty()) { | ||
| UCS_TEST_SKIP_R("No sibling DMA device found"); | ||
| } | ||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||
|
|
||
| // Memory devices: the same GPU BDF with distinct user values | ||
| std::vector<ucs_sys_device_t> mems; | ||
| auto gpu_dev = register_device("gpu0", sibling_gpu); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, gpu_dev); | ||
| mems.push_back(gpu_dev); | ||
|
|
||
| ucs_sys_bus_id_t gpu_bus_id; | ||
| ASSERT_UCS_OK(ucs_topo_get_device_bus_id(gpu_dev, &gpu_bus_id)); | ||
| for (int i = 1; i < num_mems; ++i) { | ||
| ucs_sys_device_t mem_alias; | ||
| ASSERT_UCS_OK(ucs_topo_find_device_by_bus_id_and_user_value( | ||
| &gpu_bus_id, i, &mem_alias)); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, mem_alias); | ||
| mems.push_back(mem_alias); | ||
| } | ||
|
tvegas1 marked this conversation as resolved.
Resolved
|
||
|
|
||
| auto dma_dev = register_device("dma", sibling_dma); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, dma_dev); | ||
|
|
||
| if (mem_first) { | ||
| for (auto mem : mems) { | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_enable_aux_path(mem)); | ||
| } | ||
| } | ||
|
|
||
| // All planes report the same auxiliary device | ||
| std::vector<ucs_sys_device_t> planes; | ||
| for (int i = 0; i < num_planes; ++i) { | ||
| auto plane = register_device("plane" + std::to_string(i), | ||
| m_hcas[i]); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, plane); | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(plane, dma_dev)); | ||
| planes.push_back(plane); | ||
| } | ||
|
|
||
| // A device whose auxiliary device is not behind the GPU's bridge | ||
| auto other = register_device("other", m_hcas[num_planes]); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, other); | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(other, other)); | ||
|
|
||
| if (!mem_first) { | ||
| for (auto mem : mems) { | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_enable_aux_path(mem)); | ||
| } | ||
| } | ||
|
|
||
| // Every memory device is matched with every plane, and vice versa | ||
| for (auto mem : mems) { | ||
| EXPECT_TRUE(ucs_topo_device_has_sibling(mem)); | ||
| for (auto plane : planes) { | ||
| EXPECT_TRUE(ucs_topo_is_sibling(plane, mem)); | ||
| EXPECT_TRUE(ucs_topo_is_reachable(plane, mem)); | ||
| } | ||
| } | ||
|
|
||
| for (auto plane : planes) { | ||
| EXPECT_TRUE(ucs_topo_device_has_sibling(plane)); | ||
| } | ||
|
|
||
| // Skip if the other HCA happens to be behind the GPU's bridge as well | ||
| if (ucs_topo_is_sibling(other, mems[0])) { | ||
| UCS_TEST_SKIP_R("Other HCA is behind the GPU bridge"); | ||
| } | ||
|
|
||
| EXPECT_FALSE(ucs_topo_device_has_sibling(other)); | ||
| for (auto mem : mems) { | ||
| EXPECT_FALSE(ucs_topo_is_sibling(other, mem)); | ||
| EXPECT_FALSE(ucs_topo_is_reachable(other, mem)); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| UCS_TEST_F(test_topo_multi_dev_sibling, mem_first) | ||
| { | ||
| run_test(true); | ||
| } | ||
|
|
||
| UCS_TEST_F(test_topo_multi_dev_sibling, devs_first) | ||
| { | ||
| run_test(false); | ||
| } | ||
|
|
||
| // A pairing must not outlive the role or the auxiliary device it was made for | ||
| UCS_TEST_F(test_topo_multi_dev_sibling, stale_siblings) | ||
| { | ||
| read_pcie_devices(); | ||
| if ((m_hcas.size() < 2) || m_gpus.empty() || m_dmas.empty()) { | ||
| UCS_TEST_SKIP_R("Not enough HCA, GPU and DMA PCIe device"); | ||
| } | ||
|
|
||
| std::string sibling_gpu, sibling_dma; | ||
| get_siblings(m_hcas[0], sibling_gpu, sibling_dma); | ||
| if (sibling_dma.empty()) { | ||
| UCS_TEST_SKIP_R("No sibling DMA device found"); | ||
| } | ||
|
|
||
| auto gpu_dev = register_device("gpu0", sibling_gpu); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, gpu_dev); | ||
| auto dma_dev = register_device("dma", sibling_dma); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, dma_dev); | ||
| auto plane = register_device("plane", m_hcas[0]); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, plane); | ||
|
|
||
| // An auxiliary device which is not behind the GPU's bridge. This depends | ||
| // on the PCIe topology of the machine. | ||
| auto other = register_device("other", m_hcas[1]); | ||
| ASSERT_NE(UCS_SYS_DEVICE_ID_UNKNOWN, other); | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_enable_aux_path(gpu_dev)); | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(other, other)); | ||
| if (ucs_topo_is_sibling(other, gpu_dev)) { | ||
| UCS_TEST_SKIP_R("Other HCA is behind the GPU bridge"); | ||
| } | ||
|
|
||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(plane, dma_dev)); | ||
| ASSERT_TRUE(ucs_topo_is_sibling(plane, gpu_dev)); | ||
|
|
||
| // Setting the same auxiliary device again keeps the pairing | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(plane, dma_dev)); | ||
| EXPECT_TRUE(ucs_topo_is_sibling(plane, gpu_dev)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we also call ucs_topo_sys_device_enable_aux_path(gpu_dev) twice here? The new MEM early-return in enable_aux_path() is not covered, while the set_sys_dev_aux() one is covered by this check. |
||
|
|
||
| // Role flip DEV -> MEM: the memory device forgets the former DEV | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_enable_aux_path(plane)); | ||
| EXPECT_FALSE(ucs_topo_is_sibling(plane, gpu_dev)); | ||
| EXPECT_FALSE(ucs_topo_device_has_sibling(gpu_dev)); | ||
|
|
||
| // Role flip MEM -> DEV pairs it again | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(plane, dma_dev)); | ||
| EXPECT_TRUE(ucs_topo_is_sibling(plane, gpu_dev)); | ||
| EXPECT_TRUE(ucs_topo_device_has_sibling(gpu_dev)); | ||
|
|
||
| // Moving the device to another auxiliary device drops the old pairing | ||
| ASSERT_UCS_OK(ucs_topo_sys_device_set_sys_dev_aux(plane, other)); | ||
| EXPECT_FALSE(ucs_topo_is_sibling(plane, gpu_dev)); | ||
| EXPECT_FALSE(ucs_topo_device_has_sibling(plane)); | ||
| EXPECT_FALSE(ucs_topo_device_has_sibling(gpu_dev)); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.