diff options
author | Rob Clark <robdclark@gmail.com> | 2016-06-09 15:29:19 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-13 11:32:18 -0400 |
commit | bd6e2732f0e2894ce792f344c41fc32591436fe3 (patch) | |
tree | c2c0d81d7607979e05a7fa9cccc57dd88e3b2aba | |
parent | babb24fec12ce391157be8d7355df5a8e991355e (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.c | 10 |
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 | |||
618 | out_unlock: | 620 | out_unlock: |
619 | mutex_unlock(&dev->object_name_lock); | 621 | mutex_unlock(&dev->object_name_lock); |
620 | out_put: | 622 | out_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 | } |
625 | EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); | 627 | EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); |