RE: [PATCHv4 4/4] DSPBRIDGE: Improved mapped memory cleanup

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

 



Hi,

>-----Original Message-----
>From: Ameya Palande [mailto:ameya.palande@xxxxxxxxx]
>Sent: Wednesday, February 17, 2010 12:06 PM
>To: linux-omap@xxxxxxxxxxxxxxx
>Cc: felipe.contreras@xxxxxxxxx; Menon, Nishanth; Chitriki Rudramuni,
>Deepak; Guzman Lugo, Fernando; Ramirez Luna, Omar
>Subject: [PATCHv4 4/4] DSPBRIDGE: Improved mapped memory cleanup
>
>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                     |   33 +++--
> 5 files changed, 44 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 6ce76cb..7fa3a16 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,17 @@ 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;
>+
>+	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);
> 	}

What do you think about it?
Instead of removing DRV_InsertDMMResElement make it an inline function with your code inside:

inline void DRV_InsertDMMResElement(u32 ppMapAddr)
{
	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);
	}	
}

It could make the code more understandable about what it is actually doing. 
It also applies to the functions which removes this patch.

Regards,
Fenando

>+
> func_end:
> 	GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_Map [0x%x]",
>status);
> 	return status;
>@@ -1664,8 +1669,7 @@ DSP_STATUS PROC_UnMap(DSP_HPROCESSOR hProcessor, void
>*pMapAddr,
> 	struct DMM_OBJECT *hDmmMgr;
> 	u32 vaAlign;
> 	u32 sizeAlign;
>-
>-	HANDLE	      dmmRes;
>+	struct DMM_MAP_OBJECT *temp, *map_obj;
>
> 	GT_2trace(PROC_DebugMask, GT_ENTER,
> 		 "Entered PROC_UnMap, args:\n\thProcessor:"
>@@ -1705,9 +1709,16 @@ 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);
>+	spin_lock(&pr_ctxt->dmm_map_lock);
>+	list_for_each_entry_safe(map_obj, temp, &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