[PATCH 2/6] drm/amdkfd: Implement DMA buf fd export from KFD

Chen, Xiaogang xiaogang.chen at amd.com
Fri Jan 13 08:03:41 UTC 2023


Reviewed-by: Xiaogang Chen <Xiaoganng.Chen at amd.com>

Regards

Xiaogang

On 1/11/2023 7:31 PM, Felix Kuehling wrote:
> Exports a DMA buf fd of a given KFD buffer handle. This is intended for
> being able to import KFD BOs into GEM contexts to leverage the
> amdgpu_bo_va API for more flexible virtual address mappings. It will
> also be used for the new upstreamable RDMA solution coming to UCX and
> RCCL.
>
> The corresponding user mode change (Thunk API and kfdtest) is here:
> https://github.com/fxkamd/ROCT-Thunk-Interface/commits/fxkamd/dmabuf
>
> Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h    |  2 +
>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 45 +++++++++++----
>   drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      | 55 +++++++++++++++++++
>   include/uapi/linux/kfd_ioctl.h                | 14 ++++-
>   4 files changed, 104 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> index 333780491867..01ba3589b60a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> @@ -308,6 +308,8 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
>   				      uint64_t va, void *drm_priv,
>   				      struct kgd_mem **mem, uint64_t *size,
>   				      uint64_t *mmap_offset);
> +int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,
> +				      struct dma_buf **dmabuf);
>   int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
>   				struct tile_config *config);
>   void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index e13c3493b786..5645103beed0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -710,6 +710,21 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,
>   	}
>   }
>   
> +static int kfd_mem_export_dmabuf(struct kgd_mem *mem)
> +{
> +	if (!mem->dmabuf) {
> +		struct dma_buf *ret = amdgpu_gem_prime_export(
> +			&mem->bo->tbo.base,
> +			mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
> +				DRM_RDWR : 0);
> +		if (IS_ERR(ret))
> +			return PTR_ERR(ret);
> +		mem->dmabuf = ret;
> +	}
> +
> +	return 0;
> +}
> +
>   static int
>   kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
>   		      struct amdgpu_bo **bo)
> @@ -717,16 +732,9 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
>   	struct drm_gem_object *gobj;
>   	int ret;
>   
> -	if (!mem->dmabuf) {
> -		mem->dmabuf = amdgpu_gem_prime_export(&mem->bo->tbo.base,
> -			mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
> -				DRM_RDWR : 0);
> -		if (IS_ERR(mem->dmabuf)) {
> -			ret = PTR_ERR(mem->dmabuf);
> -			mem->dmabuf = NULL;
> -			return ret;
> -		}
> -	}
> +	ret = kfd_mem_export_dmabuf(mem);
> +	if (ret)
> +		return ret;
>   
>   	gobj = amdgpu_gem_prime_import(adev_to_drm(adev), mem->dmabuf);
>   	if (IS_ERR(gobj))
> @@ -2267,6 +2275,23 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
>   	return ret;
>   }
>   
> +int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,
> +				      struct dma_buf **dma_buf)
> +{
> +	int ret;
> +
> +	mutex_lock(&mem->lock);
> +	ret = kfd_mem_export_dmabuf(mem);
> +	if (ret)
> +		goto out;
> +
> +	get_dma_buf(mem->dmabuf);
> +	*dma_buf = mem->dmabuf;
> +out:
> +	mutex_unlock(&mem->lock);
> +	return ret;
> +}
> +
>   /* Evict a userptr BO by stopping the queues if necessary
>    *
>    * Runs in MMU notifier, may be in RECLAIM_FS context. This means it
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> index f79b8e964140..bcf2263927d6 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> @@ -1572,6 +1572,58 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
>   	return r;
>   }
>   
> +static int kfd_ioctl_export_dmabuf(struct file *filep,
> +				   struct kfd_process *p, void *data)
> +{
> +	struct kfd_ioctl_export_dmabuf_args *args = data;
> +	struct kfd_process_device *pdd;
> +	struct dma_buf *dmabuf;
> +	struct kfd_dev *dev;
> +	void *mem;
> +	int ret = 0;
> +
> +	dev = kfd_device_by_id(GET_GPU_ID(args->handle));
> +	if (!dev)
> +		return -EINVAL;
> +
> +	mutex_lock(&p->mutex);
> +
> +	pdd = kfd_get_process_device_data(dev, p);
> +	if (!pdd) {
> +		ret = -EINVAL;
> +		goto err_unlock;
> +	}
> +
> +	mem = kfd_process_device_translate_handle(pdd,
> +						GET_IDR_HANDLE(args->handle));
> +	if (!mem) {
> +		ret = -EINVAL;
> +		goto err_unlock;
> +	}
> +
> +	ret = amdgpu_amdkfd_gpuvm_export_dmabuf(mem, &dmabuf);
> +	mutex_unlock(&p->mutex);
> +	if (ret)
> +		goto err_out;
> +
> +	ret = dma_buf_fd(dmabuf, args->flags);
> +	if (ret < 0) {
> +		dma_buf_put(dmabuf);
> +		goto err_out;
> +	}
> +	/* dma_buf_fd assigns the reference count to the fd, no need to
> +	 * put the reference here.
> +	 */
> +	args->dmabuf_fd = ret;
> +
> +	return 0;
> +
> +err_unlock:
> +	mutex_unlock(&p->mutex);
> +err_out:
> +	return ret;
> +}
> +
>   /* Handle requests for watching SMI events */
>   static int kfd_ioctl_smi_events(struct file *filep,
>   				struct kfd_process *p, void *data)
> @@ -2754,6 +2806,9 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
>   
>   	AMDKFD_IOCTL_DEF(AMDKFD_IOC_AVAILABLE_MEMORY,
>   			kfd_ioctl_get_available_memory, 0),
> +
> +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_EXPORT_DMABUF,
> +				kfd_ioctl_export_dmabuf, 0),
>   };
>   
>   #define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls)
> diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
> index 42b60198b6c5..2da5c3ad71bd 100644
> --- a/include/uapi/linux/kfd_ioctl.h
> +++ b/include/uapi/linux/kfd_ioctl.h
> @@ -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
>   
>   struct kfd_ioctl_get_version_args {
>   	__u32 major_version;	/* from KFD */
> @@ -463,6 +464,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
>    */
> @@ -877,7 +884,10 @@ 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
>   
>   #endif


More information about the dri-devel mailing list