Please discard previous one. Regards, Fernando. >From 6bcdc02f6265246e385194433775e75db7ad44cf Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo <x0095840@xxxxxx> Date: Wed, 10 Feb 2010 02:31:40 -0600 Subject: [PATCH] DSPBRIDGE: Adding protection Resource cleanup linked lists This patch protects the Resorce cleanup lists from concurrent access Signed-off-by: Fernando Guzman Lugo <x0095840@xxxxxx> --- arch/arm/plat-omap/include/dspbridge/drv.h | 3 + drivers/dsp/bridge/pmgr/wcd.c | 16 ++++++- drivers/dsp/bridge/rmgr/drv.c | 71 +++++++++++++++++++++++---- drivers/dsp/bridge/rmgr/drv_interface.c | 8 ++- 4 files changed, 83 insertions(+), 15 deletions(-) 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; -- 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html