Skip to content

Commit 814cf1b

Browse files
UCT/ROCM: Fix dmabuf support check for more os.
Co-authored-by: Edgar Gabriel <Edgar.Gabriel@amd.com>
1 parent 33e7d1d commit 814cf1b

2 files changed

Lines changed: 117 additions & 24 deletions

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Gonzalo Brito Gadeschi <gonzalob@nvidia.com>
4242
Graham Lopez <lopezmg@ornl.gov>
4343
Guy Ealey Morag <gealeymorag@nvidia.com>
4444
Guy Shattah <sguy@mellanox.com>
45+
Hannes Hansen <mail@hannesh.de>
4546
Hessam Mirsadeghi <hmirsadeghi@nvidia.com>
4647
Hiroyuki Sato <hiroysato@gmail.com>
4748
Hod Badihi <hbadihi@nvidia.com>

src/uct/rocm/base/rocm_base.c

Lines changed: 116 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
346438
static 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

Comments
 (0)