From 6602ffb84949779fd5d27399ca5f608a409a2a83 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 28 Aug 2014 11:07:30 +0200 Subject: [PATCH] drm/exynos/ipp: free partially allocated resources on error In case of allocation errors some already allocated buffers were not freed. The patch fixes it. Signed-off-by: Andrzej Hajda Reviewed-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 67 ++++++++++++------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 060a198da771..ab7b74cd4daa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -599,6 +599,35 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, return ret; } +static int ipp_put_mem_node(struct drm_device *drm_dev, + struct drm_exynos_ipp_cmd_node *c_node, + struct drm_exynos_ipp_mem_node *m_node) +{ + int i; + + DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node); + + if (!m_node) { + DRM_ERROR("invalid dequeue node.\n"); + return -EFAULT; + } + + DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); + + /* put gem buffer */ + for_each_ipp_planar(i) { + unsigned long handle = m_node->buf_info.handles[i]; + if (handle) + exynos_drm_gem_put_dma_addr(drm_dev, handle, + c_node->filp); + } + + list_del(&m_node->list); + kfree(m_node); + + return 0; +} + static struct drm_exynos_ipp_mem_node *ipp_get_mem_node(struct drm_device *drm_dev, struct drm_file *file, @@ -619,6 +648,7 @@ static struct drm_exynos_ipp_mem_node m_node->ops_id = qbuf->ops_id; m_node->prop_id = qbuf->prop_id; m_node->buf_id = qbuf->buf_id; + INIT_LIST_HEAD(&m_node->list); DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id); DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id); @@ -634,7 +664,8 @@ static struct drm_exynos_ipp_mem_node qbuf->handle[i], file); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); - goto err_clear; + ipp_put_mem_node(drm_dev, c_node, m_node); + return ERR_PTR(-EFAULT); } buf_info->handles[i] = qbuf->handle[i]; @@ -649,40 +680,6 @@ static struct drm_exynos_ipp_mem_node mutex_unlock(&c_node->mem_lock); return m_node; - -err_clear: - kfree(m_node); - return ERR_PTR(-EFAULT); -} - -static int ipp_put_mem_node(struct drm_device *drm_dev, - struct drm_exynos_ipp_cmd_node *c_node, - struct drm_exynos_ipp_mem_node *m_node) -{ - int i; - - DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node); - - if (!m_node) { - DRM_ERROR("invalid dequeue node.\n"); - return -EFAULT; - } - - DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); - - /* put gem buffer */ - for_each_ipp_planar(i) { - unsigned long handle = m_node->buf_info.handles[i]; - if (handle) - exynos_drm_gem_put_dma_addr(drm_dev, handle, - c_node->filp); - } - - /* delete list in queue */ - list_del(&m_node->list); - kfree(m_node); - - return 0; } static void ipp_free_event(struct drm_pending_event *event) -- 2.39.2