diff options
author | Ben Jones <ben.jones@imgtec.com> | 2012-05-14 18:37:18 +0100 |
---|---|---|
committer | Android Partner Code Review <android-gerrit-partner@google.com> | 2012-05-14 12:42:38 -0700 |
commit | a447a75f417f2e9127afe0d21cdb8770b9b058f0 (patch) | |
tree | 05dc142c67da296233fbda75f0c78d1f73c20441 /drivers/gpu | |
parent | 4501c035d5e654c9243b714f421a19c4bd84e0fe (diff) | |
download | kernel_samsung_crespo-a447a75f417f2e9127afe0d21cdb8770b9b058f0.zip kernel_samsung_crespo-a447a75f417f2e9127afe0d21cdb8770b9b058f0.tar.gz kernel_samsung_crespo-a447a75f417f2e9127afe0d21cdb8770b9b058f0.tar.bz2 |
gpu: pvr: Update to DDK 1.8@905891
- Fix some bugs in the newly introduced memory pool code (b/6096575)
Change-Id: Ib505041f98ffedf9ae785c79d49ce719202cacb0
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/pvr/mm.c | 133 | ||||
-rw-r--r-- | drivers/gpu/pvr/pvrversion.h | 4 |
2 files changed, 80 insertions, 57 deletions
diff --git a/drivers/gpu/pvr/mm.c b/drivers/gpu/pvr/mm.c index 2ca2b47..ecad206 100644 --- a/drivers/gpu/pvr/mm.c +++ b/drivers/gpu/pvr/mm.c @@ -56,9 +56,11 @@ #include <linux/highmem.h> #include <linux/sched.h> +#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) #include <linux/shrinker.h> #endif +#endif #include "img_defs.h" #include "services.h" @@ -78,6 +80,8 @@ #include "lists.h" #endif +static atomic_t g_sPagePoolEntryCount = ATOMIC_INIT(0); + #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) typedef enum { DEBUG_MEM_ALLOC_TYPE_KMALLOC, @@ -121,8 +125,14 @@ static DEBUG_MEM_ALLOC_REC *g_MemoryRecords; static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; -static IMG_UINT32 g_SysRAMWaterMark; -static IMG_UINT32 g_SysRAMHighWaterMark; +static IMG_UINT32 g_SysRAMWaterMark; +static IMG_UINT32 g_SysRAMHighWaterMark; + +static inline IMG_UINT32 +SysRAMTrueWaterMark(void) +{ + return g_SysRAMWaterMark + PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount)); +} static IMG_UINT32 g_IOMemWaterMark; static IMG_UINT32 g_IOMemHighWaterMark; @@ -204,7 +214,6 @@ static LinuxKMemCache *g_PsLinuxPagePoolCache; static LIST_HEAD(g_sPagePoolList); static int g_iPagePoolMaxEntries; -static atomic_t g_sPagePoolEntryCount = ATOMIC_INIT(0); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length); @@ -220,11 +229,18 @@ static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea); #endif -static inline IMG_BOOL AreaIsUncached(IMG_UINT32 ui32AreaFlags) +static inline IMG_BOOL +AreaIsUncached(IMG_UINT32 ui32AreaFlags) { return (ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED)) != 0; } +static inline IMG_BOOL +CanFreeToPool(LinuxMemArea *psLinuxMemArea) +{ + return AreaIsUncached(psLinuxMemArea->ui32AreaFlags) && !psLinuxMemArea->bNeedsCacheInvalidate; +} + IMG_VOID * _KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) { @@ -304,10 +320,14 @@ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType, || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) { + IMG_UINT32 ui32SysRAMTrueWaterMark; + g_SysRAMWaterMark += ui32Bytes; - if (g_SysRAMWaterMark > g_SysRAMHighWaterMark) + ui32SysRAMTrueWaterMark = SysRAMTrueWaterMark(); + + if (ui32SysRAMTrueWaterMark > g_SysRAMHighWaterMark) { - g_SysRAMHighWaterMark = g_SysRAMWaterMark; + g_SysRAMHighWaterMark = ui32SysRAMTrueWaterMark; } } else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP @@ -620,7 +640,7 @@ FreePageToLinux(struct page *psPage) } -#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) +#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) static DEFINE_MUTEX(g_sPagePoolMutex); static inline void @@ -641,7 +661,7 @@ PagePoolTrylock(void) return mutex_trylock(&g_sPagePoolMutex); } -#else +#else static inline void PagePoolLock(void) { @@ -657,7 +677,8 @@ PagePoolTrylock(void) { return 1; } -#endif +#endif + static inline void AddEntryToPool(LinuxPagePoolEntry *psPagePoolEntry) @@ -695,7 +716,7 @@ RemoveFirstEntryFromPool(void) } static struct page * -AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPageCache) +AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPagePool) { struct page *psPage = NULL; @@ -713,7 +734,7 @@ AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPageCache) { psPage = psPagePoolEntry->psPage; LinuxPagePoolEntryFree(psPagePoolEntry); - *pbFromPageCache = IMG_TRUE; + *pbFromPagePool = IMG_TRUE; } } @@ -722,7 +743,7 @@ AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPageCache) psPage = AllocPageFromLinux(); if (psPage) { - *pbFromPageCache = IMG_FALSE; + *pbFromPagePool = IMG_FALSE; } } @@ -731,10 +752,10 @@ AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPageCache) } static IMG_VOID -FreePage(IMG_UINT32 ui32AreaFlags, struct page *psPage) +FreePage(IMG_BOOL bToPagePool, struct page *psPage) { - if (AreaIsUncached(ui32AreaFlags) && atomic_read(&g_sPagePoolEntryCount) < g_iPagePoolMaxEntries) + if (bToPagePool && atomic_read(&g_sPagePoolEntryCount) < g_iPagePoolMaxEntries) { LinuxPagePoolEntry *psPagePoolEntry = LinuxPagePoolEntryAlloc(); if (psPagePoolEntry) @@ -761,6 +782,9 @@ FreePagePool(IMG_VOID) #if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) PVR_TRACE(("%s: Freeing %d pages from pool", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount))); +#else + PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0); + PVR_ASSERT(list_empty(&g_sPagePoolList)); #endif list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem) @@ -781,7 +805,8 @@ FreePagePool(IMG_VOID) static struct shrinker g_sShrinker; #endif -static int ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) +static int +ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) { unsigned long uNumToScan = psShrinkControl->nr_to_scan; @@ -829,13 +854,13 @@ static int ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *ps #endif static IMG_BOOL -AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *phBlockPageList, IMG_UINT32 ui32NumPages, IMG_BOOL *pbFromPageCache) +AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *phBlockPageList, IMG_UINT32 ui32NumPages, IMG_BOOL *pbFromPagePool) { struct page **ppsPageList; IMG_HANDLE hBlockPageList; IMG_INT32 i; PVRSRV_ERROR eError; - IMG_BOOL bFromPageCache = IMG_FALSE; + IMG_BOOL bFromPagePool = IMG_FALSE; eError = OSAllocMem(0, sizeof(*ppsPageList) * ui32NumPages, (IMG_VOID **)&ppsPageList, &hBlockPageList, "Array of pages"); @@ -844,26 +869,38 @@ AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *ph goto failed_page_list_alloc; } - *pbFromPageCache = IMG_TRUE; + *pbFromPagePool = IMG_TRUE; for(i = 0; i < (IMG_INT32)ui32NumPages; i++) { - ppsPageList[i] = AllocPage(ui32AreaFlags, &bFromPageCache); + ppsPageList[i] = AllocPage(ui32AreaFlags, &bFromPagePool); if (!ppsPageList[i]) { goto failed_alloc_pages; } - *pbFromPageCache &= bFromPageCache; + *pbFromPagePool &= bFromPagePool; } *pppsPageList = ppsPageList; *phBlockPageList = hBlockPageList; +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, + ppsPageList, + 0, + 0, + NULL, + PAGES_TO_BYTES(ui32NumPages), + "unknown", + 0 + ); +#endif + return IMG_TRUE; failed_alloc_pages: for(i--; i >= 0; i--) { - FreePage(ui32AreaFlags, ppsPageList[i]); + FreePage(*pbFromPagePool, ppsPageList[i]); } (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList); @@ -873,15 +910,19 @@ failed_page_list_alloc: static IMG_VOID -FreePages(IMG_UINT32 ui32AreaFlags, struct page **ppsPageList, IMG_HANDLE hBlockPageList, IMG_UINT32 ui32NumPages) +FreePages(IMG_BOOL bToPagePool, struct page **ppsPageList, IMG_HANDLE hBlockPageList, IMG_UINT32 ui32NumPages) { IMG_INT32 i; for(i = 0; i < (IMG_INT32)ui32NumPages; i++) { - FreePage(ui32AreaFlags, ppsPageList[i]); + FreePage(bToPagePool, ppsPageList[i]); } +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, ppsPageList, __FILE__, __LINE__); +#endif + (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList); } @@ -896,7 +937,7 @@ NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) struct page **ppsPageList = NULL; IMG_HANDLE hBlockPageList; #endif - IMG_BOOL bFromPageCache; + IMG_BOOL bFromPagePool = IMG_FALSE; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) @@ -907,7 +948,7 @@ NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) #if defined(PVR_LINUX_MEM_AREA_USE_VMAP) ui32NumPages = RANGE_TO_PAGES(ui32Bytes); - if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPageCache)) + if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool)) { goto failed; } @@ -919,7 +960,6 @@ NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) { goto failed; } - bFromPageCache = IMG_FALSE; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) ReservePages(pvCpuVAddr, ui32Bytes); @@ -941,10 +981,9 @@ NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) #endif - if (!bFromPageCache && AreaIsUncached(ui32AreaFlags)) + if (AreaIsUncached(ui32AreaFlags) && !bFromPagePool) { OSInvalidateCPUCacheRangeKM(psLinuxMemArea, pvCpuVAddr, ui32Bytes); - } return psLinuxMemArea; @@ -954,7 +993,7 @@ failed: #if defined(PVR_LINUX_MEM_AREA_USE_VMAP) if (ppsPageList) { - FreePages(psLinuxMemArea->ui32AreaFlags, ppsPageList, hBlockPageList, ui32NumPages); + FreePages(bFromPagePool, ppsPageList, hBlockPageList, ui32NumPages); } #endif if (psLinuxMemArea) @@ -993,7 +1032,7 @@ FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea) ppsPageList = psLinuxMemArea->uData.sVmalloc.ppsPageList; hBlockPageList = psLinuxMemArea->uData.sVmalloc.hBlockPageList; - FreePages(psLinuxMemArea->ui32AreaFlags, ppsPageList, hBlockPageList, ui32NumPages); + FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages); #else #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress, @@ -1311,7 +1350,7 @@ NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) IMG_UINT32 ui32NumPages; struct page **ppsPageList; IMG_HANDLE hBlockPageList; - IMG_BOOL bFromPageCache; + IMG_BOOL bFromPagePool; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) @@ -1321,23 +1360,11 @@ NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) ui32NumPages = RANGE_TO_PAGES(ui32Bytes); - if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPageCache)) + if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool)) { goto failed_alloc_pages; } -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) - DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, - ppsPageList, - 0, - 0, - NULL, - PAGE_ALIGN(ui32Bytes), - "unknown", - 0 - ); -#endif - psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; psLinuxMemArea->uData.sPageList.ppsPageList = ppsPageList; psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList; @@ -1346,7 +1373,7 @@ NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); - psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags) && !bFromPageCache; + psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags) && !bFromPagePool; #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); @@ -1381,11 +1408,7 @@ FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea) ppsPageList = psLinuxMemArea->uData.sPageList.ppsPageList; hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList; -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) - DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, ppsPageList, __FILE__, __LINE__); -#endif - - FreePages(psLinuxMemArea->ui32AreaFlags, ppsPageList, hBlockPageList, ui32NumPages); + FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages); LinuxMemAreaStructFree(psLinuxMemArea); } @@ -2250,7 +2273,7 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el) "Highest Water Mark of bytes mapped via vmap", g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]); #endif -#if PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0 +#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) seq_printf(sfile, "%-60s: %d pages\n", "Number of pages in page pool", atomic_read(&g_sPagePoolEntryCount)); @@ -2258,7 +2281,7 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el) seq_printf( sfile, "\n"); seq_printf(sfile, "%-60s: %d bytes\n", "The Current Water Mark for memory allocated from system RAM", - g_SysRAMWaterMark); + SysRAMTrueWaterMark()); seq_printf(sfile, "%-60s: %d bytes\n", "The Highest Water Mark for memory allocated from system RAM", g_SysRAMHighWaterMark); @@ -2331,7 +2354,7 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el) #endif seq_printf(sfile, "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n", - g_SysRAMWaterMark); + SysRAMTrueWaterMark()); seq_printf(sfile, "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n", g_SysRAMHighWaterMark); @@ -2342,7 +2365,7 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el) "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n", g_IOMemHighWaterMark); -#if PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0 +#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) seq_printf(sfile, "<watermark key=\"mr18\" description=\"page_pool_current\" bytes=\"%d\"/>\n", PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount))); @@ -2656,7 +2679,7 @@ LinuxMMInit(IMG_VOID) goto failed; } -#if PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0 +#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) g_iPagePoolMaxEntries = PVR_LINUX_MEM_AREA_POOL_MAX_PAGES; if (g_iPagePoolMaxEntries <= 0 || g_iPagePoolMaxEntries > INT_MAX/2) { diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h index 3cbc693..28a2f45 100644 --- a/drivers/gpu/pvr/pvrversion.h +++ b/drivers/gpu/pvr/pvrversion.h @@ -36,7 +36,7 @@ #define PVRVERSION_FAMILY "sgxddk" #define PVRVERSION_BRANCHNAME "1.8" -#define PVRVERSION_BUILD 904153 +#define PVRVERSION_BUILD 905891 #define PVRVERSION_BSCONTROL "CustomerGoogle_Android_ogles1_ogles2_GPL" #define PVRVERSION_STRING "CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@" PVR_STR2(PVRVERSION_BUILD) @@ -45,7 +45,7 @@ #define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved." #define PVRVERSION_BUILD_HI 90 -#define PVRVERSION_BUILD_LO 4153 +#define PVRVERSION_BUILD_LO 5891 #define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO) #endif /* _PVRVERSION_H_ */ |