libhsakmt: Implement dmabuf export for RDMA

Implement hsaKmtExportDMABufHandle, which can be used for a new
upstreamable RDMA solution. It exports a DMABuf handle for an arbitrary
virtual address along with the offset of the address within the
allocation. It also checks that the size of the intended export does
not exceed the allocation.

This uses the new AMDKFD_IOC_EXPORT_DMABUF, which requires KFD ioctl
API version 1.12.

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Change-Id: Ie5fdb1f73ab3c7fa36c315ce326b1fb89eacc8b6
This commit is contained in:
Felix Kuehling
2021-11-16 23:13:11 -05:00
parent e40ae8481e
commit 332f59eb2a
6 changed files with 93 additions and 2 deletions
+42
View File
@@ -3309,6 +3309,48 @@ error_free_metadata:
return status;
}
HSAKMT_STATUS fmm_export_dma_buf_fd(void *MemoryAddress,
HSAuint64 MemorySizeInBytes,
int *DMABufFd,
HSAuint64 *Offset)
{
struct kfd_ioctl_export_dmabuf_args exportArgs = {0};
manageable_aperture_t *aperture;
HsaApertureInfo ApeInfo;
vm_object_t *obj;
HSAuint64 offset;
int r;
aperture = fmm_find_aperture(MemoryAddress, &ApeInfo);
if (!aperture)
return HSAKMT_STATUS_INVALID_PARAMETER;
pthread_mutex_lock(&aperture->fmm_mutex);
obj = vm_find_object_by_address_range(aperture, MemoryAddress);
if (obj) {
offset = VOID_PTRS_SUB(MemoryAddress, obj->start);
if (offset + MemorySizeInBytes <= obj->size) {
exportArgs.handle = obj->handle;
exportArgs.flags = O_CLOEXEC;
exportArgs.dmabuf_fd = 0;
} else {
obj = NULL;
}
}
pthread_mutex_unlock(&aperture->fmm_mutex);
if (!obj)
return HSAKMT_STATUS_INVALID_PARAMETER;
r = kmtIoctl(kfd_fd, AMDKFD_IOC_EXPORT_DMABUF, (void *)&exportArgs);
if (r)
return HSAKMT_STATUS_ERROR;
*DMABufFd = exportArgs.dmabuf_fd;
*Offset = offset;
return HSAKMT_STATUS_SUCCESS;
}
HSAKMT_STATUS fmm_share_memory(void *MemoryAddress,
HSAuint64 SizeInBytes,
HsaSharedMemoryHandle *SharedMemoryHandle)
+4
View File
@@ -78,6 +78,10 @@ HSAKMT_STATUS fmm_register_graphics_handle(HSAuint64 GraphicsResourceHandle,
uint32_t *gpu_id_array,
uint32_t gpu_id_array_size);
HSAKMT_STATUS fmm_deregister_memory(void *address);
HSAKMT_STATUS fmm_export_dma_buf_fd(void *MemoryAddress,
HSAuint64 MemorySizeInBytes,
int *DMABufFd,
HSAuint64 *Offset);
HSAKMT_STATUS fmm_share_memory(void *MemoryAddress,
HSAuint64 SizeInBytes,
HsaSharedMemoryHandle *SharedMemoryHandle);
+1
View File
@@ -70,6 +70,7 @@ hsaKmtSVMGetAttr;
hsaKmtSetXNACKMode;
hsaKmtGetXNACKMode;
hsaKmtOpenSMI;
hsaKmtExportDMABufHandle;
local: *;
};
+14
View File
@@ -318,6 +318,20 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtRegisterGraphicsHandleToNodes(HSAuint64 GraphicsRe
return ret;
}
HSAKMT_STATUS HSAKMTAPI hsaKmtExportDMABufHandle(void *MemoryAddress,
HSAuint64 MemorySizeInBytes,
int *DMABufFd,
HSAuint64 *Offset)
{
CHECK_KFD_OPEN();
CHECK_KFD_MINOR_VERSION(12);
pr_debug("[%s] address %p\n", __func__, MemoryAddress);
return fmm_export_dma_buf_fd(MemoryAddress, MemorySizeInBytes,
DMABufFd, Offset);
}
HSAKMT_STATUS HSAKMTAPI hsaKmtShareMemory(void *MemoryAddress,
HSAuint64 SizeInBytes,
HsaSharedMemoryHandle *SharedMemoryHandle)