aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2013-04-18 21:11:56 -0400
committerDave Airlie <airlied@redhat.com>2013-04-30 19:40:21 -0400
commit011c2282c74db120f01a8414edc66c3f217f5511 (patch)
tree5e43eb6b5d21e8aa29e88f0398fcdd7ca55abdb5
parent219b47339ced80ca580bb6ce7d1636166984afa7 (diff)
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>
-rw-r--r--drivers/gpu/drm/drm_prime.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c1
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c4
5 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 7830d8e1f212..71c7315ca00f 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -271,7 +271,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
271 * refcount on gem itself instead of f_count of dmabuf. 271 * refcount on gem itself instead of f_count of dmabuf.
272 */ 272 */
273 drm_gem_object_reference(obj); 273 drm_gem_object_reference(obj);
274 dma_buf_put(dma_buf);
275 return obj; 274 return obj;
276 } 275 }
277 } 276 }
@@ -280,6 +279,8 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
280 if (IS_ERR(attach)) 279 if (IS_ERR(attach))
281 return ERR_PTR(PTR_ERR(attach)); 280 return ERR_PTR(PTR_ERR(attach));
282 281
282 get_dma_buf(dma_buf);
283
283 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); 284 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
284 if (IS_ERR_OR_NULL(sgt)) { 285 if (IS_ERR_OR_NULL(sgt)) {
285 ret = PTR_ERR(sgt); 286 ret = PTR_ERR(sgt);
@@ -300,6 +301,8 @@ fail_unmap:
300 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); 301 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
301fail_detach: 302fail_detach:
302 dma_buf_detach(dma_buf, attach); 303 dma_buf_detach(dma_buf, attach);
304 dma_buf_put(dma_buf);
305
303 return ERR_PTR(ret); 306 return ERR_PTR(ret);
304} 307}
305EXPORT_SYMBOL(drm_gem_prime_import); 308EXPORT_SYMBOL(drm_gem_prime_import);
@@ -342,6 +345,9 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
342 goto fail; 345 goto fail;
343 346
344 mutex_unlock(&file_priv->prime.lock); 347 mutex_unlock(&file_priv->prime.lock);
348
349 dma_buf_put(dma_buf);
350
345 return 0; 351 return 0;
346 352
347fail: 353fail:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index ba0a3aa78547..ff7f2a886a34 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -235,7 +235,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
235 * refcount on gem itself instead of f_count of dmabuf. 235 * refcount on gem itself instead of f_count of dmabuf.
236 */ 236 */
237 drm_gem_object_reference(obj); 237 drm_gem_object_reference(obj);
238 dma_buf_put(dma_buf);
239 return obj; 238 return obj;
240 } 239 }
241 } 240 }
@@ -244,6 +243,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
244 if (IS_ERR(attach)) 243 if (IS_ERR(attach))
245 return ERR_PTR(-EINVAL); 244 return ERR_PTR(-EINVAL);
246 245
246 get_dma_buf(dma_buf);
247 247
248 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); 248 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
249 if (IS_ERR_OR_NULL(sgt)) { 249 if (IS_ERR_OR_NULL(sgt)) {
@@ -298,6 +298,8 @@ err_unmap_attach:
298 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); 298 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
299err_buf_detach: 299err_buf_detach:
300 dma_buf_detach(dma_buf, attach); 300 dma_buf_detach(dma_buf, attach);
301 dma_buf_put(dma_buf);
302
301 return ERR_PTR(ret); 303 return ERR_PTR(ret);
302} 304}
303 305
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index c6dfc1466e3a..30485e9efcb7 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -272,7 +272,6 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
272 * refcount on gem itself instead of f_count of dmabuf. 272 * refcount on gem itself instead of f_count of dmabuf.
273 */ 273 */
274 drm_gem_object_reference(&obj->base); 274 drm_gem_object_reference(&obj->base);
275 dma_buf_put(dma_buf);
276 return &obj->base; 275 return &obj->base;
277 } 276 }
278 } 277 }
@@ -282,6 +281,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
282 if (IS_ERR(attach)) 281 if (IS_ERR(attach))
283 return ERR_CAST(attach); 282 return ERR_CAST(attach);
284 283
284 get_dma_buf(dma_buf);
285
285 obj = i915_gem_object_alloc(dev); 286 obj = i915_gem_object_alloc(dev);
286 if (obj == NULL) { 287 if (obj == NULL) {
287 ret = -ENOMEM; 288 ret = -ENOMEM;
@@ -301,5 +302,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
301 302
302fail_detach: 303fail_detach:
303 dma_buf_detach(dma_buf, attach); 304 dma_buf_detach(dma_buf, attach);
305 dma_buf_put(dma_buf);
306
304 return ERR_PTR(ret); 307 return ERR_PTR(ret);
305} 308}
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 0682cb5c0150..be7cd97a0db0 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -212,7 +212,6 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
212 * refcount on gem itself instead of f_count of dmabuf. 212 * refcount on gem itself instead of f_count of dmabuf.
213 */ 213 */
214 drm_gem_object_reference(obj); 214 drm_gem_object_reference(obj);
215 dma_buf_put(buffer);
216 return obj; 215 return obj;
217 } 216 }
218 } 217 }
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index 3816270ba49b..ef034fa3e6f5 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -303,6 +303,8 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev,
303 if (IS_ERR(attach)) 303 if (IS_ERR(attach))
304 return ERR_CAST(attach); 304 return ERR_CAST(attach);
305 305
306 get_dma_buf(dma_buf);
307
306 sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); 308 sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
307 if (IS_ERR(sg)) { 309 if (IS_ERR(sg)) {
308 ret = PTR_ERR(sg); 310 ret = PTR_ERR(sg);
@@ -322,5 +324,7 @@ fail_unmap:
322 dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); 324 dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
323fail_detach: 325fail_detach:
324 dma_buf_detach(dma_buf, attach); 326 dma_buf_detach(dma_buf, attach);
327 dma_buf_put(dma_buf);
328
325 return ERR_PTR(ret); 329 return ERR_PTR(ret);
326} 330}