From patchwork Wed Feb 10 08:32:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guzman Lugo, Fernando" X-Patchwork-Id: 78299 X-Patchwork-Delegate: omar.ramirez@ti.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1A8X640014254 for ; Wed, 10 Feb 2010 08:33:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752586Ab0BJIdF (ORCPT ); Wed, 10 Feb 2010 03:33:05 -0500 Received: from devils.ext.ti.com ([198.47.26.153]:44614 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751849Ab0BJIdC convert rfc822-to-8bit (ORCPT ); Wed, 10 Feb 2010 03:33:02 -0500 Received: from dlep36.itg.ti.com ([157.170.170.91]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id o1A8X0Qp011242 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 10 Feb 2010 02:33:00 -0600 Received: from dlep26.itg.ti.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id o1A8X0ru007014; Wed, 10 Feb 2010 02:33:00 -0600 (CST) Received: from dsbe71.ent.ti.com (localhost [127.0.0.1]) by dlep26.itg.ti.com (8.13.8/8.13.8) with ESMTP id o1A8X02r019676; Wed, 10 Feb 2010 02:33:00 -0600 (CST) Received: from dlee06.ent.ti.com ([157.170.170.11]) by dsbe71.ent.ti.com ([156.117.232.23]) with mapi; Wed, 10 Feb 2010 02:33:00 -0600 From: "Guzman Lugo, Fernando" To: "linux-omap@vger.kernel.org" CC: Ameya Palande , Hiroshi Doyu , "felipe.contreras@nokia.com" Date: Wed, 10 Feb 2010 02:32:58 -0600 Subject: [RESEND] [PATCH] DSPBRIDGE: Adding protection Resource cleanup linked lists Thread-Topic: [RESEND] [PATCH] DSPBRIDGE: Adding protection Resource cleanup linked lists Thread-Index: AcqqK6Zu28xEu8fzS7GiMNHbzcdhvg== Message-ID: <496565EC904933469F292DDA3F1663E602AA725DC6@dlee06.ent.ti.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 10 Feb 2010 08:33:06 +0000 (UTC) diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-omap/include/dspbridge/drv.h index b6a5fd2..b044291 100644 --- a/arch/arm/plat-omap/include/dspbridge/drv.h +++ b/arch/arm/plat-omap/include/dspbridge/drv.h @@ -137,15 +137,18 @@ struct PROCESS_CONTEXT{ /* DSP Node resources */ struct NODE_RES_OBJECT *pNodeList; + struct mutex node_mutex; /* DMM resources */ struct DMM_RES_OBJECT *pDMMList; + struct mutex dmm_mutex; /* DSP Heap resources */ struct DSPHEAP_RES_OBJECT *pDSPHEAPList; /* Stream resources */ struct STRM_RES_OBJECT *pSTRMList; + struct mutex strm_mutex; } ; diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c index b086c0f..bd2bfa3 100644 --- a/drivers/dsp/bridge/pmgr/wcd.c +++ b/drivers/dsp/bridge/pmgr/wcd.c @@ -1121,17 +1121,23 @@ bool validate_node_handle(struct NODE_OBJECT *hNode, void *pr_ctxt) { bool retVal = false; struct PROCESS_CONTEXT *pCtxt = pr_ctxt; - struct NODE_RES_OBJECT *pNode = pCtxt->pNodeList; + struct NODE_RES_OBJECT *pNode; if (hNode == (struct NODE_OBJECT *) DSP_HGPPNODE) retVal = true; + if (mutex_lock_interruptible(&pCtxt->node_mutex)) + return DSP_EFAIL; + + pNode = pCtxt->pNodeList; while (pNode && !retVal) { if (hNode == pNode->hNode) retVal = true; pNode = pNode->next; } + mutex_unlock(&pCtxt->node_mutex); + return retVal; } @@ -1570,14 +1576,20 @@ bool validate_strm_handle(struct STRM_OBJECT *hStrm, void *pr_ctxt) { bool retVal = false; struct PROCESS_CONTEXT *pCtxt = pr_ctxt; - struct STRM_RES_OBJECT *pStrm = pCtxt->pSTRMList; + struct STRM_RES_OBJECT *pStrm; + if (mutex_lock_interruptible(&pCtxt->strm_mutex)) + return DSP_EFAIL; + + pStrm = pCtxt->pSTRMList; while (pStrm && !retVal) { if (hStrm == pStrm->hStream) retVal = true; pStrm = pStrm->next; } + mutex_unlock(&pCtxt->strm_mutex); + return retVal; } diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c index 36bab9f..e8b2c58 100644 --- a/drivers/dsp/bridge/rmgr/drv.c +++ b/drivers/dsp/bridge/rmgr/drv.c @@ -97,6 +97,10 @@ DSP_STATUS DRV_InsertNodeResElement(HANDLE hNode, HANDLE hNodeRes, status = DSP_EHANDLE; } if (DSP_SUCCEEDED(status)) { + if (mutex_lock_interruptible(&pCtxt->node_mutex)) { + kfree(*pNodeRes); + return DSP_EFAIL; + } (*pNodeRes)->hNode = hNode; if (pCtxt->pNodeList != NULL) { pTempNodeRes = pCtxt->pNodeList; @@ -111,6 +115,7 @@ DSP_STATUS DRV_InsertNodeResElement(HANDLE hNode, HANDLE hNodeRes, GT_0trace(curTrace, GT_ENTER, "DRV_InsertNodeResElement: 3"); } + mutex_unlock(&pCtxt->node_mutex); } GT_0trace(curTrace, GT_ENTER, "DRV_InsertNodeResElement: 4"); return status; @@ -123,7 +128,10 @@ DSP_STATUS DRV_RemoveNodeResElement(HANDLE hNodeRes, HANDLE hPCtxt) struct NODE_RES_OBJECT *pNodeRes = (struct NODE_RES_OBJECT *)hNodeRes; struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; struct NODE_RES_OBJECT *pTempNode; + DSP_STATUS status = DSP_SOK; + if (mutex_lock_interruptible(&pCtxt->node_mutex)) + return DSP_EFAIL; pTempNode = pCtxt->pNodeList; if (pTempNode == pNodeRes) { pCtxt->pNodeList = pNodeRes->next; @@ -131,11 +139,13 @@ DSP_STATUS DRV_RemoveNodeResElement(HANDLE hNodeRes, HANDLE hPCtxt) while (pTempNode && pTempNode->next != pNodeRes) pTempNode = pTempNode->next; if (!pTempNode) - return DSP_ENOTFOUND; - pTempNode->next = pNodeRes->next; + status = DSP_ENOTFOUND; + else + pTempNode->next = pNodeRes->next; } + mutex_unlock(&pCtxt->node_mutex); kfree(pNodeRes); - return DSP_SOK; + return status; } /* Actual Node De-Allocation */ @@ -200,6 +210,11 @@ DSP_STATUS DRV_InsertDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) status = DSP_EHANDLE; } if (DSP_SUCCEEDED(status)) { + if (mutex_lock_interruptible(&pCtxt->dmm_mutex)) { + kfree(*pDMMRes); + return DSP_EFAIL; + } + if (pCtxt->pDMMList != NULL) { GT_0trace(curTrace, GT_5CLASS, "DRV_InsertDMMResElement: 3"); @@ -213,6 +228,7 @@ DSP_STATUS DRV_InsertDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) GT_0trace(curTrace, GT_5CLASS, "DRV_InsertDMMResElement: 4"); } + mutex_unlock(&pCtxt->dmm_mutex); } GT_0trace(curTrace, GT_ENTER, "DRV_InsertDMMResElement: 5"); return status; @@ -225,7 +241,10 @@ DSP_STATUS DRV_RemoveDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; struct DMM_RES_OBJECT *pDMMRes = (struct DMM_RES_OBJECT *)hDMMRes; struct DMM_RES_OBJECT *pTempDMMRes = NULL; + DSP_STATUS status = DSP_SOK; + if (mutex_lock_interruptible(&pCtxt->dmm_mutex)) + return DSP_EFAIL; pTempDMMRes = pCtxt->pDMMList; if (pCtxt->pDMMList == pDMMRes) { pCtxt->pDMMList = pDMMRes->next; @@ -233,11 +252,13 @@ DSP_STATUS DRV_RemoveDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) while (pTempDMMRes && pTempDMMRes->next != pDMMRes) pTempDMMRes = pTempDMMRes->next; if (!pTempDMMRes) - return DSP_ENOTFOUND; - pTempDMMRes->next = pDMMRes->next; + status = DSP_ENOTFOUND; + else + pTempDMMRes->next = pDMMRes->next; } + mutex_unlock(&pCtxt->dmm_mutex); kfree(pDMMRes); - return DSP_SOK; + return status; } /* Update DMM resource status */ @@ -315,6 +336,9 @@ DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE hDMMRes, HANDLE hPCtxt) DSP_STATUS status = DSP_SOK; struct DMM_RES_OBJECT *pTempDMM = NULL; + if (mutex_lock_interruptible(&pCtxt->dmm_mutex)) + return DSP_EFAIL; + pTempDMM = pCtxt->pDMMList; while ((pTempDMM != NULL) && (pTempDMM->ulDSPAddr != pMapAddr)) { GT_3trace(curTrace, GT_ENTER, @@ -323,6 +347,9 @@ DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE hDMMRes, HANDLE hPCtxt) pTempDMM->ulDSPAddr, pMapAddr); pTempDMM = pTempDMM->next; } + + mutex_unlock(&pCtxt->dmm_mutex); + if (pTempDMM != NULL) { GT_0trace(curTrace, GT_ENTER, "DRV_GetDMMResElement: 3"); *pDMMRes = pTempDMM; @@ -378,12 +405,18 @@ DSP_STATUS DRV_GetNodeResElement(HANDLE hNode, HANDLE hNodeRes, HANDLE hPCtxt) struct NODE_RES_OBJECT *pTempNode2 = NULL; struct NODE_RES_OBJECT *pTempNode = NULL; + if (mutex_lock_interruptible(&pCtxt->node_mutex)) + return DSP_EFAIL; + pTempNode = pCtxt->pNodeList; GT_0trace(curTrace, GT_ENTER, "DRV_GetNodeResElement: 1"); while ((pTempNode != NULL) && (pTempNode->hNode != hNode)) { pTempNode2 = pTempNode; pTempNode = pTempNode->next; } + + mutex_unlock(&pCtxt->node_mutex); + if (pTempNode != NULL) *nodeRes = pTempNode; else @@ -410,6 +443,10 @@ DSP_STATUS DRV_ProcInsertSTRMResElement(HANDLE hStreamHandle, HANDLE hSTRMRes, status = DSP_EHANDLE; } if (DSP_SUCCEEDED(status)) { + if (mutex_lock_interruptible(&pCtxt->strm_mutex)) { + kfree(*pSTRMRes); + return DSP_EFAIL; + } (*pSTRMRes)->hStream = hStreamHandle; if (pCtxt->pSTRMList != NULL) { GT_0trace(curTrace, GT_ENTER, @@ -424,6 +461,7 @@ DSP_STATUS DRV_ProcInsertSTRMResElement(HANDLE hStreamHandle, HANDLE hSTRMRes, GT_0trace(curTrace, GT_ENTER, "DRV_InsertSTRMResElement: 4"); } + mutex_unlock(&pCtxt->strm_mutex); } return status; } @@ -436,7 +474,10 @@ DSP_STATUS DRV_ProcRemoveSTRMResElement(HANDLE hSTRMRes, HANDLE hPCtxt) struct STRM_RES_OBJECT *pSTRMRes = (struct STRM_RES_OBJECT *)hSTRMRes; struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; struct STRM_RES_OBJECT *pTempSTRMRes; + DSP_STATUS status = DSP_SOK; + if (mutex_lock_interruptible(&pCtxt->strm_mutex)) + return DSP_EFAIL; pTempSTRMRes = pCtxt->pSTRMList; if (pCtxt->pSTRMList == pSTRMRes) { @@ -445,12 +486,13 @@ DSP_STATUS DRV_ProcRemoveSTRMResElement(HANDLE hSTRMRes, HANDLE hPCtxt) while (pTempSTRMRes && pTempSTRMRes->next != pSTRMRes) pTempSTRMRes = pTempSTRMRes->next; if (pTempSTRMRes == NULL) - return DSP_ENOTFOUND; - pTempSTRMRes->next = pSTRMRes->next; + status = DSP_ENOTFOUND; + else + pTempSTRMRes->next = pSTRMRes->next; } - + mutex_unlock(&pCtxt->strm_mutex); kfree(pSTRMRes); - return DSP_SOK; + return status; } /* Actual Stream De-Allocation */ @@ -522,13 +564,20 @@ DSP_STATUS DRV_GetSTRMResElement(HANDLE hStrm, HANDLE hSTRMRes, HANDLE hPCtxt) struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; DSP_STATUS status = DSP_SOK; struct STRM_RES_OBJECT *pTempSTRM2 = NULL; - struct STRM_RES_OBJECT *pTempSTRM = pCtxt->pSTRMList; + struct STRM_RES_OBJECT *pTempSTRM; + + if (mutex_lock_interruptible(&pCtxt->strm_mutex)) + return DSP_EFAIL; + pTempSTRM = pCtxt->pSTRMList; while ((pTempSTRM != NULL) && (pTempSTRM->hStream != hStrm)) { GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 2"); pTempSTRM2 = pTempSTRM; pTempSTRM = pTempSTRM->next; } + + mutex_unlock(&pCtxt->strm_mutex); + if (pTempSTRM != NULL) { GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 3"); *STRMRes = pTempSTRM; diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c b/drivers/dsp/bridge/rmgr/drv_interface.c index 1676c78..3fd3665 100644 --- a/drivers/dsp/bridge/rmgr/drv_interface.c +++ b/drivers/dsp/bridge/rmgr/drv_interface.c @@ -492,10 +492,14 @@ static int bridge_open(struct inode *ip, struct file *filp) * process context list. */ pr_ctxt = MEM_Calloc(sizeof(struct PROCESS_CONTEXT), MEM_PAGED); - if (pr_ctxt) + if (pr_ctxt) { pr_ctxt->resState = PROC_RES_ALLOCATED; - else + mutex_init(&pr_ctxt->dmm_mutex); + mutex_init(&pr_ctxt->node_mutex); + mutex_init(&pr_ctxt->strm_mutex); + } else { status = -ENOMEM; + } filp->private_data = pr_ctxt;