Sometimes, an exported dma-buf is added to the import list. That messes up with trace point accounting, so track real vs. fake imports to correct this. Signed-off-by: Gurchetan Singh <gurchetansingh@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_gem.c | 5 ++++- drivers/gpu/drm/drm_internal.h | 4 ++-- drivers/gpu/drm/drm_prime.c | 18 +++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 6f70419f2c90..7637be0ceb74 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -226,8 +226,11 @@ drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) */ mutex_lock(&filp->prime.lock); if (obj->dma_buf) { + struct drm_device *dev = filp->minor->dev; + bool removed_real_import = false; drm_prime_remove_buf_handle_locked(&filp->prime, - obj->dma_buf); + obj->dma_buf, + &removed_real_import); } mutex_unlock(&filp->prime.lock); } diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 17f3548c8ed2..40d572e46e2a 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -75,8 +75,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf); - + struct dma_buf *dma_buf, + bool *removed_real_import); /* drm_drv.c */ struct drm_minor *drm_minor_acquire(unsigned int minor_id); void drm_minor_release(struct drm_minor *minor); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index deb23dbec8b5..31f033ec8549 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -90,13 +90,15 @@ struct drm_prime_member { struct dma_buf *dma_buf; uint32_t handle; + bool fake_import; struct rb_node dmabuf_rb; struct rb_node handle_rb; }; static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf, uint32_t handle) + struct dma_buf *dma_buf, uint32_t handle, + bool fake_import) { struct drm_prime_member *member; struct rb_node **p, *rb; @@ -108,6 +110,7 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, get_dma_buf(dma_buf); member->dma_buf = dma_buf; member->handle = handle; + member->fake_import = fake_import; rb = NULL; p = &prime_fpriv->dmabufs.rb_node; @@ -188,9 +191,11 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri } void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf) + struct dma_buf *dma_buf, + bool *removed_real_import) { struct rb_node *rb; + *removed_real_import = false; rb = prime_fpriv->dmabufs.rb_node; while (rb) { @@ -201,6 +206,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr rb_erase(&member->handle_rb, &prime_fpriv->handles); rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); + if (!member->fake_import) + *removed_real_import = true; + dma_buf_put(dma_buf); kfree(member); return; @@ -303,7 +311,6 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, return PTR_ERR(dma_buf); mutex_lock(&file_priv->prime.lock); - ret = drm_prime_lookup_buf_handle(&file_priv->prime, dma_buf, handle); if (ret == 0) @@ -315,6 +322,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, obj = dev->driver->gem_prime_import(dev, dma_buf); else obj = drm_gem_prime_import(dev, dma_buf); + if (IS_ERR(obj)) { ret = PTR_ERR(obj); goto out_unlock; @@ -334,7 +342,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, goto out_put; ret = drm_prime_add_buf_handle(&file_priv->prime, - dma_buf, *handle); + dma_buf, *handle, false); mutex_unlock(&file_priv->prime.lock); if (ret) goto fail; @@ -473,7 +481,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, * ioctl doesn't miss to remove this buffer handle from the cache. */ ret = drm_prime_add_buf_handle(&file_priv->prime, - dmabuf, handle); + dmabuf, handle, true); mutex_unlock(&dev->object_name_lock); if (ret) goto fail_put_dmabuf; -- 2.25.1