mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 09:06:44 +07:00
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>
This commit is contained in:
parent
ce92e3c961
commit
da34242e5e
@ -130,6 +130,21 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf,
|
|||||||
attach->priv = NULL;
|
attach->priv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drm_prime_remove_buf_handle_locked(
|
||||||
|
struct drm_prime_file_private *prime_fpriv,
|
||||||
|
struct dma_buf *dma_buf)
|
||||||
|
{
|
||||||
|
struct drm_prime_member *member, *safe;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
|
||||||
|
if (member->dma_buf == dma_buf) {
|
||||||
|
dma_buf_put(dma_buf);
|
||||||
|
list_del(&member->entry);
|
||||||
|
kfree(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
|
static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
|
||||||
enum dma_data_direction dir)
|
enum dma_data_direction dir)
|
||||||
{
|
{
|
||||||
@ -321,15 +336,25 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto fail_put_dmabuf;
|
goto fail_put_dmabuf;
|
||||||
|
|
||||||
*prime_fd = dma_buf_fd(buf, flags);
|
ret = dma_buf_fd(buf, flags);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail_rm_handle;
|
||||||
|
|
||||||
|
*prime_fd = ret;
|
||||||
mutex_unlock(&file_priv->prime.lock);
|
mutex_unlock(&file_priv->prime.lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_have_obj:
|
out_have_obj:
|
||||||
get_dma_buf(dmabuf);
|
get_dma_buf(dmabuf);
|
||||||
*prime_fd = dma_buf_fd(dmabuf, flags);
|
ret = dma_buf_fd(dmabuf, flags);
|
||||||
|
if (ret < 0)
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
else
|
||||||
|
*prime_fd = ret;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
fail_rm_handle:
|
||||||
|
drm_prime_remove_buf_handle_locked(&file_priv->prime, buf);
|
||||||
fail_put_dmabuf:
|
fail_put_dmabuf:
|
||||||
/* clear NOT to be checked when releasing dma_buf */
|
/* clear NOT to be checked when releasing dma_buf */
|
||||||
obj->export_dma_buf = NULL;
|
obj->export_dma_buf = NULL;
|
||||||
@ -600,16 +625,8 @@ EXPORT_SYMBOL(drm_prime_lookup_buf_handle);
|
|||||||
|
|
||||||
void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
|
void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
|
||||||
{
|
{
|
||||||
struct drm_prime_member *member, *safe;
|
|
||||||
|
|
||||||
mutex_lock(&prime_fpriv->lock);
|
mutex_lock(&prime_fpriv->lock);
|
||||||
list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
|
drm_prime_remove_buf_handle_locked(prime_fpriv, dma_buf);
|
||||||
if (member->dma_buf == dma_buf) {
|
|
||||||
dma_buf_put(dma_buf);
|
|
||||||
list_del(&member->entry);
|
|
||||||
kfree(member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&prime_fpriv->lock);
|
mutex_unlock(&prime_fpriv->lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_prime_remove_buf_handle);
|
EXPORT_SYMBOL(drm_prime_remove_buf_handle);
|
||||||
|
Loading…
Reference in New Issue
Block a user