aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_prime.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_prime.c')
-rw-r--r--drivers/gpu/drm/drm_prime.c39
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
133static 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
133static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, 148static 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
328out_have_obj: 347out_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
356fail_rm_handle:
357 drm_prime_remove_buf_handle_locked(&file_priv->prime, buf);
333fail_put_dmabuf: 358fail_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
601void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) 626void 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}
615EXPORT_SYMBOL(drm_prime_remove_buf_handle); 632EXPORT_SYMBOL(drm_prime_remove_buf_handle);