aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2016-06-09 15:29:19 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-06-13 11:32:18 -0400
commitbd6e2732f0e2894ce792f344c41fc32591436fe3 (patch)
treec2c0d81d7607979e05a7fa9cccc57dd88e3b2aba
parentbabb24fec12ce391157be8d7355df5a8e991355e (diff)
drm/prime: fix error path deadlock fail
There were a couple messed up things about this fail path. (1) it would drop object_name_lock twice (2) drm_gem_handle_delete() (in drm_gem_remove_prime_handles()) needs to grab prime_lock Reported-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465500559-17873-1-git-send-email-robdclark@gmail.com
-rw-r--r--drivers/gpu/drm/drm_prime.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index aab0f3f1f42d..780589b420a4 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -593,7 +593,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
593 get_dma_buf(dma_buf); 593 get_dma_buf(dma_buf);
594 } 594 }
595 595
596 /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ 596 /* _handle_create_tail unconditionally unlocks dev->object_name_lock. */
597 ret = drm_gem_handle_create_tail(file_priv, obj, handle); 597 ret = drm_gem_handle_create_tail(file_priv, obj, handle);
598 drm_gem_object_unreference_unlocked(obj); 598 drm_gem_object_unreference_unlocked(obj);
599 if (ret) 599 if (ret)
@@ -601,11 +601,10 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
601 601
602 ret = drm_prime_add_buf_handle(&file_priv->prime, 602 ret = drm_prime_add_buf_handle(&file_priv->prime,
603 dma_buf, *handle); 603 dma_buf, *handle);
604 mutex_unlock(&file_priv->prime.lock);
604 if (ret) 605 if (ret)
605 goto fail; 606 goto fail;
606 607
607 mutex_unlock(&file_priv->prime.lock);
608
609 dma_buf_put(dma_buf); 608 dma_buf_put(dma_buf);
610 609
611 return 0; 610 return 0;
@@ -615,11 +614,14 @@ fail:
615 * to detach.. which seems ok.. 614 * to detach.. which seems ok..
616 */ 615 */
617 drm_gem_handle_delete(file_priv, *handle); 616 drm_gem_handle_delete(file_priv, *handle);
617 dma_buf_put(dma_buf);
618 return ret;
619
618out_unlock: 620out_unlock:
619 mutex_unlock(&dev->object_name_lock); 621 mutex_unlock(&dev->object_name_lock);
620out_put: 622out_put:
621 dma_buf_put(dma_buf);
622 mutex_unlock(&file_priv->prime.lock); 623 mutex_unlock(&file_priv->prime.lock);
624 dma_buf_put(dma_buf);
623 return ret; 625 return ret;
624} 626}
625EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); 627EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);