void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea)
{
	u32 ui32PageCount;
	struct page **pvPageList;
	void *hBlockPageList;
	u32 i;

	PVR_ASSERT(psLinuxMemArea);
	PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);

#if defined(DEBUG_LINUX_MEM_AREAS)
	DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
#endif

	ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
	pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
	hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;

#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList,
				  __FILE__, __LINE__);
#endif

	for (i = 0; i < ui32PageCount; i++)
		__free_pages(pvPageList[i], 0);

	OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList,
			hBlockPageList);

	LinuxMemAreaStructFree(psLinuxMemArea);
}
void _VFreeWrapper(void *pvCpuVAddr, char *pszFileName, u32 ui32Line)
{
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr,
				  pszFileName, ui32Line);
#endif
	vfree(pvCpuVAddr);
}
void _KMemCacheFreeWrapper(struct kmem_cache *psCache, void *pvObject,
		      char *pszFileName, u32 ui32Line)
{
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject,
				  pszFileName, ui32Line);
#endif

	kmem_cache_free(psCache, pvObject);
}
void _IOUnmapWrapper(void __iomem *pvIORemapCookie, char *pszFileName,
		u32 ui32Line)
{
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
				  (__force void *)pvIORemapCookie,
				  pszFileName, ui32Line);
#endif
	iounmap(pvIORemapCookie);
}
Example #5
0
void _KUnMapWrapper(struct page *psPage, char *pszFileName,
	       u32 ui32Line)
{
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMAP, psPage,
				  pszFileName, ui32Line);
#endif

	kunmap(psPage);
}
void FreeIOLinuxMemArea(struct LinuxMemArea *psLinuxMemArea)
{
	PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO);

#if defined(DEBUG_LINUX_MEM_AREAS)
	DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
#endif

#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO,
				  (void *)psLinuxMemArea->uData.sIO.
				  CPUPhysAddr.uiAddr, __FILE__, __LINE__);
#endif

	LinuxMemAreaStructFree(psLinuxMemArea);
}
void LinuxMMCleanup(void)
{
#if defined(DEBUG_LINUX_MEM_AREAS)
	{
		struct DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord =
		    g_LinuxMemAreaRecords, *psNextRecord;

		if (g_LinuxMemAreaCount)
			PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
				"There are %d struct LinuxMemArea "
				"allocation unfreed (%ld bytes)",
				 __func__, g_LinuxMemAreaCount,
				 g_LinuxMemAreaWaterMark);

		while (psCurrentRecord) {
			struct LinuxMemArea *psLinuxMemArea;

			psNextRecord = psCurrentRecord->psNext;
			psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
			PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
				"Cleaning up Linux memory area (%p), "
				"type=%s, size=%ld bytes",
				 __func__, psCurrentRecord->psLinuxMemArea,
				 LinuxMemAreaTypeToString(psCurrentRecord->
							  psLinuxMemArea->
							  eAreaType),
				 psCurrentRecord->psLinuxMemArea->
				 ui32ByteSize);

			LinuxMemAreaDeepFree(psLinuxMemArea);

			psCurrentRecord = psNextRecord;
		}
		RemoveProcEntry("mem_areas");
	}
#endif

#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
	{
		struct DEBUG_MEM_ALLOC_REC *psCurrentRecord =
		    g_MemoryRecords, *psNextRecord;

		while (psCurrentRecord) {
			psNextRecord = psCurrentRecord->psNext;
			PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
				 "type=%s CpuVAddr=%p CpuPAddr=0x%08lx, "
				 "allocated @ file=%s,line=%d",
				 __func__,
				 DebugMemAllocRecordTypeToString
				 (psCurrentRecord->eAllocType),
				 psCurrentRecord->pvCpuVAddr,
				 psCurrentRecord->ulCpuPAddr,
				 psCurrentRecord->pszFileName,
				 psCurrentRecord->ui32Line);
			switch (psCurrentRecord->eAllocType) {
			case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
				KFreeWrapper(psCurrentRecord->pvCpuVAddr);
				break;
			case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
				IOUnmapWrapper((__force __iomem void *)
						psCurrentRecord->pvCpuVAddr);
				break;
			case DEBUG_MEM_ALLOC_TYPE_IO:

				DebugMemAllocRecordRemove
				    (DEBUG_MEM_ALLOC_TYPE_IO,
				     psCurrentRecord->pvKey, __FILE__,
				     __LINE__);
				break;
			case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
				VFreeWrapper(psCurrentRecord->pvCpuVAddr);
				break;
			case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:

				DebugMemAllocRecordRemove
				    (DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
				     psCurrentRecord->pvKey, __FILE__,
				     __LINE__);
				break;
			case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
				KMemCacheFreeWrapper(psCurrentRecord->
							     pvPrivateData,
						     psCurrentRecord->
							     pvCpuVAddr);
				break;
			default:
				PVR_ASSERT(0);
			}
			psCurrentRecord = psNextRecord;
		}
		RemoveProcEntry("meminfo");
	}
#endif

	if (psLinuxMemAreaCache) {
		kmem_cache_destroy(psLinuxMemAreaCache);
		psLinuxMemAreaCache = NULL;
	}
}