[PATCH 2/3] drm/amdgpu: Add ioctl infra for exporting/importing UALink handles
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Mukul Joshi <[email protected]> Add the ioctl infrastructure to support exporting and importing BOs to facilitate NPA based memory sharing across GPUs in a rack scale setup. Proposed userspace: https://github.com/ROCm/rocm-systems/blob/35959f8e1260c7cee3e51a740e320be3856ee4ff/projects/rocr-runtime/libhsakmt/src/memory.c#L971 https://github.com/ROCm/rocm-systems/blob/35959f8e1260c7cee3e51a740e320be3856ee4ff/projects/rocr-runtime/libhsakmt/src/memory.c#L1036 v2: Move the ioctl wire-up to the end of the series. Signed-off-by: Mukul Joshi <[email protected]> Signed-off-by: Horatio Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c | 44 ++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h | 2 + include/uapi/drm/amdgpu_drm.h | 30 +++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 04b21e456fbc0..25430ff39a6c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -54,6 +54,7 @@ #include "amdgpu_userq.h" #include "amdgpu_userq_fence.h" #include "../amdxcp/amdgpu_xcp_drv.h" +#include "amdgpu_ualink.h" /* * KMS wrapper. @@ -3119,6 +3120,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_WAIT, amdgpu_userq_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_GEM_LIST_HANDLES, amdgpu_gem_list_handles_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_PROC_OPTIONS, amdgpu_proc_options_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_UALINK_HANDLE, amdgpu_gem_ualink_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW) }; static const struct drm_driver amdgpu_kms_driver = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c index 402d8941fb045..63374c6b9ebd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c @@ -3963,6 +3963,50 @@ int amdgpu_ualink_export_handle(struct drm_device *dev, struct drm_file *filp, return r; } +int amdgpu_gem_ualink_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + union drm_amdgpu_ualink_handle *args = data; + struct amdgpu_device *adev = drm_to_adev(dev); + struct amdgpu_ualink_handle handle = {}; + u32 gem_handle; + int r, fd = -1; + + if (adev->ualink.info->accel_state != + AMDGPU_UALINK_ACCEL_STATE_ACTIVE) { + dev_err(adev->dev, + "ualink device is not in active state in vpod\n"); + return -EOPNOTSUPP; + } + + /* The input and output members of the ioctl argument alias each other. + * Latch every input field before invoking the handlers, and only write + * the output fields afterwards. + */ + switch (args->in.op) { + case DRM_AMDGPU_UALINK_HANDLE_OP_EXPORT: + gem_handle = args->in.gem_handle; + r = amdgpu_ualink_export_handle(dev, filp, gem_handle, &handle); + if (!r) { + args->out.export_ualink_handle[0] = handle.handle_lo; + args->out.export_ualink_handle[1] = handle.handle_hi; + } + break; + case DRM_AMDGPU_UALINK_HANDLE_OP_IMPORT: + handle.handle_lo = args->in.import_ualink_handle[0]; + handle.handle_hi = args->in.import_ualink_handle[1]; + r = amdgpu_ualink_import_handle(dev, &handle, &fd); + if (!r) + args->out.import_dmabuf_handle = fd; + break; + default: + r = -EINVAL; + break; + } + + return r; +} + int amdgpu_ualink_manager_start(struct amdgpu_device *adev) { int i, r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h index 63710b484c6a5..9908d3a277172 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h @@ -409,6 +409,8 @@ int amdgpu_ualink_export_handle(struct drm_device *dev, struct drm_file *filp, int amdgpu_ualink_import_handle(struct drm_device *dev, const struct amdgpu_ualink_handle *ualink_handle, int *fd_out); +int amdgpu_gem_ualink_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); void amdgpu_ualink_revoke_exported_memory(struct amdgpu_bo *bo); int ualink_ip_hw_init(struct amdgpu_ip_block *ip_block); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index d6d5402a1e789..0e8115673d8d2 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -59,6 +59,7 @@ extern "C" { #define DRM_AMDGPU_USERQ_WAIT 0x18 #define DRM_AMDGPU_GEM_LIST_HANDLES 0x19 #define DRM_AMDGPU_PROC_OPTIONS 0x1A +#define DRM_AMDGPU_UALINK_HANDLE 0x1B #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) @@ -81,6 +82,7 @@ extern "C" { #define DRM_IOCTL_AMDGPU_USERQ_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait) #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles) #define DRM_IOCTL_AMDGPU_PROC_OPTIONS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options) +#define DRM_IOCTL_AMDGPU_UALINK_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_UALINK_HANDLE, union drm_amdgpu_ualink_handle) /** * DOC: memory domains @@ -1705,6 +1707,34 @@ struct drm_amdgpu_proc_options { } kfd_sigbus_delay; }; +#define DRM_AMDGPU_UALINK_HANDLE_OP_EXPORT 0 +#define DRM_AMDGPU_UALINK_HANDLE_OP_IMPORT 1 + +struct drm_amdgpu_ualink_handle_in { + /* Export or import */ + __u32 op; + /* For future use, no flags defined so far */ + __u32 flags; + union { + /* GEM handle of the BO to export */ + __u32 gem_handle; + /* UALink handle to import */ + __u64 import_ualink_handle[2]; + }; +}; + +union drm_amdgpu_ualink_handle_out { + /* Exported UALink handle */ + __u64 export_ualink_handle[2]; + /** DMABuf representing the imported UALink handle */ + __u32 import_dmabuf_handle; +}; + +union drm_amdgpu_ualink_handle { + struct drm_amdgpu_ualink_handle_in in; + union drm_amdgpu_ualink_handle_out out; +}; + #if defined(__cplusplus) } #endif -- 2.55.0