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 <gurchetansi...@chromium.org>
---
 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

Reply via email to