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 9 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,44 @@ 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
|
||||||||||||||||||||||
| if (peer >= ucs_topo_global_ctx.num_devices) { | ||||||||||||||||||||||
| break; | ||||||||||||||||||||||
|
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: bits are only set for indices |
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 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 +1428,20 @@ ucs_status_t ucs_topo_sys_device_enable_aux_path(ucs_sys_device_t sys_dev) | |||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* Already a memory device: keep the existing matches and skip the rescan */ | ||||||||||||||||||||||
| 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 +1465,15 @@ ucs_status_t ucs_topo_sys_device_set_sys_dev_aux(ucs_sys_device_t sys_dev, | |||||||||||||||||||||
| goto out; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* Same auxiliary device as before: skip the rescan */ | ||||||||||||||||||||||
| 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 +1496,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; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.