@@ -297,52 +297,144 @@ ucs_status_t uct_rocm_base_detect_memory_type(uct_md_h md, const void *addr,
297297 return UCS_OK ;
298298}
299299
300- int uct_rocm_base_is_dmabuf_supported ()
300+ FILE * uct_rocm_base_load_prod_config_file ()
301301{
302- int dmabuf_supported = 0 ;
303-
304- #if HAVE_HSA_AMD_PORTABLE_EXPORT_DMABUF
305- const char kernel_opt1 [] = "CONFIG_DMABUF_MOVE_NOTIFY=y" ;
306- const char kernel_opt2 [] = "CONFIG_PCI_P2PDMA=y" ;
307- int found_opt1 = 0 ;
308- int found_opt2 = 0 ;
309- FILE * fp ;
310- struct utsname utsname ;
302+ /* Skip if zcat is unavailable or /proc/config.gz does not exist.
303+ * popen() succeeds even when the file is missing, producing an empty
304+ * stream that falsely triggers the "not found" error path.
305+ * Check if zcat is available in the system */
306+ int has_zcat = 0 ;
307+ int has_config_file = 0 ;
311308 char kernel_conf_file [128 ];
312- char buf [256 ];
309+ const char path [] = "/proc/config.gz" ;
310+ char popen_cmd [256 ];
311+
312+ ucs_snprintf_safe (kernel_conf_file , sizeof (kernel_conf_file ), path );
313+ has_zcat = (system ("which zcat > /dev/null 2>&1" ) == 0 );
314+ has_config_file = (access (path , R_OK ) == 0 );
315+ if (!has_zcat || !has_config_file ) {
316+ ucs_trace ("Skipping %s (zcat %s, file %s)" , kernel_conf_file ,
317+ has_zcat ? "available" : "unavailable" ,
318+ has_config_file ? "exists" : "not found" );
319+ return NULL ;
320+ }
321+ ucs_snprintf_safe (popen_cmd , sizeof (popen_cmd ), "zcat %s 2>/dev/null" , path );
322+ return popen (popen_cmd , "r" );
323+ }
313324
325+ FILE * uct_rocm_base_load_kernel_config_file ()
326+ {
327+ const char * fmts [] = {
328+ "/boot/config-%s" ,
329+ "/usr/src/linux-%s/.config" ,
330+ "/usr/src/linux/.config" ,
331+ "/usr/lib/modules/%s/config" ,
332+ "/usr/lib/ostree-boot/config-%s" ,
333+ "/usr/lib/kernel/config-%s" ,
334+ "/usr/src/linux-headers-%s/.config" ,
335+ "/lib/modules/%s/build/.config"
336+ };
337+ FILE * fp = NULL ;
338+ char kernel_conf_file [128 ];
339+ struct utsname utsname ;
340+
314341 if (uname (& utsname ) == -1 ) {
315342 ucs_trace ("could not get kernel name" );
316- goto out ;
343+ return NULL ;
317344 }
318345
319- ucs_snprintf_safe (kernel_conf_file , sizeof (kernel_conf_file ),
320- "/boot/config-%s" , utsname .release );
321- fp = fopen (kernel_conf_file , "r" );
322- if (fp == NULL ) {
323- ucs_trace ("could not open kernel conf file %s error: %m" ,
324- kernel_conf_file );
325- goto out ;
346+ for (size_t i = 0 ; i < sizeof (fmts ) / sizeof (fmts [0 ]); ++ i ) {
347+ const char * path = fmts [i ];
348+ ucs_snprintf_safe (kernel_conf_file , sizeof (kernel_conf_file ), path , utsname .release );
349+ fp = fopen (kernel_conf_file , "r" );
350+ if (fp != NULL ) {
351+ ucs_trace ("reading kernel config from %s" , kernel_conf_file );
352+ return fp ;
353+ }
354+ ucs_trace ("could not open kernel conf file %s error: %m" , kernel_conf_file );
326355 }
356+ return fp ;
357+ }
358+
359+ int uct_rocm_base_file_contains_dmabuf_support (FILE * fp , const char kernel_opt1 [], const char kernel_opt2 [])
360+ {
361+ int dmabuf_supported = 0 ;
362+ int found_opt1 = 0 ;
363+ int found_opt2 = 0 ;
364+ char buf [256 ];
327365
328366 while (fgets (buf , sizeof (buf ), fp ) != NULL ) {
329- if (strstr (buf , kernel_opt1 ) != NULL ) {
367+ if (! found_opt1 && ( strstr (buf , kernel_opt1 ) != NULL ) ) {
330368 found_opt1 = 1 ;
331369 }
332- if (strstr (buf , kernel_opt2 ) != NULL ) {
370+ if (! found_opt2 && ( strstr (buf , kernel_opt2 ) != NULL ) ) {
333371 found_opt2 = 1 ;
334372 }
335373 if (found_opt1 && found_opt2 ) {
336374 dmabuf_supported = 1 ;
337- break ;
338375 }
339376 }
377+ return dmabuf_supported ;
378+ }
379+
380+ int uct_rocm_base_kernel_config_supports_dmabuf ()
381+ {
382+ int dmabuf_supported = 0 ;
383+ FILE * fp = NULL ;
384+ const char kernel_opt1 [] = "CONFIG_DMABUF_MOVE_NOTIFY=y" ;
385+ const char kernel_opt2 [] = "CONFIG_PCI_P2PDMA=y" ;
386+
387+ /* Special handling for /proc/config.gz */
388+ fp = uct_rocm_base_load_prod_config_file ();
389+ if (fp != NULL ) {
390+ dmabuf_supported = uct_rocm_base_file_contains_dmabuf_support (fp , kernel_opt1 , kernel_opt2 );
391+ pclose (fp );
392+ if (dmabuf_supported == 1 ) {
393+ return dmabuf_supported ;
394+ }
395+ }
396+
397+ fp = uct_rocm_base_load_kernel_config_file ();
398+ if (fp == NULL ) {
399+ ucs_trace ("no kernel conf file found" );
400+ return 0 ;
401+ }
402+ dmabuf_supported = uct_rocm_base_file_contains_dmabuf_support (fp , kernel_opt1 , kernel_opt2 );
403+ fclose (fp );
404+ return dmabuf_supported ;
405+ }
406+
407+ int uct_rocm_base_kernel_symbols_supports_dmabuf ()
408+ {
409+ int dmabuf_supported = 0 ;
410+ FILE * fp = NULL ;
411+ const char kernel_sym1 [] = "dma_buf_move_notify" ;
412+ const char kernel_sym2 [] = "pci_p2pdma" ;
413+
414+ fp = fopen ("/proc/kallsyms" , "r" );
415+ if (fp == NULL ) {
416+ ucs_trace ("no /proc/kallsyms file found" );
417+ return dmabuf_supported ;
418+ }
419+ dmabuf_supported = uct_rocm_base_file_contains_dmabuf_support (fp , kernel_sym1 , kernel_sym2 );
340420 fclose (fp );
341- #endif
342- out :
343421 return dmabuf_supported ;
344422}
345423
424+ int uct_rocm_base_is_dmabuf_supported ()
425+ {
426+ #if HAVE_HSA_AMD_PORTABLE_EXPORT_DMABUF
427+ if (uct_rocm_base_kernel_config_supports_dmabuf ()) {
428+ return 1 ;
429+ }
430+
431+ ucs_trace ("no kernel conf file found or no support for dmabuf found, trying /proc/kallsyms fallback" );
432+ return uct_rocm_base_kernel_symbols_supports_dmabuf ();
433+ #else
434+ return 0 ;
435+ #endif
436+ }
437+
346438static void uct_rocm_base_dmabuf_export (const void * addr , const size_t length ,
347439 ucs_memory_type_t mem_type ,
348440 int * dmabuf_fd , size_t * dmabuf_offset )
0 commit comments