From patchwork Thu May 29 02:49:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YoungJun Cho X-Patchwork-Id: 4258581 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7AABDBF90B for ; Thu, 29 May 2014 02:49:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 684E320279 for ; Thu, 29 May 2014 02:49:27 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id EC27E20340 for ; Thu, 29 May 2014 02:49:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EFFBD6E95D; Wed, 28 May 2014 19:49:19 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) by gabe.freedesktop.org (Postfix) with ESMTP id 9DC496E2D1 for ; Wed, 28 May 2014 19:49:17 -0700 (PDT) Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N6B00J6MEI4O930@mailout4.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 29 May 2014 11:49:16 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.46]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id 20.C3.16580.C20A6835; Thu, 29 May 2014 11:49:16 +0900 (KST) X-AuditID: cbfee691-b7f2f6d0000040c4-3b-5386a02c2fcd Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 39.89.07139.C20A6835; Thu, 29 May 2014 11:49:16 +0900 (KST) Received: from localhost.localdomain ([10.252.75.90]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N6B000AMEI0TZ00@mmp1.samsung.com>; Thu, 29 May 2014 11:49:15 +0900 (KST) From: YoungJun Cho To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH 6/8] drm/exynos: ipp: rearrange c_node->mem_lock using routines Date: Thu, 29 May 2014 11:49:10 +0900 Message-id: <1401331752-15417-7-git-send-email-yj44.cho@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1401331752-15417-1-git-send-email-yj44.cho@samsung.com> References: <1401331752-15417-1-git-send-email-yj44.cho@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrDLMWRmVeSWpSXmKPExsVy+t8zPV2dBW3BBisniFjcWneO1aL33Ekm iytf37NZTLo/gcXixb2LLBZnm96wW8yY/JLNgd1j+7cHrB73u48zefRtWcUYwBzFZZOSmpNZ llqkb5fAlTH5xX3GgjluFbOv72NuYPxh3sXIySEhYCLR/OEZC4QtJnHh3nq2LkYuDiGBZYwS 877OYoYpOrh3BlRiEaPE3Av/GCGcViaJxTsvsoJUsQloSjz/uAPMFhEwleiYtBRsLLNAtcTi iXOZQGxhAX+JB7cOgk1lEVCV6L0/iQ3E5hVwkdi7ZwpQDQfQNgWJOZNsQExOAVeJr1+dQSqE gCpufVrLDLJWQqCfXWLZzS8sEGMEJL5NPsQC0SorsekA1M2SEgdX3GCZwCi8gJFhFaNoakFy QXFSepGpXnFibnFpXrpecn7uJkZISE/cwXj/gPUhxmSgcROZpUST84ExkVcSb2hsZmRhamJq bGRuaUaasJI4b/qjpCAhgfTEktTs1NSC1KL4otKc1OJDjEwcnFINjCV6WbNWzkmR46t+dvZC razwxNBF0rvkc6wa+M5dUn8UtUPqFcvjWenvkyqX2iUUXq2K8X7+/FdO4XZdDXel5lDL9ZL7 Tm+K6D8xJdnjjtgM5g/P8xkNmTsrHtyO9PsTMeug3aJeHW6PjxOLY+NVI8MTlrb633PMKItq ELmxQju0cq67YMp5JZbijERDLeai4kQA7BhvkX8CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJIsWRmVeSWpSXmKPExsVy+t9jAV2dBW3BBlcf8VncWneO1aL33Ekm iytf37NZTLo/gcXixb2LLBZnm96wW8yY/JLNgd1j+7cHrB73u48zefRtWcUYwBzVwGiTkZqY klqkkJqXnJ+SmZduq+QdHO8cb2pmYKhraGlhrqSQl5ibaqvk4hOg65aZA7ReSaEsMacUKBSQ WFyspG+HaUJoiJuuBUxjhK5vSBBcj5EBGkhYx5gx+cV9xoI5bhWzr+9jbmD8Yd7FyMkhIWAi cXDvDDYIW0ziwr31QDYXh5DAIkaJuRf+MUI4rUwSi3deZAWpYhPQlHj+cQeYLSJgKtExaSkL iM0sUC2xeOJcJhBbWMBf4sGtg8wgNouAqkTv/UlgG3gFXCT27pkCVMMBtE1BYs4kGxCTU8BV 4utXZ5AKIaCKW5/WMk9g5F3AyLCKUTS1ILmgOCk910ivODG3uDQvXS85P3cTIzhinknvYFzV YHGIUYCDUYmHV0K2LViINbGsuDL3EKMEB7OSCK9GOFCINyWxsiq1KD++qDQntfgQYzLQTROZ pUST84HRnFcSb2hsYmZkaWRmbGJubEyasJI478FW60AhgfTEktTs1NSC1CKYLUwcnFINjCy7 lnj7Cv86envT/BXHZx6aK3chtehze8GzXtuHO8Lk7nF8/qUstiL087J7HVZvO3YUyfAFOH1w Fv/xgD1t18Mi96Pb3uetSf1yatlX2aeLLht/rs6XLip9NFUwdZKm4EZJu0kZN5wPuXL+4s/a ZDo/99ykYuls57d37CRKZXOmLVX4vLX8zBIlluKMREMt5qLiRADWUIJx3AIAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Cc: a.hajda@samsung.com, kyungmin.park@samsung.com, sw0312.kim@samsung.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The c_node->mem_list[] should be protected with c_node->mem_lock. Signed-off-by: YoungJun Cho Reviewed-by: Seong-Woo Kim Reviewed-by: Andrzej Hajda Acked-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 86 +++++++++++++++++-------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index cebd6b6..92350ba 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -583,8 +583,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node) struct list_head *head; int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, }; - mutex_lock(&c_node->mem_lock); - for_each_ipp_ops(i) { /* source/destination memory list */ head = &c_node->mem_list[i]; @@ -613,8 +611,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node) ret = max(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]); - mutex_unlock(&c_node->mem_lock); - return ret; } @@ -657,16 +653,13 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, return -EFAULT; } - mutex_lock(&c_node->mem_lock); - DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); /* get operations callback */ ops = ippdrv->ops[m_node->ops_id]; if (!ops) { DRM_ERROR("not support ops.\n"); - ret = -EFAULT; - goto err_unlock; + return -EFAULT; } /* set address and enable irq */ @@ -675,12 +668,10 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, m_node->buf_id, IPP_BUF_ENQUEUE); if (ret) { DRM_ERROR("failed to set addr.\n"); - goto err_unlock; + return ret; } } -err_unlock: - mutex_unlock(&c_node->mem_lock); return ret; } @@ -695,11 +686,9 @@ static struct drm_exynos_ipp_mem_node void *addr; int i; - mutex_lock(&c_node->mem_lock); - m_node = kzalloc(sizeof(*m_node), GFP_KERNEL); if (!m_node) - goto err_unlock; + return ERR_PTR(-ENOMEM); /* clear base address for error handling */ memset(&buf_info, 0x0, sizeof(buf_info)); @@ -733,15 +722,14 @@ static struct drm_exynos_ipp_mem_node m_node->filp = file; m_node->buf_info = buf_info; + mutex_lock(&c_node->mem_lock); list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]); - mutex_unlock(&c_node->mem_lock); + return m_node; err_clear: kfree(m_node); -err_unlock: - mutex_unlock(&c_node->mem_lock); return ERR_PTR(-EFAULT); } @@ -758,13 +746,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev, return -EFAULT; } - if (list_empty(&m_node->list)) { - DRM_ERROR("empty memory node.\n"); - return -ENOMEM; - } - - mutex_lock(&c_node->mem_lock); - DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); /* put gem buffer */ @@ -779,8 +760,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev, list_del(&m_node->list); kfree(m_node); - mutex_unlock(&c_node->mem_lock); - return 0; } @@ -893,7 +872,9 @@ static int ipp_queue_buf_with_run(struct device *dev, return 0; } + mutex_lock(&c_node->mem_lock); if (!ipp_check_mem_list(c_node)) { + mutex_unlock(&c_node->mem_lock); DRM_DEBUG_KMS("empty memory.\n"); return 0; } @@ -910,10 +891,12 @@ static int ipp_queue_buf_with_run(struct device *dev, } else { ret = ipp_set_mem_node(ippdrv, c_node, m_node); if (ret) { + mutex_unlock(&c_node->mem_lock); DRM_ERROR("failed to set m node.\n"); return ret; } } + mutex_unlock(&c_node->mem_lock); return 0; } @@ -925,12 +908,14 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev, struct drm_exynos_ipp_mem_node *m_node, *tm_node; /* delete list */ + mutex_lock(&c_node->mem_lock); list_for_each_entry_safe(m_node, tm_node, &c_node->mem_list[qbuf->ops_id], list) { if (m_node->buf_id == qbuf->buf_id && m_node->ops_id == qbuf->ops_id) ipp_put_mem_node(drm_dev, c_node, m_node); } + mutex_unlock(&c_node->mem_lock); } int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, @@ -1266,9 +1251,11 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, /* store command info in ippdrv */ ippdrv->c_node = c_node; + mutex_lock(&c_node->mem_lock); if (!ipp_check_mem_list(c_node)) { DRM_DEBUG_KMS("empty memory.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_unlock; } /* set current property in ippdrv */ @@ -1276,7 +1263,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, if (ret) { DRM_ERROR("failed to set property.\n"); ippdrv->c_node = NULL; - return ret; + goto err_unlock; } /* check command */ @@ -1291,7 +1278,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, if (!m_node) { DRM_ERROR("failed to get node.\n"); ret = -EFAULT; - return ret; + goto err_unlock; } DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node); @@ -1299,7 +1286,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ret = ipp_set_mem_node(ippdrv, c_node, m_node); if (ret) { DRM_ERROR("failed to set m node.\n"); - return ret; + goto err_unlock; } } break; @@ -1311,7 +1298,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ret = ipp_set_mem_node(ippdrv, c_node, m_node); if (ret) { DRM_ERROR("failed to set m node.\n"); - return ret; + goto err_unlock; } } break; @@ -1323,14 +1310,16 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ret = ipp_set_mem_node(ippdrv, c_node, m_node); if (ret) { DRM_ERROR("failed to set m node.\n"); - return ret; + goto err_unlock; } } break; default: DRM_ERROR("invalid operations.\n"); - return -EINVAL; + ret = -EINVAL; + goto err_unlock; } + mutex_unlock(&c_node->mem_lock); DRM_DEBUG_KMS("cmd[%d]\n", property->cmd); @@ -1339,11 +1328,17 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ret = ippdrv->start(ippdrv->dev, property->cmd); if (ret) { DRM_ERROR("failed to start ops.\n"); + ippdrv->c_node = NULL; return ret; } } return 0; + +err_unlock: + mutex_unlock(&c_node->mem_lock); + ippdrv->c_node = NULL; + return ret; } static int ipp_stop_property(struct drm_device *drm_dev, @@ -1360,6 +1355,8 @@ static int ipp_stop_property(struct drm_device *drm_dev, /* put event */ ipp_put_event(c_node, NULL); + mutex_lock(&c_node->mem_lock); + /* check command */ switch (property->cmd) { case IPP_CMD_M2M: @@ -1409,6 +1406,8 @@ static int ipp_stop_property(struct drm_device *drm_dev, } err_clear: + mutex_unlock(&c_node->mem_lock); + /* stop operations */ if (ippdrv->stop) ippdrv->stop(ippdrv->dev, property->cmd); @@ -1520,9 +1519,11 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, return 0; } + mutex_lock(&c_node->mem_lock); if (!ipp_check_mem_list(c_node)) { DRM_DEBUG_KMS("empty memory.\n"); - return 0; + ret = 0; + goto err_mem_unlock; } /* check command */ @@ -1536,7 +1537,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_mem_node, list); if (!m_node) { DRM_ERROR("empty memory node.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_mem_unlock; } tbuf_id[i] = m_node->buf_id; @@ -1558,7 +1560,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, m_node = ipp_find_mem_node(c_node, &qbuf); if (!m_node) { DRM_ERROR("empty memory node.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_mem_unlock; } tbuf_id[EXYNOS_DRM_OPS_DST] = m_node->buf_id; @@ -1575,7 +1578,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_mem_node, list); if (!m_node) { DRM_ERROR("empty memory node.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_mem_unlock; } tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id; @@ -1586,8 +1590,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, break; default: DRM_ERROR("invalid operations.\n"); - return -EINVAL; + ret = -EINVAL; + goto err_mem_unlock; } + mutex_unlock(&c_node->mem_lock); if (tbuf_id[EXYNOS_DRM_OPS_DST] != buf_id[EXYNOS_DRM_OPS_DST]) DRM_ERROR("failed to match buf_id[%d %d]prop_id[%d]\n", @@ -1626,6 +1632,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]); return 0; + +err_mem_unlock: + mutex_unlock(&c_node->mem_lock); + return ret; } void ipp_sched_event(struct work_struct *work)