From 30632cec54048944ee364781b4b8c2676ae5dfed Mon Sep 17 00:00:00 2001 From: Sami Kiminki Date: Mon, 26 Oct 2015 19:23:54 +0200 Subject: gpu: nvgpu: Implement NVGPU_GPU_IOCTL_GET_BUFFER_INFO Implement NVGPU_GPU_IOCTL_GET_BUFFER_INFO. The new IOCTL can be used to identify buffers and retrieve their sizes. This allows the userspace to be agnostic to the dmabuf implementation, as the generic dmabuf fd interface does not have a reliable way for buffer identification. Bug 1614735 Bug 1623949 Bug 1660392 Change-Id: Ic3dd0a9385c9852778110ccb80636dd6f4f36208 Signed-off-by: Sami Kiminki Reviewed-on: http://git-master/r/822845 Reviewed-on: http://git-master/r/833252 Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 1bc35597..141a37af 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -120,6 +120,8 @@ struct gk20a_dmabuf_priv { int pin_count; struct list_head states; + + u64 buffer_id; }; static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); @@ -3044,6 +3046,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) { struct gk20a_dmabuf_priv *priv; static DEFINE_MUTEX(priv_lock); + static u64 priv_count = 0; priv = dma_buf_get_drvdata(dmabuf, dev); if (likely(priv)) @@ -3060,6 +3063,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) } mutex_init(&priv->lock); INIT_LIST_HEAD(&priv->states); + priv->buffer_id = ++priv_count; dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv); priv_exist_or_err: mutex_unlock(&priv_lock); @@ -3145,8 +3149,11 @@ int gk20a_vm_map_buffer(struct vm_gk20a *vm, /* get ref to the mem handle (released on unmap_locked) */ dmabuf = dma_buf_get(dmabuf_fd); - if (IS_ERR(dmabuf)) + if (IS_ERR(dmabuf)) { + dev_warn(dev_from_vm(vm), "%s: fd %d is not a dmabuf", + __func__, dmabuf_fd); return PTR_ERR(dmabuf); + } err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm)); if (err) { @@ -3653,6 +3660,37 @@ const struct gk20a_mmu_level *gk20a_mm_get_mmu_levels(struct gk20a *g, gk20a_mm_levels_64k : gk20a_mm_levels_128k; } +int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, + u64 *buffer_id, u64 *buffer_len) +{ + struct dma_buf *dmabuf; + struct gk20a_dmabuf_priv *priv; + int err = 0; + + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) { + dev_warn(dev, "%s: fd %d is not a dmabuf", __func__, dmabuf_fd); + return PTR_ERR(dmabuf); + } + + err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev); + if (err) { + dev_warn(dev, "Failed to allocate dmabuf drvdata (err = %d)", + err); + goto clean_up; + } + + priv = dma_buf_get_drvdata(dmabuf, dev); + if (likely(priv)) { + *buffer_id = priv->buffer_id; + *buffer_len = dmabuf->size; + } + +clean_up: + dma_buf_put(dmabuf); + return err; +} + void gk20a_init_mm(struct gpu_ops *gops) { gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled; -- cgit v1.2.2