Skip to content

Commit aa26f29

Browse files
committed
linux/dax: add CXLDevice info attribute(s) in DAX and NUMA nodes
There can be multiple entries if the region is interleaved. Might be better to merge into a single info attr? We'll see. This uses "memregion" identifiers (regionX) to match dax devices and CXL devices. The corresponding Linux code (CXL volatile regions, etc) is planned for Linux 6.3. Refs #554 Signed-off-by: Brice Goglin <[email protected]>
1 parent 3caffb4 commit aa26f29

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

doc/hwloc.doxy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,11 @@ and GID #1 of port #3.
21272127
These info attributes are attached to objects specified in parentheses.
21282128

21292129
<dl>
2130+
<dt>CXLDevice (NUMA Nodes or DAX Memory OS devices)</dt>
2131+
<dd>The PCI/CXL bus ID of a device whose CXL Type-3 memory is exposed here.
2132+
There may be multiple instances of this attributes if multiple device memories
2133+
are interleaved.
2134+
</dd>
21302135
<dt>DAXDevice (NUMA Nodes)</dt>
21312136
<dd>The name of the Linux DAX device that was used to expose a non-volatile
21322137
memory region as a volatile NUMA node.

hwloc/topology-linux.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3690,6 +3690,69 @@ read_node_mscaches(struct hwloc_topology *topology,
36903690
return 0;
36913691
}
36923692

3693+
static int
3694+
annotate_cxl_dax(hwloc_obj_t obj, unsigned region, int root_fd)
3695+
{
3696+
char path[300];
3697+
unsigned i;
3698+
3699+
for(i=0; ; i++) {
3700+
char decoder[20]; /* "decoderX.Y" */
3701+
char decoderpath[256], *endpoint;
3702+
char uportpath[256], *pcirootbus, *pcibdf;
3703+
unsigned pcidomain, pcibus, pcidevice, pcifunc;
3704+
char *slash, *end;
3705+
int err;
3706+
3707+
/* read the i-th decoder name from file target<i> */
3708+
snprintf(path, sizeof(path), "/sys/bus/cxl/devices/region%u/target%u", region, i);
3709+
if (hwloc_read_path_by_length(path, decoder, sizeof(decoder), root_fd) < 0)
3710+
break;
3711+
end = strchr(decoder, '\n');
3712+
if (end)
3713+
*end = '\0';
3714+
hwloc_debug("hwloc/dax/cxl: found decoder `%s' for region#%u target#%u\n", decoder, region, i);
3715+
3716+
/* get the endpoint symlink which ends with "/portT/endpointX/decoderY.X/" */
3717+
snprintf(path, sizeof(path), "/sys/bus/cxl/devices/%s", decoder);
3718+
err = hwloc_readlink(path, decoderpath, sizeof(decoderpath), root_fd);
3719+
if (err < 0)
3720+
break;
3721+
endpoint = strstr(decoderpath, "endpoint");
3722+
if (!endpoint)
3723+
break;
3724+
slash = strchr(endpoint, '/');
3725+
if (!slash)
3726+
break;
3727+
*slash = '\0';
3728+
hwloc_debug("hwloc/dax/cxl: found endpoint `%s'\n", endpoint);
3729+
3730+
/* get the PCI in the endpointX/uport symlink "../../../pci<busid>/<BDFs>../memX" */
3731+
snprintf(path, sizeof(path), "/sys/bus/cxl/devices/%s/uport", endpoint);
3732+
err = hwloc_readlink(path, uportpath, sizeof(uportpath), root_fd);
3733+
if (err < 0)
3734+
break;
3735+
hwloc_debug("hwloc/dax/cxl: lookind for BDF at the end of uport `%s'\n", uportpath);
3736+
pcirootbus = strstr(uportpath, "/pci");
3737+
if (!pcirootbus)
3738+
break;
3739+
slash = pcirootbus + 11; /* "/pciXXXX:YY/" */
3740+
if (*slash != '/')
3741+
break;
3742+
pcibdf = NULL;
3743+
while (sscanf(slash, "/%x:%x:%x.%x/", &pcidomain, &pcibus, &pcidevice, &pcifunc) == 4) {
3744+
pcibdf = slash+1;
3745+
slash += 13;
3746+
}
3747+
*slash = '\0';
3748+
if (pcibdf) {
3749+
hwloc_obj_add_info(obj, "CXLDevice", pcibdf);
3750+
}
3751+
}
3752+
3753+
return 0;
3754+
}
3755+
36933756
static int
36943757
dax_is_kmem(const char *name, int fsroot_fd)
36953758
{
@@ -3705,7 +3768,7 @@ annotate_dax_parent(hwloc_obj_t obj, const char *name, int fsroot_fd)
37053768
{
37063769
char daxpath[300];
37073770
char link[PATH_MAX];
3708-
char *begin, *end;
3771+
char *begin, *end, *region;
37093772
const char *type;
37103773
int err;
37113774

@@ -3745,6 +3808,14 @@ annotate_dax_parent(hwloc_obj_t obj, const char *name, int fsroot_fd)
37453808
type = strstr(begin, "ndbus") ? "NVM" : "SPM";
37463809
hwloc_obj_add_info(obj, "DAXType", type);
37473810

3811+
/* try to get some CXL info from the region */
3812+
region = strstr(begin, "/region");
3813+
if (region) {
3814+
unsigned i = strtoul(region+7, &end, 10);
3815+
if (end != region+7)
3816+
annotate_cxl_dax(obj, i, fsroot_fd);
3817+
}
3818+
37483819
/* insert DAXParent last because it's likely less useful than others */
37493820
hwloc_obj_add_info(obj, "DAXParent", begin);
37503821

0 commit comments

Comments
 (0)