[PATCH 4/4] DSPBRIDGE: Improved mapped memory cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch improves current mapped memory cleanup mechanism by using linux
native list implementation. As a side effect we also get following benefits:

1. Unnecessary data members in DMM_MAP_OBJECT are removed which results in
   memory saving.

2. Following functions are removed as they are not needed anymore:
   DRV_ProcFreeDMMRes()
   DRV_UpdateDMMResElement()
   DRV_InsertDMMResElement()
   DRV_GetDMMResElement()
   DRV_RemoveDMMResElement()

Signed-off-by: Ameya Palande <ameya.palande@xxxxxxxxx>
---
 arch/arm/plat-omap/include/dspbridge/drv.h         |   30 +---
 .../plat-omap/include/dspbridge/resourcecleanup.h  |   11 --
 drivers/dsp/bridge/rmgr/drv.c                      |  161 ++------------------
 drivers/dsp/bridge/rmgr/drv_interface.c            |    3 +-
 drivers/dsp/bridge/rmgr/proc.c                     |   43 ++++--
 5 files changed, 54 insertions(+), 194 deletions(-)

diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-omap/include/dspbridge/drv.h
index f7d0e3e..854923a 100644
--- a/arch/arm/plat-omap/include/dspbridge/drv.h
+++ b/arch/arm/plat-omap/include/dspbridge/drv.h
@@ -90,16 +90,11 @@ struct NODE_RES_OBJECT {
 	struct NODE_RES_OBJECT         *next;
 } ;
 
-/* Abstracts DMM resource info */
+/* Used for DMM mapped memory accounting */
 struct DMM_MAP_OBJECT {
-	s32            dmmAllocated; /* DMM status */
-	u32           ulMpuAddr;
-	u32           ulDSPAddr;
-	u32           ulDSPResAddr;
-	u32           size;
-	HANDLE          hProcessor;
-	struct DMM_MAP_OBJECT  *next;
-} ;
+	struct	list_head	link;
+	u32	dsp_addr;
+};
 
 /* Used for DMM reserved memory accounting */
 struct DMM_RSV_OBJECT {
@@ -146,8 +141,8 @@ struct PROCESS_CONTEXT{
 	struct mutex node_mutex;
 
 	/* DMM mapped memory resources */
-	struct DMM_MAP_OBJECT *dmm_map_list;
-	struct mutex dmm_map_mutex;
+	struct list_head dmm_map_list;
+	spinlock_t dmm_map_lock;
 
 	/* DMM reserved memory resources */
 	struct list_head dmm_rsv_list;
@@ -398,17 +393,4 @@ struct PROCESS_CONTEXT{
 	extern DSP_STATUS DRV_ReleaseResources(IN u32 dwContext,
 					       struct DRV_OBJECT *hDrvObject);
 
-/*
- *  ======== DRV_ProcFreeDMMRes ========
- *  Purpose:
- *       Actual DMM De-Allocation.
- *  Parameters:
- *      hPCtxt:      Path to the driver Registry Key.
- *  Returns:
- *      DSP_SOK if success;
- */
-
-
-	extern DSP_STATUS  DRV_ProcFreeDMMRes(HANDLE hPCtxt);
-
 #endif				/* DRV_ */
diff --git a/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h
index ffbcf5e..2bb756a 100644
--- a/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h
+++ b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h
@@ -48,17 +48,6 @@ extern DSP_STATUS DRV_RemoveNodeResElement(HANDLE nodeRes, HANDLE status);
 
 extern void DRV_ProcNodeUpdateStatus(HANDLE hNodeRes, s32 status);
 
-extern DSP_STATUS DRV_UpdateDMMResElement(HANDLE dmmRes, u32 pMpuAddr,
-					  u32 ulSize, u32 pReqAddr,
-					  u32 ppMapAddr, HANDLE hProcesso);
-
-extern DSP_STATUS DRV_InsertDMMResElement(HANDLE dmmRes, HANDLE pCtxt);
-
-extern DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE dmmRes,
-				       HANDLE pCtxt);
-
-extern DSP_STATUS DRV_RemoveDMMResElement(HANDLE dmmRes, HANDLE pCtxt);
-
 extern DSP_STATUS DRV_ProcUpdateSTRMRes(u32 uNumBufs, HANDLE STRMRes);
 
 extern DSP_STATUS DRV_ProcInsertSTRMResElement(HANDLE hStrm, HANDLE STRMRes,
diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c
index b88b5a3..bb6c246 100644
--- a/drivers/dsp/bridge/rmgr/drv.c
+++ b/drivers/dsp/bridge/rmgr/drv.c
@@ -193,129 +193,27 @@ static DSP_STATUS DRV_ProcFreeNodeRes(HANDLE hPCtxt)
 	return status;
 }
 
-/* Allocate the DMM resource element
-* This is called from Proc_Map. after the actual resource is allocated */
-DSP_STATUS DRV_InsertDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt)
-{
-	struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt;
-	struct DMM_MAP_OBJECT **pDMMRes = (struct DMM_MAP_OBJECT **)hDMMRes;
-	DSP_STATUS	status = DSP_SOK;
-	struct DMM_MAP_OBJECT *pTempDMMRes = NULL;
-
-	*pDMMRes = (struct DMM_MAP_OBJECT *)
-		    MEM_Calloc(1 * sizeof(struct DMM_MAP_OBJECT), MEM_PAGED);
-	GT_0trace(curTrace, GT_ENTER, "DRV_InsertDMMResElement: 1");
-	if (*pDMMRes == NULL) {
-		GT_0trace(curTrace, GT_5CLASS, "DRV_InsertDMMResElement: 2");
-		status = DSP_EHANDLE;
-	}
-	if (DSP_SUCCEEDED(status)) {
-		if (mutex_lock_interruptible(&pCtxt->dmm_map_mutex)) {
-			kfree(*pDMMRes);
-			return DSP_EFAIL;
-		}
-
-		if (pCtxt->dmm_map_list) {
-			GT_0trace(curTrace, GT_5CLASS,
-				 "DRV_InsertDMMResElement: 3");
-			pTempDMMRes = pCtxt->dmm_map_list;
-			while (pTempDMMRes->next)
-				pTempDMMRes = pTempDMMRes->next;
-
-			pTempDMMRes->next = *pDMMRes;
-		} else {
-			pCtxt->dmm_map_list = *pDMMRes;
-			GT_0trace(curTrace, GT_5CLASS,
-				 "DRV_InsertDMMResElement: 4");
-		}
-		mutex_unlock(&pCtxt->dmm_map_mutex);
-	}
-	GT_0trace(curTrace, GT_ENTER, "DRV_InsertDMMResElement: 5");
-	return status;
-}
-
-/* Release DMM resource element context
-* This is called from Proc_UnMap. after the actual resource is freed */
-DSP_STATUS DRV_RemoveDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt)
-{
-	struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt;
-	struct DMM_MAP_OBJECT *pDMMRes = (struct DMM_MAP_OBJECT *)hDMMRes;
-	struct DMM_MAP_OBJECT *pTempDMMRes = NULL;
-	DSP_STATUS status = DSP_SOK;
-
-	if (mutex_lock_interruptible(&pCtxt->dmm_map_mutex))
-		return DSP_EFAIL;
-	pTempDMMRes = pCtxt->dmm_map_list;
-	if (pCtxt->dmm_map_list == pDMMRes) {
-		pCtxt->dmm_map_list = pDMMRes->next;
-	} else {
-		while (pTempDMMRes && pTempDMMRes->next != pDMMRes)
-			pTempDMMRes = pTempDMMRes->next;
-		if (!pTempDMMRes)
-			status = DSP_ENOTFOUND;
-		else
-			pTempDMMRes->next = pDMMRes->next;
-	}
-	mutex_unlock(&pCtxt->dmm_map_mutex);
-	kfree(pDMMRes);
-	return status;
-}
-
-/* Update DMM resource status */
-DSP_STATUS DRV_UpdateDMMResElement(HANDLE hDMMRes, u32 pMpuAddr, u32 ulSize,
-				  u32 pReqAddr, u32 pMapAddr,
-				  HANDLE hProcessor)
-{
-	struct DMM_MAP_OBJECT *pDMMRes = (struct DMM_MAP_OBJECT *)hDMMRes;
-	DSP_STATUS status = DSP_SOK;
-
-	DBC_Assert(hDMMRes != NULL);
-	pDMMRes->ulMpuAddr = pMpuAddr;
-	pDMMRes->ulDSPAddr = pMapAddr;
-	pDMMRes->ulDSPResAddr = pReqAddr;
-	pDMMRes->size = ulSize;
-	pDMMRes->hProcessor = hProcessor;
-	pDMMRes->dmmAllocated = 1;
-
-	return status;
-}
-
-/* Actual DMM De-Allocation */
-DSP_STATUS  DRV_ProcFreeDMMRes(HANDLE hPCtxt)
-{
-	struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt;
-	DSP_STATUS status = DSP_SOK;
-	struct DMM_MAP_OBJECT *pDMMList = pCtxt->dmm_map_list;
-	struct DMM_MAP_OBJECT *pDMMRes = NULL;
-
-	GT_0trace(curTrace, GT_ENTER, "\nDRV_ProcFreeDMMRes: 1\n");
-	while (pDMMList) {
-		pDMMRes = pDMMList;
-		pDMMList = pDMMList->next;
-		if (pDMMRes->dmmAllocated) {
-			/* PROC_UnMap will free pDMMRes pointer */
-			status = PROC_UnMap(pDMMRes->hProcessor,
-				 (void *)pDMMRes->ulDSPAddr, pCtxt);
-			if (DSP_FAILED(status))
-				pr_debug("%s: PROC_UnMap failed! status ="
-						" 0x%xn", __func__, status);
-		}
-	}
-	return status;
-}
-
 /* Release all Mapped and Reserved DMM resources */
 DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE hPCtxt)
 {
 	struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt;
 	DSP_STATUS status = DSP_SOK;
-	struct DMM_RSV_OBJECT *temp, *rsv_obj;
-
-	DRV_ProcFreeDMMRes(pCtxt);
-	pCtxt->dmm_map_list = NULL;
+	struct DMM_MAP_OBJECT *temp_map, *map_obj;
+	struct DMM_RSV_OBJECT *temp_rsv, *rsv_obj;
+
+	/* Free DMM mapped memory resources */
+	list_for_each_entry_safe(map_obj, temp_map, &pCtxt->dmm_map_list,
+			link) {
+		status = PROC_UnMap(pCtxt->hProcessor,
+				(void *)map_obj->dsp_addr, pCtxt);
+		if (DSP_FAILED(status))
+			pr_err("%s: PROC_UnMap failed!"
+					" status = 0x%xn", __func__, status);
+	}
 
 	/* Free DMM reserved memory resources */
-	list_for_each_entry_safe(rsv_obj, temp, &pCtxt->dmm_rsv_list, link) {
+	list_for_each_entry_safe(rsv_obj, temp_rsv, &pCtxt->dmm_rsv_list,
+			link) {
 		status = PROC_UnReserveMemory(pCtxt->hProcessor,
 				(void *)rsv_obj->dsp_reserved_addr, pCtxt);
 		if (DSP_FAILED(status))
@@ -325,37 +223,6 @@ DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE hPCtxt)
 	return status;
 }
 
-DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE hDMMRes, HANDLE hPCtxt)
-{
-	struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt;
-	struct DMM_MAP_OBJECT **pDMMRes = (struct DMM_MAP_OBJECT **)hDMMRes;
-	DSP_STATUS status = DSP_SOK;
-	struct DMM_MAP_OBJECT *pTempDMM = NULL;
-
-	if (mutex_lock_interruptible(&pCtxt->dmm_map_mutex))
-		return DSP_EFAIL;
-
-	pTempDMM = pCtxt->dmm_map_list;
-	while (pTempDMM && (pTempDMM->ulDSPAddr != pMapAddr)) {
-		GT_3trace(curTrace, GT_ENTER,
-			 "DRV_GetDMMResElement: 2 pTempDMM:%x "
-			 "pTempDMM->ulDSPAddr:%x pMapAddr:%x\n", pTempDMM,
-			 pTempDMM->ulDSPAddr, pMapAddr);
-		pTempDMM = pTempDMM->next;
-	}
-
-	mutex_unlock(&pCtxt->dmm_map_mutex);
-
-	if (pTempDMM) {
-		GT_0trace(curTrace, GT_ENTER, "DRV_GetDMMResElement: 3");
-		*pDMMRes = pTempDMM;
-	} else {
-		status = DSP_ENOTFOUND;
-		GT_0trace(curTrace, GT_ENTER, "DRV_GetDMMResElement: 4");
-	}
-	return status;
-}
-
 /* Update Node allocation status */
 void DRV_ProcNodeUpdateStatus(HANDLE hNodeRes, s32 status)
 {
diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c b/drivers/dsp/bridge/rmgr/drv_interface.c
index 80b8c7e..800ed61 100644
--- a/drivers/dsp/bridge/rmgr/drv_interface.c
+++ b/drivers/dsp/bridge/rmgr/drv_interface.c
@@ -499,7 +499,8 @@ static int bridge_open(struct inode *ip, struct file *filp)
 	pr_ctxt = MEM_Calloc(sizeof(struct PROCESS_CONTEXT), MEM_PAGED);
 	if (pr_ctxt) {
 		pr_ctxt->resState = PROC_RES_ALLOCATED;
-		mutex_init(&pr_ctxt->dmm_map_mutex);
+		spin_lock_init(&pr_ctxt->dmm_map_lock);
+		INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
 		spin_lock_init(&pr_ctxt->dmm_rsv_lock);
 		INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
 		mutex_init(&pr_ctxt->node_mutex);
diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c
index b8e0334..5ddfff6 100644
--- a/drivers/dsp/bridge/rmgr/proc.c
+++ b/drivers/dsp/bridge/rmgr/proc.c
@@ -1286,8 +1286,7 @@ DSP_STATUS PROC_Map(DSP_HPROCESSOR hProcessor, void *pMpuAddr, u32 ulSize,
 	u32 sizeAlign;
 	DSP_STATUS status = DSP_SOK;
 	struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor;
-
-       HANDLE        dmmRes;
+	struct DMM_MAP_OBJECT *map_obj;
 
 	GT_6trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Map, args:\n\t"
 		 "hProcessor %x, pMpuAddr %x, ulSize %x, pReqAddr %x, "
@@ -1334,11 +1333,22 @@ DSP_STATUS PROC_Map(DSP_HPROCESSOR hProcessor, void *pMpuAddr, u32 ulSize,
 	}
 	(void)SYNC_LeaveCS(hProcLock);
 
-	if (DSP_SUCCEEDED(status)) {
-		DRV_InsertDMMResElement(&dmmRes, pr_ctxt);
-		DRV_UpdateDMMResElement(dmmRes, (u32)pMpuAddr, ulSize,
-				(u32)pReqAddr, (u32)*ppMapAddr, hProcessor);
+	if (DSP_FAILED(status))
+		goto func_end;
+
+	/*
+	 * A successful map should be followed by insertion of map_obj
+	 * into dmm_map_list, so that mapped memory resource tracking
+	 * remains uptodate
+	 */
+	map_obj = kmalloc(sizeof(struct DMM_MAP_OBJECT), GFP_KERNEL);
+	if (map_obj) {
+		map_obj->dsp_addr = (u32)*ppMapAddr;
+		spin_lock(&pr_ctxt->dmm_map_lock);
+		list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
+		spin_unlock(&pr_ctxt->dmm_map_lock);
 	}
+
 func_end:
 	GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_Map [0x%x]", status);
 	return status;
@@ -1669,8 +1679,7 @@ DSP_STATUS PROC_UnMap(DSP_HPROCESSOR hProcessor, void *pMapAddr,
 	struct DMM_OBJECT *hDmmMgr;
 	u32 vaAlign;
 	u32 sizeAlign;
-
-	HANDLE	      dmmRes;
+	struct DMM_MAP_OBJECT *map_obj;
 
 	GT_2trace(PROC_DebugMask, GT_ENTER,
 		 "Entered PROC_UnMap, args:\n\thProcessor:"
@@ -1710,9 +1719,21 @@ DSP_STATUS PROC_UnMap(DSP_HPROCESSOR hProcessor, void *pMapAddr,
 	if (DSP_FAILED(status))
 		goto func_end;
 
-	if (DRV_GetDMMResElement((u32)pMapAddr, &dmmRes, pr_ctxt)
-							!= DSP_ENOTFOUND)
-		DRV_RemoveDMMResElement(dmmRes, pr_ctxt);
+	/*
+	 * A successful unmap should be followed by removal of map_obj
+	 * from dmm_map_list, so that mapped memory resource tracking
+	 * remains uptodate
+	 */
+	spin_lock(&pr_ctxt->dmm_map_lock);
+	list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
+		if (map_obj->dsp_addr == (u32)pMapAddr) {
+			list_del(&map_obj->link);
+			kfree(map_obj);
+			break;
+		}
+	}
+	spin_unlock(&pr_ctxt->dmm_map_lock);
+
 func_end:
 	GT_1trace(PROC_DebugMask, GT_ENTER,
 		 "Leaving PROC_UnMap [0x%x]", status);
-- 
1.6.3.3

--
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

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux