aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Jones <ben.jones@imgtec.com>2012-05-14 18:37:18 +0100
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2012-05-14 12:42:38 -0700
commita447a75f417f2e9127afe0d21cdb8770b9b058f0 (patch)
tree05dc142c67da296233fbda75f0c78d1f73c20441 /drivers/gpu
parent4501c035d5e654c9243b714f421a19c4bd84e0fe (diff)
downloadkernel_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.c133
-rw-r--r--drivers/gpu/pvr/pvrversion.h4
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_ */