@@ -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);
}
@@ -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);
@@ -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;
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@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(-)