mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 05:01:48 +00:00
drm: prime: fix refcounting on the dmabuf import error path
In commit be8a42ae60
we inroduced a refcount problem, where on the
drm_gem_prime_fd_to_handle() error path we'll call dma_buf_put() for
self imported dma buffers.
Fix this by taking a reference on the dma buffer in the .gem_import
hook instead of assuming the caller had taken one. Besides fixing the
bug this is also more logical.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Cc: stable@vger.kernel.org
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
219b47339c
commit
011c2282c7
@ -271,7 +271,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
|
|||||||
* refcount on gem itself instead of f_count of dmabuf.
|
* refcount on gem itself instead of f_count of dmabuf.
|
||||||
*/
|
*/
|
||||||
drm_gem_object_reference(obj);
|
drm_gem_object_reference(obj);
|
||||||
dma_buf_put(dma_buf);
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,6 +279,8 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
|
|||||||
if (IS_ERR(attach))
|
if (IS_ERR(attach))
|
||||||
return ERR_PTR(PTR_ERR(attach));
|
return ERR_PTR(PTR_ERR(attach));
|
||||||
|
|
||||||
|
get_dma_buf(dma_buf);
|
||||||
|
|
||||||
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||||
if (IS_ERR_OR_NULL(sgt)) {
|
if (IS_ERR_OR_NULL(sgt)) {
|
||||||
ret = PTR_ERR(sgt);
|
ret = PTR_ERR(sgt);
|
||||||
@ -300,6 +301,8 @@ fail_unmap:
|
|||||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||||
fail_detach:
|
fail_detach:
|
||||||
dma_buf_detach(dma_buf, attach);
|
dma_buf_detach(dma_buf, attach);
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_gem_prime_import);
|
EXPORT_SYMBOL(drm_gem_prime_import);
|
||||||
@ -342,6 +345,9 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
mutex_unlock(&file_priv->prime.lock);
|
mutex_unlock(&file_priv->prime.lock);
|
||||||
|
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -235,7 +235,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
|
|||||||
* refcount on gem itself instead of f_count of dmabuf.
|
* refcount on gem itself instead of f_count of dmabuf.
|
||||||
*/
|
*/
|
||||||
drm_gem_object_reference(obj);
|
drm_gem_object_reference(obj);
|
||||||
dma_buf_put(dma_buf);
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,6 +243,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
|
|||||||
if (IS_ERR(attach))
|
if (IS_ERR(attach))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
get_dma_buf(dma_buf);
|
||||||
|
|
||||||
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||||
if (IS_ERR_OR_NULL(sgt)) {
|
if (IS_ERR_OR_NULL(sgt)) {
|
||||||
@ -298,6 +298,8 @@ err_unmap_attach:
|
|||||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
||||||
err_buf_detach:
|
err_buf_detach:
|
||||||
dma_buf_detach(dma_buf, attach);
|
dma_buf_detach(dma_buf, attach);
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,6 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
|
|||||||
* refcount on gem itself instead of f_count of dmabuf.
|
* refcount on gem itself instead of f_count of dmabuf.
|
||||||
*/
|
*/
|
||||||
drm_gem_object_reference(&obj->base);
|
drm_gem_object_reference(&obj->base);
|
||||||
dma_buf_put(dma_buf);
|
|
||||||
return &obj->base;
|
return &obj->base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,6 +281,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
|
|||||||
if (IS_ERR(attach))
|
if (IS_ERR(attach))
|
||||||
return ERR_CAST(attach);
|
return ERR_CAST(attach);
|
||||||
|
|
||||||
|
get_dma_buf(dma_buf);
|
||||||
|
|
||||||
obj = i915_gem_object_alloc(dev);
|
obj = i915_gem_object_alloc(dev);
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@ -301,5 +302,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
|
|||||||
|
|
||||||
fail_detach:
|
fail_detach:
|
||||||
dma_buf_detach(dma_buf, attach);
|
dma_buf_detach(dma_buf, attach);
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,6 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
|
|||||||
* refcount on gem itself instead of f_count of dmabuf.
|
* refcount on gem itself instead of f_count of dmabuf.
|
||||||
*/
|
*/
|
||||||
drm_gem_object_reference(obj);
|
drm_gem_object_reference(obj);
|
||||||
dma_buf_put(buffer);
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,8 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev,
|
|||||||
if (IS_ERR(attach))
|
if (IS_ERR(attach))
|
||||||
return ERR_CAST(attach);
|
return ERR_CAST(attach);
|
||||||
|
|
||||||
|
get_dma_buf(dma_buf);
|
||||||
|
|
||||||
sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||||
if (IS_ERR(sg)) {
|
if (IS_ERR(sg)) {
|
||||||
ret = PTR_ERR(sg);
|
ret = PTR_ERR(sg);
|
||||||
@ -322,5 +324,7 @@ fail_unmap:
|
|||||||
dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
|
dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
|
||||||
fail_detach:
|
fail_detach:
|
||||||
dma_buf_detach(dma_buf, attach);
|
dma_buf_detach(dma_buf, attach);
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user