@@ -3690,6 +3690,69 @@ read_node_mscaches(struct hwloc_topology *topology,
3690
3690
return 0 ;
3691
3691
}
3692
3692
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
+
3693
3756
static int
3694
3757
dax_is_kmem (const char * name , int fsroot_fd )
3695
3758
{
@@ -3705,7 +3768,7 @@ annotate_dax_parent(hwloc_obj_t obj, const char *name, int fsroot_fd)
3705
3768
{
3706
3769
char daxpath [300 ];
3707
3770
char link [PATH_MAX ];
3708
- char * begin , * end ;
3771
+ char * begin , * end , * region ;
3709
3772
const char * type ;
3710
3773
int err ;
3711
3774
@@ -3745,6 +3808,14 @@ annotate_dax_parent(hwloc_obj_t obj, const char *name, int fsroot_fd)
3745
3808
type = strstr (begin , "ndbus" ) ? "NVM" : "SPM" ;
3746
3809
hwloc_obj_add_info (obj , "DAXType" , type );
3747
3810
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
+
3748
3819
/* insert DAXParent last because it's likely less useful than others */
3749
3820
hwloc_obj_add_info (obj , "DAXParent" , begin );
3750
3821
0 commit comments