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 <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2480763
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sagar Kamble
2021-02-02 19:40:53 +05:30
committed by mobile promotions
parent ed16377983
commit 79fb97100d
2 changed files with 124 additions and 2 deletions

View File

@@ -1917,6 +1917,89 @@ out:
#endif #endif
#ifdef CONFIG_NVGPU_COMPRESSION #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, static int nvgpu_handle_comptags_control(struct gk20a *g,
struct dma_buf *dmabuf, struct dma_buf *dmabuf,
struct gk20a_dmabuf_priv *priv, 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, err = nvgpu_gpu_ioctl_register_buffer(g,
(struct nvgpu_gpu_register_buffer_args *)buf); (struct nvgpu_gpu_register_buffer_args *)buf);
break; 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 #endif
default: default:

View File

@@ -503,6 +503,27 @@ struct nvgpu_gpu_vsms_mapping {
__u64 vsms_map_buf_addr; __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 * If the buffer registration is done, this flag is set in the output flags in
* the buffer info query ioctl. * the buffer info query ioctl.
@@ -510,11 +531,24 @@ struct nvgpu_gpu_vsms_mapping {
#define NVGPU_GPU_BUFFER_INFO_FLAGS_METADATA_REGISTERED (1ULL << 0) #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 * If the comptags are allocated and enabled for the buffer, this flag is set
* flags in the buffer info query ioctl. * in the output flags in the buffer info query ioctl.
*/ */
#define NVGPU_GPU_BUFFER_INFO_FLAGS_COMPTAGS_ALLOCATED (1ULL << 1) #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 { struct nvgpu_gpu_get_buffer_info_args {
union { union {
struct { struct {