From 79fb97100df0e33c73a65f37f48091e30c1cc824 Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Tue, 2 Feb 2021 19:40:53 +0530 Subject: [PATCH] gpu: nvgpu: implement GET_BUFFER_INFO ioctl Userspace applications will need to query buffer information such as size, comptags allocation status, user associated metadata etc. for enabling newer IPC mechanisms. Add support for this new ioctl. Bug 200586313 Change-Id: I87607eb306afa0cce1bec7a1fb2925ec3bc33e50 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2480763 Reviewed-by: svc_kernel_abi Reviewed-by: Konsta Holtta Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 88 +++++++++++++++++++++++++ include/uapi/linux/nvgpu-ctrl.h | 38 ++++++++++- 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index e5f0a1aee..d053f32fc 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -1917,6 +1917,89 @@ out: #endif #ifdef CONFIG_NVGPU_COMPRESSION +static int nvgpu_gpu_ioctl_get_buffer_info(struct gk20a *g, + struct nvgpu_gpu_get_buffer_info_args *args) +{ + u64 user_metadata_addr = args->in.metadata_addr; + u32 in_metadata_size = args->in.metadata_size; + struct gk20a_dmabuf_priv *priv = NULL; + s32 dmabuf_fd = args->in.dmabuf_fd; + struct dma_buf *dmabuf; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_BUFFER_METADATA)) { + nvgpu_err(g, "Buffer metadata not supported"); + return -EINVAL; + } + + args->out.metadata_size = 0; + args->out.flags = 0; + args->out.size = 0; + + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) { + nvgpu_warn(g, "%s: fd %d is not a dmabuf", + __func__, dmabuf_fd); + return PTR_ERR(dmabuf); + } + + args->out.size = dmabuf->size; + + priv = gk20a_dma_buf_get_drvdata(dmabuf, dev_from_gk20a(g)); + if (!priv) { + nvgpu_log_info(g, "Buffer metadata not allocated"); + goto out; + } + + nvgpu_mutex_acquire(&priv->lock); + + if (in_metadata_size > 0) { + size_t write_size = priv->metadata_blob_size; + + nvgpu_speculation_barrier(); + + if (write_size > in_metadata_size) { + write_size = in_metadata_size; + } + + if (copy_to_user((void __user *)(uintptr_t) + user_metadata_addr, + priv->metadata_blob, write_size)) { + nvgpu_err(g, "metadata blob copy failed"); + err = -EFAULT; + goto out_priv_unlock; + } + } + + args->out.metadata_size = priv->metadata_blob_size; + + if (priv->registered) { + args->out.flags |= + NVGPU_GPU_BUFFER_INFO_FLAGS_METADATA_REGISTERED; + } + + if (priv->comptags.enabled) { + args->out.flags |= + NVGPU_GPU_BUFFER_INFO_FLAGS_COMPTAGS_ALLOCATED; + } + + if (priv->mutable_metadata) { + args->out.flags |= + NVGPU_GPU_BUFFER_INFO_FLAGS_MUTABLE_METADATA; + } + + nvgpu_log_info(g, "buffer info: fd: %d, flags %llx, size %llu", + dmabuf_fd, args->out.flags, args->out.size); + +out_priv_unlock: + nvgpu_mutex_release(&priv->lock); +out: + dma_buf_put(dmabuf); + return err; +} + static int nvgpu_handle_comptags_control(struct gk20a *g, struct dma_buf *dmabuf, struct gk20a_dmabuf_priv *priv, @@ -2462,6 +2545,11 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg err = nvgpu_gpu_ioctl_register_buffer(g, (struct nvgpu_gpu_register_buffer_args *)buf); break; + + case NVGPU_GPU_IOCTL_GET_BUFFER_INFO: + err = nvgpu_gpu_ioctl_get_buffer_info(g, + (struct nvgpu_gpu_get_buffer_info_args *)buf); + break; #endif default: diff --git a/include/uapi/linux/nvgpu-ctrl.h b/include/uapi/linux/nvgpu-ctrl.h index 912ada3ab..910aab2b8 100644 --- a/include/uapi/linux/nvgpu-ctrl.h +++ b/include/uapi/linux/nvgpu-ctrl.h @@ -503,6 +503,27 @@ struct nvgpu_gpu_vsms_mapping { __u64 vsms_map_buf_addr; }; +/* + * get buffer information ioctl. + * + * Note: Additional metadata is available with the buffer only for supporting + * legacy userspace APIs and for compatibility with desktop RM. Usage of this + * API should be avoided. + * + * This ioctl returns information about buffer to libnvrm_gpu. This information + * includes buffer registration status, comptags allocation status, size of the + * buffer, copy of the metadata blob associated with the buffer during + * registration based on input size and size of the metadata blob + * registered. + * + * return 0 on success, < 0 in case of failure. Note that If the buffer + * has no privdata allocated or if it is not registered, this + * devctl returns 0 with only size. + * retval -EINVAL if the enabled flag NVGPU_SUPPORT_BUFFER_METADATA isn't + * set or invalid params. + * retval -EFAULT if the metadata blob copy fails. + */ + /* * If the buffer registration is done, this flag is set in the output flags in * the buffer info query ioctl. @@ -510,11 +531,24 @@ struct nvgpu_gpu_vsms_mapping { #define NVGPU_GPU_BUFFER_INFO_FLAGS_METADATA_REGISTERED (1ULL << 0) /* - * If the comptags are allocated for the buffer, this flag is set in the output - * flags in the buffer info query ioctl. + * If the comptags are allocated and enabled for the buffer, this flag is set + * in the output flags in the buffer info query ioctl. */ #define NVGPU_GPU_BUFFER_INFO_FLAGS_COMPTAGS_ALLOCATED (1ULL << 1) +/* + * If the metadata state (blob and comptags) of the buffer can be redefined, + * this flag is set in the output flags in the buffer info query ioctl. + */ +#define NVGPU_GPU_BUFFER_INFO_FLAGS_MUTABLE_METADATA (1ULL << 2) + +/* + * get buffer info ioctl arguments struct. + * + * Note: Additional metadata is available with the buffer only for supporting + * legacy userspace APIs and for compatibility with desktop RM. Usage of this + * API should be avoided. + */ struct nvgpu_gpu_get_buffer_info_args { union { struct {