Skip to content

Commit 5fbb3bc

Browse files
rocr: Add WSL support by conditionally handling DRM
operations (#2081) This patch enhances compatibility for DXG environments by introducing conditional checks for DRM operations, particularly around buffer object metadata handling in IPC scenarios. These changes improve robustness in DXG IPC memory management without impacting existing functionality in standard Linux environments. Signed-off-by: Horatio Zhang <[email protected]> [rocm-systems] ROCm/rocm-systems#2081 (commit 4bd1b90)
1 parent e20da25 commit 5fbb3bc

File tree

3 files changed

+61
-37
lines changed

3 files changed

+61
-37
lines changed

runtime/hsa-runtime/core/inc/thunk_loader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ class ThunkLoader {
365365
uint64_t flags, \
366366
uint32_t op);
367367

368+
typedef int (DRM_DEF(amdgpu_bo_query_info))(amdgpu_bo_handle bo, \
369+
struct amdgpu_bo_info* info);
370+
371+
typedef int (DRM_DEF(amdgpu_bo_set_metadata))(amdgpu_bo_handle bo, \
372+
struct amdgpu_bo_metadata* info);
373+
368374
typedef int (DRM_DEF(drmCommandWriteRead))(int fd, \
369375
unsigned long drmCommandIndex, \
370376
void *data, \
@@ -483,6 +489,8 @@ class ThunkLoader {
483489
DRM_DEF(amdgpu_bo_export)* DRM_PFN(amdgpu_bo_export);
484490
DRM_DEF(amdgpu_bo_import)* DRM_PFN(amdgpu_bo_import);
485491
DRM_DEF(amdgpu_bo_va_op)* DRM_PFN(amdgpu_bo_va_op);
492+
DRM_DEF(amdgpu_bo_query_info)* DRM_PFN(amdgpu_bo_query_info);
493+
DRM_DEF(amdgpu_bo_set_metadata)* DRM_PFN(amdgpu_bo_set_metadata);
486494
DRM_DEF(drmCommandWriteRead)* DRM_PFN(drmCommandWriteRead);
487495

488496
private:

runtime/hsa-runtime/core/runtime/runtime.cpp

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -378,13 +378,15 @@ hsa_status_t Runtime::FreeMemory(void* ptr) {
378378
//clear the set metadata here if possible if theres an existing ldrm_bo
379379
if (it->second.ldrm_bo) {
380380
#if defined(__linux__)
381-
struct amdgpu_bo_info info = {0};
382-
auto err = amdgpu_bo_query_info(it->second.ldrm_bo, &info);
381+
if (!thunkLoader()->IsDXG()) {
382+
struct amdgpu_bo_info info = {0};
383+
auto err = DRM_CALL(amdgpu_bo_query_info(it->second.ldrm_bo, &info));
383384

384-
//clear metadata
385-
amdgpu_bo_metadata zero_metadata = {0};
386-
memset(zero_metadata.umd_metadata, 0, sizeof(uint32_t));
387-
amdgpu_bo_set_metadata(it->second.ldrm_bo, &zero_metadata);
385+
//clear metadata
386+
amdgpu_bo_metadata zero_metadata = {0};
387+
memset(zero_metadata.umd_metadata, 0, sizeof(uint32_t));
388+
DRM_CALL(amdgpu_bo_set_metadata(it->second.ldrm_bo, &zero_metadata));
389+
}
388390
#else
389391
assert(!"Unimplemented!");
390392
#endif
@@ -1404,29 +1406,31 @@ hsa_status_t Runtime::IPCCreate(void* ptr, size_t len, hsa_amd_ipc_memory_t* han
14041406

14051407
if (agent->device_type() == Agent::kAmdGpuDevice) {
14061408
#if defined(__linux__)
1407-
AMD::GpuAgent* agent_ = reinterpret_cast<AMD::GpuAgent*>(agent);
1408-
amdgpu_bo_import_result res;
1409+
if (!thunkLoader()->IsDXG()) {
1410+
AMD::GpuAgent* agent_ = reinterpret_cast<AMD::GpuAgent*>(agent);
1411+
amdgpu_bo_import_result res;
14091412

1410-
srand(static_cast<uint32_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count()));
1411-
handle->handle[7] = rand();
1413+
srand(static_cast<uint32_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count()));
1414+
handle->handle[7] = rand();
14121415

1413-
//libdrm import for buffer object handle
1414-
if (DRM_CALL(amdgpu_bo_import(agent_->libDrmDev(), amdgpu_bo_handle_type_dma_buf_fd, dmabuf_fd, &res))) {
1415-
fprintf(stderr, "Error in amdgpu_bo_import\n");
1416-
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1417-
}
1416+
//libdrm import for buffer object handle
1417+
if (DRM_CALL(amdgpu_bo_import(agent_->libDrmDev(), amdgpu_bo_handle_type_dma_buf_fd, dmabuf_fd, &res))) {
1418+
fprintf(stderr, "Error in amdgpu_bo_import\n");
1419+
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1420+
}
14181421

1419-
//query buffer object for pre existing metadata
1420-
struct amdgpu_bo_info info = {0};
1421-
if (!amdgpu_bo_query_info(res.buf_handle, &info) && !!info.metadata.size_metadata) {
1422-
handle->handle[7] = info.metadata.umd_metadata[0];
1423-
} else {
1424-
amdgpu_bo_metadata buf_info = {0};
1425-
buf_info.size_metadata = sizeof(uint32_t);
1426-
buf_info.umd_metadata[0] = handle->handle[7];
1422+
//query buffer object for pre existing metadata
1423+
struct amdgpu_bo_info info = {0};
1424+
if (!DRM_CALL(amdgpu_bo_query_info(res.buf_handle, &info)) && !!info.metadata.size_metadata) {
1425+
handle->handle[7] = info.metadata.umd_metadata[0];
1426+
} else {
1427+
amdgpu_bo_metadata buf_info = {0};
1428+
buf_info.size_metadata = sizeof(uint32_t);
1429+
buf_info.umd_metadata[0] = handle->handle[7];
14271430

1428-
amdgpu_bo_set_metadata(res.buf_handle, &buf_info);
1429-
allocation_map_[ptr].ldrm_bo = res.buf_handle;
1431+
DRM_CALL(amdgpu_bo_set_metadata(res.buf_handle, &buf_info));
1432+
allocation_map_[ptr].ldrm_bo = res.buf_handle;
1433+
}
14301434
}
14311435
#else
14321436
assert(!"Unimplemented!");
@@ -1593,15 +1597,17 @@ hsa_status_t Runtime::IPCAttach(const hsa_amd_ipc_memory_t* handle, size_t len,
15931597
if (ret) return HSA_STATUS_ERROR_INVALID_ARGUMENT;
15941598
if (ipc_dmabuf_supported_ && !isSysMem) {
15951599
#if defined(__linux__)
1596-
// use the bo from the allocation map
1597-
// Only check metadata for GPU memory
1598-
struct amdgpu_bo_info info = {0};
1599-
int ret = amdgpu_bo_query_info(allocation_map_[importAddress].ldrm_bo, &info);
1600-
1601-
// Validate metadata for IPC handle
1602-
if (ret || info.metadata.umd_metadata[0] != importHandle.handle[7]) {
1603-
fprintf(stderr, "IPC Attach: Invalid IPC handle! %u and %u\n", importHandle.handle[7], info.metadata.umd_metadata[0]);
1604-
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1600+
if (!thunkLoader()->IsDXG()) {
1601+
// use the bo from the allocation map
1602+
// Only check metadata for GPU memory
1603+
struct amdgpu_bo_info info = {0};
1604+
int ret = DRM_CALL(amdgpu_bo_query_info(allocation_map_[importAddress].ldrm_bo, &info));
1605+
1606+
// Validate metadata for IPC handle
1607+
if (ret || info.metadata.umd_metadata[0] != importHandle.handle[7]) {
1608+
fprintf(stderr, "IPC Attach: Invalid IPC handle! %u and %u\n", importHandle.handle[7], info.metadata.umd_metadata[0]);
1609+
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1610+
}
16051611
}
16061612
#else
16071613
assert(!"Unimplemented!");
@@ -3790,11 +3796,13 @@ Runtime::MappedHandleAllowedAgent::~MappedHandleAllowedAgent() {
37903796
hsa_status_t Runtime::MappedHandleAllowedAgent::EnableAccess(hsa_access_permission_t perms) {
37913797
if (targetAgent->device_type() == core::Agent::DeviceType::kAmdCpuDevice) {
37923798
#if defined(__linux__)
3793-
void* mapped_ptr =
3799+
if (!core::Runtime::runtime_singleton_->thunkLoader()->IsDXG()) {
3800+
void* mapped_ptr =
37943801
mmap(va, size, PermissionsToMmapFlags(perms), MAP_SHARED | MAP_FIXED, mappedHandle->drm_fd,
37953802
reinterpret_cast<uint64_t>(mappedHandle->drm_cpu_addr));
3796-
if (mapped_ptr != va)
3797-
return HSA_STATUS_ERROR;
3803+
if (mapped_ptr != va)
3804+
return HSA_STATUS_ERROR;
3805+
}
37983806
} else {
37993807
hsa_status_t status = targetAgent->driver().Map(
38003808
shareable_handle, va, mappedHandle->offset, size, perms);

runtime/hsa-runtime/core/runtime/thunk_loader.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,12 @@ namespace core {
411411
DRM_PFN(amdgpu_bo_va_op) = (DRM_DEF(amdgpu_bo_va_op)*)dlsym(thunk_handle, "amdgpu_bo_va_op");
412412
if (DRM_PFN(amdgpu_bo_va_op) == NULL) goto ERROR;
413413

414+
DRM_PFN(amdgpu_bo_query_info) = (DRM_DEF(amdgpu_bo_query_info)*)dlsym(thunk_handle, "amdgpu_bo_query_info");
415+
if (DRM_PFN(amdgpu_bo_query_info) == NULL) goto ERROR;
416+
417+
DRM_PFN(amdgpu_bo_set_metadata) = (DRM_DEF(amdgpu_bo_set_metadata)*)dlsym(thunk_handle, "amdgpu_bo_set_metadata");
418+
if (DRM_PFN(amdgpu_bo_set_metadata) == NULL) goto ERROR;
419+
414420
DRM_PFN(drmCommandWriteRead) = (DRM_DEF(drmCommandWriteRead)*)dlsym(thunk_handle, "drmCommandWriteRead");
415421
if (DRM_PFN(drmCommandWriteRead) == NULL) goto ERROR;
416422
debug_print("Load all DTIF APIs OK!\n");
@@ -524,6 +530,8 @@ namespace core {
524530
DRM_PFN(amdgpu_bo_export) = (DRM_DEF(amdgpu_bo_export)*)(&amdgpu_bo_export);
525531
DRM_PFN(amdgpu_bo_import) = (DRM_DEF(amdgpu_bo_import)*)(&amdgpu_bo_import);
526532
DRM_PFN(amdgpu_bo_va_op) = (DRM_DEF(amdgpu_bo_va_op)*)(&amdgpu_bo_va_op);
533+
DRM_PFN(amdgpu_bo_query_info) = (DRM_DEF(amdgpu_bo_query_info)*)(&amdgpu_bo_query_info);
534+
DRM_PFN(amdgpu_bo_set_metadata) = (DRM_DEF(amdgpu_bo_set_metadata)*)(&amdgpu_bo_set_metadata);
527535
#if defined(__linux__)
528536
DRM_PFN(drmCommandWriteRead) = (DRM_DEF(drmCommandWriteRead)*)(&drmCommandWriteRead);
529537
#endif

0 commit comments

Comments
 (0)