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
Этот коммит содержится в:
Felix Kuehling
2021-11-16 23:13:11 -05:00
родитель e40ae8481e
Коммит 332f59eb2a
6 изменённых файлов: 93 добавлений и 2 удалений
+20
Просмотреть файл
@@ -436,6 +436,26 @@ hsaKmtRegisterGraphicsHandleToNodes(
HSAuint32* NodeArray //IN
);
/**
* Export a dmabuf handle and offset for a given memory address
*
* Validates that @MemoryAddress belongs to a valid allocation and that the
* @MemorySizeInBytes doesn't exceed the end of that allocation. Returns a
* dmabuf fd of the allocation and the offset of MemoryAddress within that
* allocation. The memory will remain allocated even after the allocation is
* freed by hsaKmtFreeMemory for as long as a dmabuf fd remains open or any
* importer of that fd maintains an active reference to the memory.
*/
HSAKMT_STATUS
HSAKMTAPI
hsaKmtExportDMABufHandle(
void *MemoryAddress, //IN
HSAuint64 MemorySizeInBytes, //IN
int *DMABufFd, //OUT
HSAuint64 *Offset //OUT
);
/**
Export a memory buffer for sharing with other processes
+12 -2
Просмотреть файл
@@ -37,9 +37,10 @@
* - 1.9 - Add available_memory ioctl
* - 1.10 - Add SMI profiler event log
* - 1.11 - Add unified memory for ctx save/restore area
* - 1.12 - Add DMA buf export ioctl
*/
#define KFD_IOCTL_MAJOR_VERSION 1
#define KFD_IOCTL_MINOR_VERSION 11
#define KFD_IOCTL_MINOR_VERSION 12
/*
* Debug revision change log
@@ -847,6 +848,12 @@ struct kfd_ioctl_import_dmabuf_args {
__u32 dmabuf_fd; /* to KFD */
};
struct kfd_ioctl_export_dmabuf_args {
__u64 handle; /* to KFD */
__u32 flags; /* to KFD */
__u32 dmabuf_fd; /* from KFD */
};
/*
* KFD SMI(System Management Interface) events
*/
@@ -1345,8 +1352,11 @@ struct kfd_ioctl_set_xnack_mode_args {
#define AMDKFD_IOC_AVAILABLE_MEMORY \
AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)
#define AMDKFD_IOC_EXPORT_DMABUF \
AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args)
#define AMDKFD_COMMAND_START 0x01
#define AMDKFD_COMMAND_END 0x24
#define AMDKFD_COMMAND_END 0x25
/* non-upstream ioctls */
#define AMDKFD_IOC_IPC_IMPORT_HANDLE \
+42
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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
Просмотреть файл
@@ -70,6 +70,7 @@ hsaKmtSVMGetAttr;
hsaKmtSetXNACKMode;
hsaKmtGetXNACKMode;
hsaKmtOpenSMI;
hsaKmtExportDMABufHandle;
local: *;
};
+14
Просмотреть файл
@@ -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)