diff options
author | YoungJun Cho <yj44.cho@samsung.com> | 2013-06-25 21:21:42 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-06-28 00:43:04 -0400 |
commit | da34242e5e0638312130f5bd5d2d277afbc6f806 (patch) | |
tree | be64bc9ae3fd2bd4272fcaee06eeac33a041c1ee /drivers/gpu/drm/drm_prime.c | |
parent | ce92e3c9613b51adccaf4d3c04eef53aee981e10 (diff) |
drm/prime: add return check for dma_buf_fd
The dma_buf_fd() can return error when it fails to prepare fd,
so the dma_buf needs to be put.
Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_prime.c')
-rw-r--r-- | drivers/gpu/drm/drm_prime.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 117ffe32a7af..52709f2171fb 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
@@ -130,6 +130,21 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, | |||
130 | attach->priv = NULL; | 130 | attach->priv = NULL; |
131 | } | 131 | } |
132 | 132 | ||
133 | static void drm_prime_remove_buf_handle_locked( | ||
134 | struct drm_prime_file_private *prime_fpriv, | ||
135 | struct dma_buf *dma_buf) | ||
136 | { | ||
137 | struct drm_prime_member *member, *safe; | ||
138 | |||
139 | list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { | ||
140 | if (member->dma_buf == dma_buf) { | ||
141 | dma_buf_put(dma_buf); | ||
142 | list_del(&member->entry); | ||
143 | kfree(member); | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
133 | static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, | 148 | static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, |
134 | enum dma_data_direction dir) | 149 | enum dma_data_direction dir) |
135 | { | 150 | { |
@@ -321,15 +336,25 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, | |||
321 | if (ret) | 336 | if (ret) |
322 | goto fail_put_dmabuf; | 337 | goto fail_put_dmabuf; |
323 | 338 | ||
324 | *prime_fd = dma_buf_fd(buf, flags); | 339 | ret = dma_buf_fd(buf, flags); |
340 | if (ret < 0) | ||
341 | goto fail_rm_handle; | ||
342 | |||
343 | *prime_fd = ret; | ||
325 | mutex_unlock(&file_priv->prime.lock); | 344 | mutex_unlock(&file_priv->prime.lock); |
326 | return 0; | 345 | return 0; |
327 | 346 | ||
328 | out_have_obj: | 347 | out_have_obj: |
329 | get_dma_buf(dmabuf); | 348 | get_dma_buf(dmabuf); |
330 | *prime_fd = dma_buf_fd(dmabuf, flags); | 349 | ret = dma_buf_fd(dmabuf, flags); |
350 | if (ret < 0) | ||
351 | dma_buf_put(dmabuf); | ||
352 | else | ||
353 | *prime_fd = ret; | ||
331 | goto out; | 354 | goto out; |
332 | 355 | ||
356 | fail_rm_handle: | ||
357 | drm_prime_remove_buf_handle_locked(&file_priv->prime, buf); | ||
333 | fail_put_dmabuf: | 358 | fail_put_dmabuf: |
334 | /* clear NOT to be checked when releasing dma_buf */ | 359 | /* clear NOT to be checked when releasing dma_buf */ |
335 | obj->export_dma_buf = NULL; | 360 | obj->export_dma_buf = NULL; |
@@ -600,16 +625,8 @@ EXPORT_SYMBOL(drm_prime_lookup_buf_handle); | |||
600 | 625 | ||
601 | void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) | 626 | void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) |
602 | { | 627 | { |
603 | struct drm_prime_member *member, *safe; | ||
604 | |||
605 | mutex_lock(&prime_fpriv->lock); | 628 | mutex_lock(&prime_fpriv->lock); |
606 | list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { | 629 | drm_prime_remove_buf_handle_locked(prime_fpriv, dma_buf); |
607 | if (member->dma_buf == dma_buf) { | ||
608 | dma_buf_put(dma_buf); | ||
609 | list_del(&member->entry); | ||
610 | kfree(member); | ||
611 | } | ||
612 | } | ||
613 | mutex_unlock(&prime_fpriv->lock); | 630 | mutex_unlock(&prime_fpriv->lock); |
614 | } | 631 | } |
615 | EXPORT_SYMBOL(drm_prime_remove_buf_handle); | 632 | EXPORT_SYMBOL(drm_prime_remove_buf_handle); |