diff options
author | Sami Kiminki <skiminki@nvidia.com> | 2015-10-26 13:23:54 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-11-17 15:38:44 -0500 |
commit | 30632cec54048944ee364781b4b8c2676ae5dfed (patch) | |
tree | 2d58fe57b8f80eb747aa1f8e3923f982870a9a16 /drivers/gpu | |
parent | 5a24e95fe605a2e7ec4d1a126c9bffd64bd77590 (diff) |
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 <skiminki@nvidia.com>
Reviewed-on: http://git-master/r/822845
Reviewed-on: http://git-master/r/833252
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 3 |
3 files changed, 53 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index 3b5ca298..0b6b5913 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -514,6 +514,13 @@ static int gk20a_ctrl_vsm_mapping(struct gk20a *g, | |||
514 | return err; | 514 | return err; |
515 | } | 515 | } |
516 | 516 | ||
517 | static int gk20a_ctrl_get_buffer_info( | ||
518 | struct gk20a *g, struct nvgpu_gpu_get_buffer_info_args *args) | ||
519 | { | ||
520 | return gk20a_mm_get_buffer_info(dev_from_gk20a(g), args->in.dmabuf_fd, | ||
521 | &args->out.id, &args->out.length); | ||
522 | } | ||
523 | |||
517 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 524 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
518 | { | 525 | { |
519 | struct platform_device *dev = filp->private_data; | 526 | struct platform_device *dev = filp->private_data; |
@@ -729,6 +736,10 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg | |||
729 | (struct nvgpu_gpu_vsms_mapping *)buf); | 736 | (struct nvgpu_gpu_vsms_mapping *)buf); |
730 | break; | 737 | break; |
731 | 738 | ||
739 | case NVGPU_GPU_IOCTL_GET_BUFFER_INFO: | ||
740 | err = gk20a_ctrl_get_buffer_info(g, | ||
741 | (struct nvgpu_gpu_get_buffer_info_args *)buf); | ||
742 | break; | ||
732 | 743 | ||
733 | default: | 744 | default: |
734 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); | 745 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); |
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 { | |||
120 | int pin_count; | 120 | int pin_count; |
121 | 121 | ||
122 | struct list_head states; | 122 | struct list_head states; |
123 | |||
124 | u64 buffer_id; | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); | 127 | 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) | |||
3044 | { | 3046 | { |
3045 | struct gk20a_dmabuf_priv *priv; | 3047 | struct gk20a_dmabuf_priv *priv; |
3046 | static DEFINE_MUTEX(priv_lock); | 3048 | static DEFINE_MUTEX(priv_lock); |
3049 | static u64 priv_count = 0; | ||
3047 | 3050 | ||
3048 | priv = dma_buf_get_drvdata(dmabuf, dev); | 3051 | priv = dma_buf_get_drvdata(dmabuf, dev); |
3049 | if (likely(priv)) | 3052 | if (likely(priv)) |
@@ -3060,6 +3063,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) | |||
3060 | } | 3063 | } |
3061 | mutex_init(&priv->lock); | 3064 | mutex_init(&priv->lock); |
3062 | INIT_LIST_HEAD(&priv->states); | 3065 | INIT_LIST_HEAD(&priv->states); |
3066 | priv->buffer_id = ++priv_count; | ||
3063 | dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv); | 3067 | dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv); |
3064 | priv_exist_or_err: | 3068 | priv_exist_or_err: |
3065 | mutex_unlock(&priv_lock); | 3069 | mutex_unlock(&priv_lock); |
@@ -3145,8 +3149,11 @@ int gk20a_vm_map_buffer(struct vm_gk20a *vm, | |||
3145 | 3149 | ||
3146 | /* get ref to the mem handle (released on unmap_locked) */ | 3150 | /* get ref to the mem handle (released on unmap_locked) */ |
3147 | dmabuf = dma_buf_get(dmabuf_fd); | 3151 | dmabuf = dma_buf_get(dmabuf_fd); |
3148 | if (IS_ERR(dmabuf)) | 3152 | if (IS_ERR(dmabuf)) { |
3153 | dev_warn(dev_from_vm(vm), "%s: fd %d is not a dmabuf", | ||
3154 | __func__, dmabuf_fd); | ||
3149 | return PTR_ERR(dmabuf); | 3155 | return PTR_ERR(dmabuf); |
3156 | } | ||
3150 | 3157 | ||
3151 | err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm)); | 3158 | err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm)); |
3152 | if (err) { | 3159 | if (err) { |
@@ -3653,6 +3660,37 @@ const struct gk20a_mmu_level *gk20a_mm_get_mmu_levels(struct gk20a *g, | |||
3653 | gk20a_mm_levels_64k : gk20a_mm_levels_128k; | 3660 | gk20a_mm_levels_64k : gk20a_mm_levels_128k; |
3654 | } | 3661 | } |
3655 | 3662 | ||
3663 | int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, | ||
3664 | u64 *buffer_id, u64 *buffer_len) | ||
3665 | { | ||
3666 | struct dma_buf *dmabuf; | ||
3667 | struct gk20a_dmabuf_priv *priv; | ||
3668 | int err = 0; | ||
3669 | |||
3670 | dmabuf = dma_buf_get(dmabuf_fd); | ||
3671 | if (IS_ERR(dmabuf)) { | ||
3672 | dev_warn(dev, "%s: fd %d is not a dmabuf", __func__, dmabuf_fd); | ||
3673 | return PTR_ERR(dmabuf); | ||
3674 | } | ||
3675 | |||
3676 | err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev); | ||
3677 | if (err) { | ||
3678 | dev_warn(dev, "Failed to allocate dmabuf drvdata (err = %d)", | ||
3679 | err); | ||
3680 | goto clean_up; | ||
3681 | } | ||
3682 | |||
3683 | priv = dma_buf_get_drvdata(dmabuf, dev); | ||
3684 | if (likely(priv)) { | ||
3685 | *buffer_id = priv->buffer_id; | ||
3686 | *buffer_len = dmabuf->size; | ||
3687 | } | ||
3688 | |||
3689 | clean_up: | ||
3690 | dma_buf_put(dmabuf); | ||
3691 | return err; | ||
3692 | } | ||
3693 | |||
3656 | void gk20a_init_mm(struct gpu_ops *gops) | 3694 | void gk20a_init_mm(struct gpu_ops *gops) |
3657 | { | 3695 | { |
3658 | gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled; | 3696 | gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled; |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 7bbaf283..7be4383b 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -688,4 +688,7 @@ static inline void nvgpu_free(void *p) | |||
688 | vfree(p); | 688 | vfree(p); |
689 | } | 689 | } |
690 | 690 | ||
691 | int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, | ||
692 | u64 *buffer_id, u64 *buffer_len); | ||
693 | |||
691 | #endif /* MM_GK20A_H */ | 694 | #endif /* MM_GK20A_H */ |