RE: [PATCH 2/2] DSPBRIDGE: New reserved memory accounting framework

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

 



Hi,

>-----Original Message-----
>From: Ameya Palande [mailto:ameya.palande@xxxxxxxxx]
>Sent: Tuesday, February 16, 2010 7:20 AM
>To: linux-omap@xxxxxxxxxxxxxxx
>Cc: felipe.contreras@xxxxxxxxx; Menon, Nishanth; Chitriki Rudramuni,
>Deepak; Ramirez Luna, Omar; Guzman Lugo, Fernando
>Subject: [PATCH 2/2] DSPBRIDGE: New reserved memory accounting framework
>
>DSP_RSV_OBJECT is introduced to track reserved memory accounting
>information.
>This will allow us to do proper cleanup for memory reserved using
>PROC_ReserveMemory().
>
>Signed-off-by: Ameya Palande <ameya.palande@xxxxxxxxx>
>---
> arch/arm/plat-omap/include/dspbridge/drv.h  |   13 ++++++
> arch/arm/plat-omap/include/dspbridge/proc.h |    5 +-
> drivers/dsp/bridge/pmgr/dmm.c               |    3 +-
> drivers/dsp/bridge/pmgr/wcd.c               |    7 ++-
> drivers/dsp/bridge/rmgr/drv.c               |   27 +++++++++---
> drivers/dsp/bridge/rmgr/drv_interface.c     |    7 ++-
> drivers/dsp/bridge/rmgr/node.c              |    5 +-
> drivers/dsp/bridge/rmgr/proc.c              |   58 +++++++++++++++++++++--
>---
> 8 files changed, 97 insertions(+), 28 deletions(-)
>
>diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-
>omap/include/dspbridge/drv.h
>index 3069e74..6e8187d 100644
>--- a/arch/arm/plat-omap/include/dspbridge/drv.h
>+++ b/arch/arm/plat-omap/include/dspbridge/drv.h
>@@ -101,6 +101,15 @@ struct DMM_MAP_OBJECT {
> 	struct DMM_MAP_OBJECT  *next;
> } ;
>
>+/*
>+ * New structure (member of process context) used for accounting of DMM
>+ * reserved memory information
>+ */
>+struct DMM_RSV_OBJECT {
>+	struct	list_head	link;
>+	u32	dsp_reserved_addr;
>+};
>+
> /* New structure (member of process context) abstracts DMM resource info
>*/
> struct DSPHEAP_RES_OBJECT {
> 	s32            heapAllocated; /* DMM status */
>@@ -141,6 +150,10 @@ struct PROCESS_CONTEXT{
> 	/* DMM mapped memory resources */
> 	struct DMM_MAP_OBJECT *dmm_map_list;
>
>+	/* DMM reserved memory resources */
>+	struct list_head dmm_rsv_list;
>+	spinlock_t dmm_rsv_list_lock;
>+
> 	/* DSP Heap resources */
> 	struct DSPHEAP_RES_OBJECT *pDSPHEAPList;
>
>diff --git a/arch/arm/plat-omap/include/dspbridge/proc.h b/arch/arm/plat-
>omap/include/dspbridge/proc.h
>index 8dbdaac..558c053 100644
>--- a/arch/arm/plat-omap/include/dspbridge/proc.h
>+++ b/arch/arm/plat-omap/include/dspbridge/proc.h
>@@ -560,7 +560,7 @@
>  *  Details:
>  */
> 	extern DSP_STATUS PROC_ReserveMemory(DSP_HPROCESSOR hProcessor,
>-					     u32 ulSize, void **ppRsvAddr);
>+		u32 ulSize, void **ppRsvAddr, struct PROCESS_CONTEXT *pr_ctxt);
>
> /*
>  *  ======== PROC_UnMap ========
>@@ -604,6 +604,7 @@
>  *  Details:
>  */
> 	extern DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR hProcessor,
>-					       void *pRsvAddr);
>+			void *pRsvAddr, struct PROCESS_CONTEXT *pr_ctxt,
>+			int cleanup);
>
> #endif				/* PROC_ */
>diff --git a/drivers/dsp/bridge/pmgr/dmm.c b/drivers/dsp/bridge/pmgr/dmm.c
>index d5a7275..72aee60 100644
>--- a/drivers/dsp/bridge/pmgr/dmm.c
>+++ b/drivers/dsp/bridge/pmgr/dmm.c
>@@ -386,9 +386,10 @@ DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT
>*hDmmMgr, u32 size,
> 		node->MappedSize = 0;
> 		/* Return the chunk's starting address */
> 		*pRsvAddr = rsvAddr;
>-	} else
>+	} else {
> 		/*dSP chunk of given size is not available */
> 		status = DSP_EMEMORY;
>+	}
>
> 	SYNC_LeaveCS(pDmmObj->hDmmLock);
> 	GT_3trace(DMM_debugMask, GT_4CLASS,
>diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c
>index beea23b..747d069 100644
>--- a/drivers/dsp/bridge/pmgr/wcd.c
>+++ b/drivers/dsp/bridge/pmgr/wcd.c
>@@ -1054,12 +1054,13 @@ u32 PROCWRAP_ReserveMemory(union Trapped_Args
>*args, void *pr_ctxt)
>
> 	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_ReserveMemory:
>entered\n");
> 	status = PROC_ReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor,
>-				   args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr);
>+				   args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr,
>+				   pr_ctxt);
> 	if (DSP_SUCCEEDED(status)) {
> 		if (put_user(pRsvAddr, args->ARGS_PROC_RSVMEM.ppRsvAddr)) {
> 			status = DSP_EINVALIDARG;
> 			PROC_UnReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor,
>-				pRsvAddr);
>+				pRsvAddr, pr_ctxt, 1);
> 		}
> 	}
> 	return status;
>@@ -1100,7 +1101,7 @@ u32 PROCWRAP_UnReserveMemory(union Trapped_Args
>*args, void *pr_ctxt)
> 	GT_0trace(WCD_debugMask, GT_ENTER,
> 		 "PROCWRAP_UnReserveMemory: entered\n");
> 	status = PROC_UnReserveMemory(args->ARGS_PROC_UNRSVMEM.hProcessor,
>-				     args->ARGS_PROC_UNRSVMEM.pRsvAddr);
>+			args->ARGS_PROC_UNRSVMEM.pRsvAddr, pr_ctxt, 1);
> 	return status;
> }
>
>diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c
>index 3dc38d0..9d5c077 100644
>--- a/drivers/dsp/bridge/rmgr/drv.c
>+++ b/drivers/dsp/bridge/rmgr/drv.c
>@@ -277,25 +277,20 @@ DSP_STATUS  DRV_ProcFreeDMMRes(HANDLE hPCtxt)
> 			if (DSP_FAILED(status))
> 				pr_debug("%s: PROC_UnMap failed! status ="
> 						" 0x%xn", __func__, status);
>-			status = PROC_UnReserveMemory(pDMMRes->hProcessor,
>-				 (void *)pDMMRes->ulDSPResAddr);
>-			if (DSP_FAILED(status))
>-				pr_debug("%s: PROC_UnReserveMemory failed!"
>-					" status = 0x%xn", __func__, status);
> 			pDMMRes->dmmAllocated = 0;
> 		}
> 	}
> 	return status;
> }
>
>-/* Release all DMM resources and its context
>-* This is called from .bridge_release. */
>+/* 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_MAP_OBJECT *pTempDMMRes2 = NULL;
> 	struct DMM_MAP_OBJECT *pTempDMMRes = NULL;
>+	struct DMM_RSV_OBJECT *temp, *rsv_obj;
>
> 	DRV_ProcFreeDMMRes(pCtxt);
> 	pTempDMMRes = pCtxt->dmm_map_list;
>@@ -305,6 +300,24 @@ DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE hPCtxt)
> 		kfree(pTempDMMRes2);
> 	}
> 	pCtxt->dmm_map_list = NULL;
>+
>+	/* Free DMM reserved memory resources */
>+	spin_lock(&pCtxt->dmm_rsv_list_lock);
>+	list_for_each_entry_safe(rsv_obj, temp, &pCtxt->dmm_rsv_list, link) {
>+		/*
>+		 * Since we have already acquired spin lock for dmm_rsv_list,
>+		 * we don't want to perform cleanup in PROC_UnReserveMemory.
>+		 */

DRV_ProcFreeDMMRes is only called from bridge_release and there is no other thread from the same process that can be executed concurrent. It is not needed lock at cleanup time.

After removing the lock, I think you don't need cleanup flag in PROC_UnReserveMemory. Because the cleanup can be done in PROC_UnReserveMemory without problems.

Regards,
Fernando.

>+		status = PROC_UnReserveMemory(pCtxt->hProcessor,
>+				(void *)rsv_obj->dsp_reserved_addr, pCtxt, 0);
>+		if (DSP_FAILED(status))
>+			pr_err("%s: PROC_UnReserveMemory failed!"
>+					" status = 0x%xn", __func__, status);
>+		list_del(&rsv_obj->link);
>+		kfree(rsv_obj);
>+	}
>+	spin_unlock(&pCtxt->dmm_rsv_list_lock);
>+
> 	return status;
> }
>
>diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c
>b/drivers/dsp/bridge/rmgr/drv_interface.c
>index 0ce9a5f..ef078cf 100644
>--- a/drivers/dsp/bridge/rmgr/drv_interface.c
>+++ b/drivers/dsp/bridge/rmgr/drv_interface.c
>@@ -497,10 +497,13 @@ 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
>+		spin_lock_init(&pr_ctxt->dmm_rsv_list_lock);
>+		INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
>+	} else {
> 		status = -ENOMEM;
>+	}
>
> 	filp->private_data = pr_ctxt;
>
>diff --git a/drivers/dsp/bridge/rmgr/node.c
>b/drivers/dsp/bridge/rmgr/node.c
>index b60d1ed..f85b4b8 100644
>--- a/drivers/dsp/bridge/rmgr/node.c
>+++ b/drivers/dsp/bridge/rmgr/node.c
>@@ -454,7 +454,7 @@ DSP_STATUS NODE_Allocate(struct PROC_OBJECT
>*hProcessor,
> 	status = PROC_ReserveMemory(hProcessor,
> 			pNode->createArgs.asa.taskArgs.uHeapSize + PAGE_SIZE,
> 			(void **)&(pNode->createArgs.asa.taskArgs.
>-				uDSPHeapResAddr));
>+				uDSPHeapResAddr), pr_ctxt);
> 	if (DSP_FAILED(status)) {
> 		GT_1trace(NODE_debugMask, GT_5CLASS,
> 			 "NODE_Allocate:Failed to reserve "
>@@ -2726,7 +2726,8 @@ static void DeleteNode(struct NODE_OBJECT *hNode,
> 					 " Status = 0x%x\n", (u32)status);
> 			}
> 			status = PROC_UnReserveMemory(hNode->hProcessor,
>-					(void *)taskArgs.uDSPHeapResAddr);
>+					(void *)taskArgs.uDSPHeapResAddr,
>+					pr_ctxt, 1);
> 			if (DSP_SUCCEEDED(status)) {
> 				GT_0trace(NODE_debugMask, GT_5CLASS,
> 					 "DSPProcessor_UnReserveMemory "
>diff --git a/drivers/dsp/bridge/rmgr/proc.c
>b/drivers/dsp/bridge/rmgr/proc.c
>index 2ccbc9b..2ef2e37 100644
>--- a/drivers/dsp/bridge/rmgr/proc.c
>+++ b/drivers/dsp/bridge/rmgr/proc.c
>@@ -1430,11 +1430,12 @@ func_end:
>  *      Reserve a virtually contiguous region of DSP address space.
>  */
> DSP_STATUS PROC_ReserveMemory(DSP_HPROCESSOR hProcessor, u32 ulSize,
>-			     void **ppRsvAddr)
>+		void **ppRsvAddr, struct PROCESS_CONTEXT *pr_ctxt)
> {
> 	struct DMM_OBJECT *hDmmMgr;
> 	DSP_STATUS status = DSP_SOK;
> 	struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor;
>+	struct DMM_RSV_OBJECT *rsv_obj;
>
> 	GT_3trace(PROC_DebugMask, GT_ENTER,
> 		 "Entered PROC_ReserveMemory, args:\n\t"
>@@ -1446,16 +1447,29 @@ DSP_STATUS PROC_ReserveMemory(DSP_HPROCESSOR
>hProcessor, u32 ulSize,
> 			 "InValid Processor Handle \n");
> 		goto func_end;
> 	}
>+
> 	status = DMM_GetHandle(pProcObject, &hDmmMgr);
> 	if (DSP_FAILED(status)) {
> 		GT_1trace(PROC_DebugMask, GT_7CLASS, "PROC_ReserveMemory: "
> 			 "Failed to get DMM Mgr handle: 0x%x\n", status);
>-	} else
>-		status = DMM_ReserveMemory(hDmmMgr, ulSize, (u32 *)ppRsvAddr);
>+		goto func_end;
>+	}
>+
>+	status = DMM_ReserveMemory(hDmmMgr, ulSize, (u32 *)ppRsvAddr);
>+	if (status != DSP_SOK)
>+		goto func_end;
>+
>+	rsv_obj = kmalloc(sizeof(struct DMM_RSV_OBJECT), GFP_KERNEL);
>+	if (rsv_obj) {
>+		rsv_obj->dsp_reserved_addr = (u32) *ppRsvAddr;
>+		spin_lock(&pr_ctxt->dmm_rsv_list_lock);
>+		list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
>+		spin_unlock(&pr_ctxt->dmm_rsv_list_lock);
>+	}
>
>+func_end:
> 	GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_ReserveMemory
>[0x%x]",
> 		 status);
>-func_end:
> 	return status;
> }
>
>@@ -1704,11 +1718,13 @@ func_end:
>  *  Purpose:
>  *      Frees a previously reserved region of DSP address space.
>  */
>-DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR hProcessor, void *pRsvAddr)
>+DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR hProcessor, void *pRsvAddr,
>+		struct PROCESS_CONTEXT *pr_ctxt, int cleanup)
> {
> 	struct DMM_OBJECT *hDmmMgr;
> 	DSP_STATUS status = DSP_SOK;
> 	struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor;
>+	struct DMM_RSV_OBJECT *temp, *rsv_obj;
>
> 	GT_2trace(PROC_DebugMask, GT_ENTER,
> 		 "Entered PROC_UnReserveMemory, args:\n\t"
>@@ -1719,18 +1735,38 @@ DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR
>hProcessor, void *pRsvAddr)
> 			 "InValid Processor Handle \n");
> 		goto func_end;
> 	}
>+
> 	status = DMM_GetHandle(pProcObject, &hDmmMgr);
>-	if (DSP_FAILED(status))
>+	if (DSP_FAILED(status)) {
> 		GT_1trace(PROC_DebugMask, GT_7CLASS,
> 			 "PROC_UnReserveMemory: Failed to get DMM Mgr "
> 			 "handle: 0x%x\n", status);
>-	else
>-		status = DMM_UnReserveMemory(hDmmMgr, (u32) pRsvAddr);
>+		goto func_end;
>+	}
>+
>+	status = DMM_UnReserveMemory(hDmmMgr, (u32) pRsvAddr);
>+
>+	/*
>+	 * cleanup flag handles the special case when this function
>+	 * is called while doing clenaup from
>+	 * DRV_RemoveAllDMMResElements
>+	 */
>+	if (status != DSP_SOK || !cleanup)
>+		goto func_end;
>+
>+	spin_lock(&pr_ctxt->dmm_rsv_list_lock);
>+	list_for_each_entry_safe(rsv_obj, temp, &pr_ctxt->dmm_rsv_list, link)
>{
>+		if (rsv_obj->dsp_reserved_addr == (u32)pRsvAddr) {
>+			list_del(&rsv_obj->link);
>+			kfree(rsv_obj);
>+			break;
>+		}
>+	}
>+	spin_unlock(&pr_ctxt->dmm_rsv_list_lock);
>
>-	GT_1trace(PROC_DebugMask, GT_ENTER,
>-		 "Leaving PROC_UnReserveMemory [0x%x]",
>-		 status);
> func_end:
>+	GT_1trace(PROC_DebugMask, GT_ENTER,
>+		 "Leaving PROC_UnReserveMemory [0x%x]", status);
> 	return 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