Re: [PATCH 1/4] [OMAPZOOM] DSPBRIDGE: Memory lock for DMM.

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

 



Hi,

From: "ext Guzman Lugo, Fernando" <x0095840@xxxxxx>
Subject: RE: [PATCH 1/4] [OMAPZOOM] DSPBRIDGE: Memory lock for DMM.
Date: Fri, 27 Mar 2009 03:04:39 +0100

> 
> Hi,
> 	I am resending this patch because the previous one has an error.
> 
> 
> From 81c5b93ad42c40179c2b271f61814f0b4035440c Mon Sep 17 00:00:00 2001
> From: Hari Kanigeri <h-kanigeri2@xxxxxx>
> Date: Thu, 26 Mar 2009 15:47:50 -0500
> Subject: [PATCH] DSPBRIDGE: Memory lock for DMM.
> 
> Lock down the pages that are mapped to DSP virtual memory to prevent from
> getting swapped out

Hm....for this page swapping case, I think that handling this issue in
kernel may cause more complexity and this can be avoided by "mlock()"
for that buffer in userland? This looks more sipmpler?

> 
> Signed-off-by: Hari Kanigeri <h-kanigeri2@xxxxxx>
> ---
>  arch/arm/plat-omap/include/dspbridge/dbdefs.h |    3 +
>  drivers/dsp/bridge/hw/hw_mmu.h                |    1 +
>  drivers/dsp/bridge/wmd/io_sm.c                |   24 +++--
>  drivers/dsp/bridge/wmd/tiomap3430.c           |  133 +++++++++++++++++++++++-
>  4 files changed, 144 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/include/dspbridge/dbdefs.h b/arch/arm/plat-omap/include/dspbridge/dbdefs.h
> index 7f5a2bf..9782693
> --- a/arch/arm/plat-omap/include/dspbridge/dbdefs.h
> +++ b/arch/arm/plat-omap/include/dspbridge/dbdefs.h
> @@ -571,6 +571,9 @@ bit 6 - MMU element size = 64bit (valid only for non mixed page entries)
>  
>  #define DSP_MAPVMALLOCADDR         0x00000080
>  
> +#define DSP_MAPDONOTLOCK	   0x00000100
> +
> +
>  #define GEM_CACHE_LINE_SIZE     128
>  #define GEM_L1P_PREFETCH_SIZE   128
>  
> diff --git a/drivers/dsp/bridge/hw/hw_mmu.h b/drivers/dsp/bridge/hw/hw_mmu.h
> index 065f0dd..b1e2458
> --- a/drivers/dsp/bridge/hw/hw_mmu.h
> +++ b/drivers/dsp/bridge/hw/hw_mmu.h
> @@ -51,6 +51,7 @@ struct HW_MMUMapAttrs_t {
>  	enum HW_Endianism_t     endianism;
>  	enum HW_ElementSize_t   elementSize;
>  	enum HW_MMUMixedSize_t  mixedSize;
> +	bool donotlockmpupage;
>  } ;
>  
>  extern HW_STATUS HW_MMU_Enable(const void __iomem *baseAddress);
> diff --git a/drivers/dsp/bridge/wmd/io_sm.c b/drivers/dsp/bridge/wmd/io_sm.c
> index bd936eb..301bd72 100755
> --- a/drivers/dsp/bridge/wmd/io_sm.c
> +++ b/drivers/dsp/bridge/wmd/io_sm.c
> @@ -553,6 +553,8 @@ func_cont1:
>  	mapAttrs = DSP_MAPLITTLEENDIAN;
>  	mapAttrs |= DSP_MAPPHYSICALADDR;
>  	mapAttrs |= DSP_MAPELEMSIZE32;
> +	mapAttrs |= DSP_MAPDONOTLOCK;
> +
>  	while (numBytes && DSP_SUCCEEDED(status)) {
>  		/* To find the max. page size with which both PA & VA are
>  		 * aligned */
> @@ -690,18 +692,18 @@ func_cont:
>  	mapAttrs = DSP_MAPLITTLEENDIAN;
>  	mapAttrs |= DSP_MAPPHYSICALADDR;
>  	mapAttrs |= DSP_MAPELEMSIZE32;
> +	mapAttrs |= DSP_MAPDONOTLOCK;
> +
>  	/* Map the L4 peripherals */
> -	{
> -		i = 0;
> -		while (L4PeripheralTable[i].physAddr && DSP_SUCCEEDED(status)) {
> -				status = hIOMgr->pIntfFxns->pfnBrdMemMap
> -					(hIOMgr->hWmdContext,
> -					L4PeripheralTable[i].physAddr,
> -					L4PeripheralTable[i].dspVirtAddr,
> -					HW_PAGE_SIZE_4KB, mapAttrs);
> -				DBC_Assert(DSP_SUCCEEDED(status));
> -				i++;
> -		}
> +	i = 0;
> +	while (L4PeripheralTable[i].physAddr && DSP_SUCCEEDED(status)) {
> +		status = hIOMgr->pIntfFxns->pfnBrdMemMap
> +			(hIOMgr->hWmdContext, L4PeripheralTable[i].physAddr,
> +			L4PeripheralTable[i].dspVirtAddr, HW_PAGE_SIZE_4KB,
> +			mapAttrs);
> +		if (DSP_FAILED(status))
> +			break;
> +		i++;
>  	}
>  
>  	if (DSP_SUCCEEDED(status)) {
> diff --git a/drivers/dsp/bridge/wmd/tiomap3430.c b/drivers/dsp/bridge/wmd/tiomap3430.c
> index 7f20574..1a97305 100755
> --- a/drivers/dsp/bridge/wmd/tiomap3430.c
> +++ b/drivers/dsp/bridge/wmd/tiomap3430.c
> @@ -28,6 +28,8 @@
>  
>  /*  ----------------------------------- Host OS */
>  #include <dspbridge/host_os.h>
> +#include <linux/mm.h>
> +#include <linux/mmzone.h>
>  #include "../arch/arm/mach-omap2/prcm-regs.h"
>  #include "../arch/arm/mach-omap2/cm-regbits-34xx.h"
>  #include "../arch/arm/mach-omap2/ti-compat.h"
> @@ -90,6 +92,7 @@
>  #define MMU_LARGE_PAGE_MASK      0xFFFF0000
>  #define MMU_SMALL_PAGE_MASK      0xFFFFF000
>  #define PAGES_II_LVL_TABLE   512
> +#define phys_to_page(phys)      pfn_to_page((phys) >> PAGE_SHIFT)
>  
>  #define MMU_GFLUSH 0x60
>  
> @@ -1372,6 +1375,11 @@ static DSP_STATUS WMD_BRD_MemMap(struct WMD_DEV_CONTEXT *hDevContext,
>  			return DSP_EINVALIDARG;
>  		}
>  	}
> +	if (attrs & DSP_MAPDONOTLOCK)
> +		hwAttrs.donotlockmpupage = 1;
> +	else
> +		hwAttrs.donotlockmpupage = 0;
> +
>  	if (attrs & DSP_MAPVMALLOCADDR) {
>  		status = MemMapVmalloc(hDevContext, ulMpuAddr, ulVirtAddr,
>  				       ulNumBytes, ulMapAttr);
> @@ -1488,12 +1496,20 @@ static DSP_STATUS WMD_BRD_MemUnMap(struct WMD_DEV_CONTEXT *hDevContext,
>  	u32 remBytes;
>  	u32 remBytesL2;
>  	u32 vaCurr;
> +	struct page *pg;
>  	DSP_STATUS status = DSP_SOK;
>  	struct WMD_DEV_CONTEXT *pDevContext = hDevContext;
>  	struct PgTableAttrs *pt = pDevContext->pPtAttrs;
> +	u32 pacount = 0;
> +	u32 *pPhysAddrPageTbl = NULL;
> +	u32 temp;
> +	u32 patemp = 0;
> +	u32 pAddr;
> +	u32 numof4KPages = 0;
>  
>  	DBG_Trace(DBG_ENTER, "> WMD_BRD_MemUnMap hDevContext %x, va %x, "
>  		  "NumBytes %x\n", hDevContext, ulVirtAddr, ulNumBytes);
> +	pPhysAddrPageTbl = DMM_GetPhysicalAddrTable();
>  	vaCurr = ulVirtAddr;
>  	remBytes = ulNumBytes;
>  	remBytesL2 = 0;
> @@ -1542,6 +1558,19 @@ static DSP_STATUS WMD_BRD_MemUnMap(struct WMD_DEV_CONTEXT *hDevContext,
>  				/* vaCurr aligned to pteSize? */
>  				if ((pteSize != 0) && (remBytesL2 >= pteSize) &&
>  				   !(vaCurr & (pteSize - 1))) {
> +					/* Collect Physical addresses from VA */
> +					pAddr = (pteVal & ~(pteSize - 1));
> +					if (pteSize == HW_PAGE_SIZE_64KB)
> +						numof4KPages = 16;
> +					else
> +						numof4KPages = 1;
> +					temp = 0;
> +					while (temp++ < numof4KPages) {
> +						pPhysAddrPageTbl[pacount++] =
> +									pAddr;
> +						pAddr += HW_PAGE_SIZE_4KB;
> +					}
> +
>  					if (HW_MMU_PteClear(pteAddrL2,
>  						vaCurr, pteSize) == RET_OK) {
>  						status = DSP_SOK;
> @@ -1602,6 +1631,20 @@ static DSP_STATUS WMD_BRD_MemUnMap(struct WMD_DEV_CONTEXT *hDevContext,
>  	 * get flushed */
>  EXIT_LOOP:
>  	flush_all(pDevContext);
> +	temp = 0;
> +	while (temp < pacount) {
> +		patemp = pPhysAddrPageTbl[temp];
> +		if (pfn_valid(__phys_to_pfn(patemp))) {
> +			pg = phys_to_page(patemp);
> +			if (page_count(pg) <= 0)
> +				printk(KERN_INFO "DSPBRIDGE:UNMAP function: "
> +					"COUNT 0 FOR PA 0x%x, size = 0x%x\n",
> +					patemp, ulNumBytes);
> +			SetPageDirty(pg);
> +			page_cache_release(pg);
> +		}
> +		temp++;
> +	}
>  	DBG_Trace(DBG_LEVEL1, "WMD_BRD_MemUnMap vaCurr %x, pteAddrL1 %x "
>  		  "pteAddrL2 %x\n", vaCurr, pteAddrL1, pteAddrL2);
>  	DBG_Trace(DBG_ENTER, "< WMD_BRD_MemUnMap status %x remBytes %x, "
> @@ -1633,11 +1676,20 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  	u32 temp = 0;
>  	u32 numUsrPgs;
>  	struct task_struct *curr_task = current;
> +	struct vm_area_struct *vma;
> +	u32  write = 0;
> +
>  
>  	DBG_Trace(DBG_ENTER, "TIOMAP_VirtToPhysical: START:ulMpuAddr=%x, "
>  		  "ulNumBytes=%x\n", ulMpuAddr, ulNumBytes);
>  	if (physicalAddrTable == NULL)
>  		return DSP_EMEMORY;
> +	down_read(&mm->mmap_sem);
> +	vma = find_vma(mm, ulMpuAddr);
> +	up_read(&mm->mmap_sem);
> +
> +	if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
> +		write = 1;
>  	while (ulNumBytes) {
>  		DBG_Trace(DBG_LEVEL4, "TIOMAP_VirtToPhysical:Read the next PGD "
>  			  "and PMD entry\n");
> @@ -1660,7 +1712,7 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  			 * page tables
>  			 */
>  			numUsrPgs = get_user_pages(curr_task, mm, ulMpuAddr, 1,
> -							true, 0, NULL, NULL);
> +							write, 1, NULL, NULL);
>  			up_read(&mm->mmap_sem);
>  			/* Get the first level page table entry information */
>  			/* Read the pointer to first level page table entry */
> @@ -1704,7 +1756,7 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  					 * the page tables */
>  					if (numUsrPgs <= PAGES_II_LVL_TABLE) {
>  						get_user_pages(curr_task, mm,
> -						ulMpuAddr, numUsrPgs, true,  0,
> +						ulMpuAddr, numUsrPgs, write,  1,
>  						NULL, NULL);
>  						DBG_Trace(DBG_LEVEL4,
>  						"get_user_pages, numUsrPgs"
> @@ -1712,7 +1764,7 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  					} else {
>  						get_user_pages(curr_task, mm,
>  						ulMpuAddr, PAGES_II_LVL_TABLE,
> -						true, 0, NULL, NULL);
> +						write, 1, NULL, NULL);
>  						DBG_Trace(DBG_LEVEL4,
>  						"get_user_pages, numUsrPgs"
>  						"= %d\n", PAGES_II_LVL_TABLE);
> @@ -1737,7 +1789,12 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  					pAddr = pteVal & MMU_LARGE_PAGE_MASK;
>  					chunkSz = HW_PAGE_SIZE_64KB;
>  					numEntries = 16;
> -					numof4KPages = 16;
> +					if (ulNumBytes >= HW_PAGE_SIZE_64KB)
> +						numof4KPages = 16;
> +					else {
> +						numof4KPages = ulNumBytes /
> +							HW_PAGE_SIZE_4KB;
> +					}
>  					break;
>  				case HW_PAGE_SIZE_4KB:
>  					pAddr = pteVal & MMU_SMALL_PAGE_MASK;
> @@ -1769,7 +1826,10 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  					ulMpuAddr += chunkSz;
>  					/* Update the number of bytes that
>  					 * are copied */
> -					ulNumBytes -= chunkSz;
> +					if (chunkSz > ulNumBytes)
> +						ulNumBytes = 0;
> +					else
> +						ulNumBytes -= chunkSz;
>  					DBG_Trace(DBG_LEVEL4,
>  						"TIOMAP_VirtToPhysical: mpuCurr"
>  						" = %x, pagesize = %x, "
> @@ -1792,10 +1852,16 @@ static DSP_STATUS TIOMAP_VirtToPhysical(struct mm_struct *mm, u32 ulMpuAddr,
>  			switch (pteSize) {
>  			case HW_PAGE_SIZE_16MB:
>  				pAddr = pteVal & MMU_SSECTION_ADDR_MASK;
> +				if (ulNumBytes >= HW_PAGE_SIZE_16MB) {
>  					chunkSz = HW_PAGE_SIZE_16MB;
>  					numEntries = 16;
>  					numof4KPages = 4096;
> -					break;
> +				} else {
> +					chunkSz = HW_PAGE_SIZE_1MB;
> +					numEntries = 1;
> +					numof4KPages = 256;
> +				}
> +				break;
>  			case HW_PAGE_SIZE_1MB:
>  				pAddr = pteVal & MMU_SECTION_ADDR_MASK;
>  					chunkSz = HW_PAGE_SIZE_1MB;
> @@ -1909,9 +1975,64 @@ static DSP_STATUS PteSet(struct PgTableAttrs *pt, u32 pa, u32 va,
>  	u32 L2BaseVa = 0;
>  	u32 L2BasePa = 0;
>  	u32 L2PageNum = 0;
> +	u32 num4KEntries = 0;
> +	u32 temp = 0;
> +	struct page *pg;
> +	u32 patemp;
> +
>  	DSP_STATUS status = DSP_SOK;
>  	DBG_Trace(DBG_ENTER, "> PteSet pPgTableAttrs %x, pa %x, va %x, "
>  		 "size %x, attrs %x\n", pt, pa, va, size, attrs);
> +	/* Lock the MPU pages that are getting mapped if this
> +	 * attribute is set */
> +	if (attrs->donotlockmpupage == 0) {
> +		switch (size) {
> +		case HW_PAGE_SIZE_64KB:
> +			num4KEntries = 16;
> +			break;
> +		case HW_PAGE_SIZE_4KB:
> +			num4KEntries = 1;
> +			break;
> +		case HW_PAGE_SIZE_16MB:
> +			num4KEntries = 4096;
> +			break;
> +		case HW_PAGE_SIZE_1MB:
> +			num4KEntries = 256;
> +			break;
> +		default:
> +			return DSP_EFAIL;
> +		}
> +		patemp = pa;
> +		while (temp++ < num4KEntries) {
> +			/* FIXME: This is a hack to avoid getting pages for
> +			 *  video overlay		*/
> +			if (pfn_valid(__phys_to_pfn(patemp))) {
> +				pg = phys_to_page(patemp);
> +				get_page(pg);
> +			}
> +			if (page_count(pg) <= 1) {
> +				printk(KERN_EMERG "DSPBRIDGE:MAP  function: "
> +					"COUNT 0 FOR PA 0x%x\n", patemp);
> +				printk(KERN_EMERG "Bad page state"
> +					KERN_EMERG "in process '%s'\n"
> +					KERN_EMERG "page:%p flags:0x%0*lx "
> +					KERN_EMERG "mapping:%p mapcount:%d "
> +					KERN_EMERG "count:%d\n"
> +					KERN_EMERG "Trying to fix it up, but "
> +					KERN_EMERG "a reboot is needed\n"
> +					KERN_EMERG "Backtrace:\n",
> +					current->comm, pg,
> +					(int)(2*sizeof(unsigned long)),
> +					(unsigned long)pg->flags, pg->mapping,
> +					page_mapcount(pg), page_count(pg));
> +				dump_stack();
> +				BUG_ON(1);
> +			}
> +
> +			patemp += HW_PAGE_SIZE_4KB;
> +		}
> +	}
> +	attrs->donotlockmpupage = 0;
>  	L1BaseVa = pt->L1BaseVa;
>  	pgTblVa = L1BaseVa;
>  	if ((size == HW_PAGE_SIZE_64KB) || (size == HW_PAGE_SIZE_4KB)) {
> -- 
> 1.5.6.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
--
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