From b2df404741a2af09c139e0b16bbf371a5e7bf758 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E6=9D=9C=E5=9D=A4=E6=98=8E?= Date: Sat, 14 May 2011 11:43:34 +0800 Subject: [PATCH] gpu: add allocnopage cache support for alloc_pages fail. --- .../os/linux/kernel/gc_hal_kernel_device.h | 39 +- .../os/linux/kernel/gc_hal_kernel_driver.c | 234 +++++++- .../hal/os/linux/kernel/gc_hal_kernel_os.c | 523 ++++++++++++++++-- .../hal/os/linux/kernel/gc_hal_kernel_os.h | 37 +- 4 files changed, 752 insertions(+), 81 deletions(-) mode change 100755 => 100644 drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c mode change 100755 => 100644 drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.h index 13c70f32f2d0..01629d99b85a 100644 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.h +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2010 by Vivante Corp. +* Copyright (C) 2005 - 2011 by Vivante Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -84,11 +84,36 @@ typedef struct _gckGALDEVICE * gckGALDEVICE; #if gcdkUSE_MEMORY_RECORD +typedef enum _gceMEMORY_TYPE +{ + gcvNON_PAGED_MEMORY = 0, + gcvCONTIGUOUS_MEMORY, + gcvVIDEO_MEMORY +} +gceMEMORY_TYPE; typedef struct MEMORY_RECORD { - gcuVIDMEM_NODE_PTR node; - gceSURF_TYPE type; - gctSIZE_T bytes; + gceMEMORY_TYPE type; + + union + { + struct + { + gctSIZE_T bytes; + gctPHYS_ADDR physical; + gctPOINTER logical; + } + Memory; + + struct + { + gcuVIDMEM_NODE_PTR node; + gceSURF_TYPE type; + gctSIZE_T bytes; + } + VideoMemory; + } + u; struct MEMORY_RECORD * prev; struct MEMORY_RECORD * next; @@ -104,6 +129,12 @@ typedef struct _gcsHAL_PRIVATE_DATA #if gcdkUSE_MEMORY_RECORD MEMORY_RECORD memoryRecordList; +#if gcdkREPORT_VIDMEM_USAGE + gctUINT64 allocatedMem[gcvSURF_NUM_TYPES]; + gctUINT64 maxAllocatedMem[gcvSURF_NUM_TYPES]; + gctUINT64 totalAllocatedMem; + gctUINT64 maxTotalAllocatedMem; +#endif #endif } gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR; diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c old mode 100755 new mode 100644 index 760a6fb84add..ea0de446c929 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -87,6 +87,90 @@ unsigned long coreClock = 552*1000000; module_param(coreClock, ulong, 0644); #endif +#if gcdkREPORT_VIDMEM_USAGE +#include + +static struct proc_dir_entry *s_gckGPUProc; +static gcsHAL_PRIVATE_DATA_PTR s_gckHalPrivate; + +static char * _MemTypes[gcvSURF_NUM_TYPES] = +{ + "UNKNOWN", /* gcvSURF_TYPE_UNKNOWN */ + "INDEX", /* gcvSURF_INDEX */ + "VERTEX", /* gcvSURF_VERTEX */ + "TEXTURE", /* gcvSURF_TEXTURE */ + "RT", /* gcvSURF_RENDER_TARGET */ + "DEPTH", /* gcvSURF_DEPTH */ + "BITMAP", /* gcvSURF_BITMAP */ + "TILE_STA", /* gcvSURF_TILE_STATUS */ + "MASK", /* gcvSURF_MASK */ + "SCISSOR", /* gcvSURF_SCISSOR */ + "HZ" /* gcvSURF_HIERARCHICAL_DEPTH */ +}; + +gctINT gvkGAL_Read_Proc(char *page, char **start, off_t offset, int count, int *eof, void *data) +{ + gctINT len = 0; + gctUINT type; + + len += sprintf(page+len, "------------------------------------\n"); + len += sprintf(page+len, " Type Current Max\n"); + + if(NULL == s_gckHalPrivate) + { + *eof = 1; + return len; + } + + for (type = 0; type < gcvSURF_NUM_TYPES; type++) + { + len += sprintf(page+len, "[%8s] %8llu KB %8llu KB\n", + _MemTypes[type], + s_gckHalPrivate->allocatedMem[type] / 1024, + s_gckHalPrivate->maxAllocatedMem[type] / 1024); + } + + len += sprintf(page+len, "[ TOTAL] %8llu KB %8llu KB\n", + s_gckHalPrivate->totalAllocatedMem / 1024, + s_gckHalPrivate->maxTotalAllocatedMem / 1024); + + *eof = 1; + return len; +} + + +static gctINT gckDeviceProc_Register(void) +{ + s_gckGPUProc = create_proc_read_entry("graphics/gpu", 0, NULL, gvkGAL_Read_Proc, NULL); + if(NULL == s_gckGPUProc) + { + return -1; + } + + return 0; +} + +static void gckDeviceProc_UnRegister(void) +{ + if(NULL != s_gckGPUProc) + { + struct proc_dir_entry *gckGPUPrarentProc = s_gckGPUProc->parent; + if(NULL == gckGPUPrarentProc) + { + return ; + } + + remove_proc_entry("gpu", gckGPUPrarentProc); + + /** no subdir */ + if(NULL == gckGPUPrarentProc->subdir) + { + remove_proc_entry("graphics", NULL); + } + } +} +#endif + int shutdown = 0; static int drv_open(struct inode *inode, struct file *filp); @@ -180,6 +264,9 @@ int drv_open(struct inode *inode, struct file* filp) { return -ENOTTY; } + /* Zero the memory. */ + gckOS_ZeroMemory(private, gcmSIZEOF(gcsHAL_PRIVATE_DATA)); + private->device = galDevice; private->mappedMemory = gcvNULL; @@ -203,6 +290,9 @@ int drv_open(struct inode *inode, struct file* filp) } filp->private_data = private; +#if gcdkREPORT_VIDMEM_USAGE + s_gckHalPrivate = private; +#endif return 0; } @@ -230,10 +320,10 @@ int drv_release(struct inode* inode, struct file* filp) device = private->device; #if gcdkUSE_MEMORY_RECORD - FreeAllMemoryRecord(galDevice->os, &private->memoryRecordList); + FreeAllMemoryRecord(galDevice->os, private, &private->memoryRecordList); #ifdef ANDROID - /* gcmkVERIFY_OK(gckOS_Delay(galDevice->os, 1000)); */ + gcmkVERIFY_OK(gckOS_Delay(galDevice->os, 1000)); #else gcmkVERIFY_OK(gckCOMMAND_Stall(device->kernel->command)); #endif @@ -253,6 +343,9 @@ int drv_release(struct inode* inode, struct file* filp) /* A process gets detached. */ gcmkVERIFY_OK( gckKERNEL_AttachProcess(galDevice->kernel, gcvFALSE)); +#if gcdkREPORT_VIDMEM_USAGE + s_gckHalPrivate = NULL; +#endif kfree(private); filp->private_data = NULL; @@ -351,19 +444,56 @@ int drv_ioctl(struct inode *inode, switch (record->iface.command) { + case gcvHAL_FREE_NON_PAGED_MEMORY: + mr = FindMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvNON_PAGED_MEMORY, + record->iface.u.FreeNonPagedMemory.bytes, + record->iface.u.FreeNonPagedMemory.physical, + record->iface.u.FreeNonPagedMemory.logical); + + if (mr != gcvNULL) + { + DestroyMemoryRecord(device->os, private, mr); + } + else + { + gcmkPRINT("*ERROR* Invalid non-paged memory for free"); + } + break; + + case gcvHAL_FREE_CONTIGUOUS_MEMORY: + mr = FindMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvCONTIGUOUS_MEMORY, + record->iface.u.FreeContiguousMemory.bytes, + record->iface.u.FreeContiguousMemory.physical, + record->iface.u.FreeContiguousMemory.logical); + + if (mr != gcvNULL) + { + DestroyMemoryRecord(device->os, private, mr); + } + else + { + gcmkPRINT("*ERROR* Invalid contiguous memory for free"); + } + break; case gcvHAL_FREE_VIDEO_MEMORY: - mr = FindMemoryRecord(device->os, - &private->memoryRecordList, - record->iface.u.FreeVideoMemory.node); + mr = FindVideoMemoryRecord(device->os, + private, + &private->memoryRecordList, + record->iface.u.FreeVideoMemory.node); if (mr != gcvNULL) { - DestoryMemoryRecord(device->os, mr); + DestroyVideoMemoryRecord(device->os, private, mr); } else { - printk("*ERROR* Invalid video memory (%p) for free\n", - record->iface.u.FreeVideoMemory.node); + gcmkPRINT("*ERROR* Invalid video memory for free"); } break; @@ -420,12 +550,75 @@ int drv_ioctl(struct inode *inode, } } #if gcdkUSE_MEMORY_RECORD + else if (iface.command == gcvHAL_ALLOCATE_NON_PAGED_MEMORY) + { + CreateMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvNON_PAGED_MEMORY, + iface.u.AllocateNonPagedMemory.bytes, + iface.u.AllocateNonPagedMemory.physical, + iface.u.AllocateNonPagedMemory.logical); + } + else if (iface.command == gcvHAL_FREE_NON_PAGED_MEMORY) + { + MEMORY_RECORD_PTR mr; + + mr = FindMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvNON_PAGED_MEMORY, + iface.u.FreeNonPagedMemory.bytes, + iface.u.FreeNonPagedMemory.physical, + iface.u.FreeNonPagedMemory.logical); + + if (mr != gcvNULL) + { + DestroyMemoryRecord(device->os, private, mr); + } + else + { + gcmkPRINT("*ERROR* Invalid non-paged memory for free"); + } + } + else if (iface.command == gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY) + { + CreateMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvCONTIGUOUS_MEMORY, + iface.u.AllocateContiguousMemory.bytes, + iface.u.AllocateContiguousMemory.physical, + iface.u.AllocateContiguousMemory.logical); + } + else if (iface.command == gcvHAL_FREE_CONTIGUOUS_MEMORY) + { + MEMORY_RECORD_PTR mr; + + mr = FindMemoryRecord(device->os, + private, + &private->memoryRecordList, + gcvCONTIGUOUS_MEMORY, + iface.u.FreeContiguousMemory.bytes, + iface.u.FreeContiguousMemory.physical, + iface.u.FreeContiguousMemory.logical); + + if (mr != gcvNULL) + { + DestroyMemoryRecord(device->os, private, mr); + } + else + { + gcmkPRINT("*ERROR* Invalid contiguous memory for free"); + } + } else if (iface.command == gcvHAL_ALLOCATE_VIDEO_MEMORY) { gctSIZE_T bytes = (iface.u.AllocateVideoMemory.node->VidMem.memory->object.type == gcvOBJ_VIDMEM) ? iface.u.AllocateVideoMemory.node->VidMem.bytes : iface.u.AllocateVideoMemory.node->Virtual.bytes; - CreateMemoryRecord(device->os, + CreateVideoMemoryRecord(device->os, + private, &private->memoryRecordList, iface.u.AllocateVideoMemory.node, iface.u.AllocateVideoMemory.type & 0xFF, @@ -436,7 +629,8 @@ int drv_ioctl(struct inode *inode, gctSIZE_T bytes = (iface.u.AllocateLinearVideoMemory.node->VidMem.memory->object.type == gcvOBJ_VIDMEM) ? iface.u.AllocateLinearVideoMemory.node->VidMem.bytes : iface.u.AllocateLinearVideoMemory.node->Virtual.bytes; - CreateMemoryRecord(device->os, + CreateVideoMemoryRecord(device->os, + private, &private->memoryRecordList, iface.u.AllocateLinearVideoMemory.node, iface.u.AllocateLinearVideoMemory.type & 0xFF, @@ -446,17 +640,18 @@ int drv_ioctl(struct inode *inode, { MEMORY_RECORD_PTR mr; - mr = FindMemoryRecord(device->os, + mr = FindVideoMemoryRecord(device->os, + private, &private->memoryRecordList, iface.u.FreeVideoMemory.node); if (mr != gcvNULL) { - DestoryMemoryRecord(device->os, mr); + DestroyVideoMemoryRecord(device->os, private, mr); } else { - printk("*ERROR* Invalid video memory for free\n"); + gcmkPRINT("*ERROR* Invalid video memory for free"); } } #endif @@ -961,10 +1156,10 @@ static int __init gpu_init(void) gpu_resources[0].start = gpu_resources[0].end = irqLine; gpu_resources[1].start = registerMemBase; - gpu_resources[1].end = registerMemBase + registerMemSize; + gpu_resources[1].end = registerMemBase + registerMemSize - 1; gpu_resources[2].start = contiguousBase; - gpu_resources[2].end = contiguousBase + contiguousSize; + gpu_resources[2].end = contiguousBase + contiguousSize - 1; /* Allocate device */ gpu_device = platform_device_alloc(DEVICE_NAME, -1); @@ -995,6 +1190,10 @@ static int __init gpu_init(void) ret = platform_driver_register(&gpu_driver); if (!ret) { +#if gcdkREPORT_VIDMEM_USAGE + gckDeviceProc_Register(); +#endif + goto out; } @@ -1020,6 +1219,11 @@ static void __exit gpu_exit(void) platform_device_unregister(gpu_device); #endif #endif + +#if gcdkREPORT_VIDMEM_USAGE + gckDeviceProc_UnRegister(); +#endif + printk("UnLoad galcore.ko success.\n"); } module_init(gpu_init); diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c old mode 100755 new mode 100644 index a839dfb3482b..f211472791d4 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c @@ -70,18 +70,34 @@ int g_pages_alloced = 0; #define MEMORY_MAP_UNLOCK(os) \ gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock)) -#if gcdkREPORT_VIDMEM_USAGE -static gctUINT64 AllocatedSurfaceTotal[12] = {0}; -/* - * AllocatedSurfaceMax[12]: Current total memory - * AllocatedSurfaceMax[13]: Current total memory in history - */ -static gctUINT64 AllocatedSurfaceMax[12 + 2] = {0}; -static char *pszSurfaceType[12] = {"UNKNOWN", "INDEX", "VERTEX", "TEXTURE", "RENDER_TARGET", \ - "DEPTH", "BITMAP", "TILE_STATUS", "MASK", "SCISSOR", "HIERARCHICAL_DEPTH", \ - "NUM_TYPES"}; +// 512MÄÚ´æµÄÇé¿öÏÂ,²âÊÔ¼¸¸öÓÎÏ·°ÑÄÚ´æºÄ¹â£¬ÆäÖµ¾Íµ½40£¬Òò´Ë100Ó¦¸ÃÊǹ»ÓÃµÄ +#define gcdkUSE_NON_PAGED_MEMORY_CACHE 100 + +#if gcdkUSE_NON_PAGED_MEMORY_CACHE +typedef struct _gcsNonPagedMemoryCache +{ +#ifndef NO_DMA_COHERENT + gctINT size; + gctSTRING addr; + dma_addr_t dmaHandle; +#else + long order; + struct page * page; #endif + struct _gcsNonPagedMemoryCache * prev; + struct _gcsNonPagedMemoryCache * next; +} +gcsNonPagedMemoryCache; + +static void +_FreeAllNonPagedMemoryCache( + gckOS Os + ); + +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ + + /******************************************************************************\ ********************************** Structures ********************************** \******************************************************************************/ @@ -128,6 +144,11 @@ struct _gckOS gctPOINTER lock; } signal; #endif +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + gctUINT cacheSize; + gcsNonPagedMemoryCache * cacheHead; + gcsNonPagedMemoryCache * cacheTail; +#endif }; #if !USE_NEW_LINUX_SIGNAL @@ -510,6 +531,12 @@ gckOS_Construct( os->signal.currentID = 0; #endif +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + os->cacheSize = 0; + os->cacheHead = gcvNULL; + os->cacheTail = gcvNULL; +#endif + /* Return pointer to the gckOS object. */ *Os = os; @@ -582,6 +609,10 @@ gckOS_Destroy( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + _FreeAllNonPagedMemoryCache(Os); +#endif + #if !USE_NEW_LINUX_SIGNAL /* * Destroy the signal manager. @@ -1197,6 +1228,214 @@ gckOS_UnmapMemory( return gcvSTATUS_OK; } +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + +static gctBOOL +_AddNonPagedMemoryCache( + gckOS Os, +#ifndef NO_DMA_COHERENT + gctINT Size, + gctSTRING Addr, + dma_addr_t DmaHandle +#else + long Order, + struct page * Page +#endif + ) +{ + gcsNonPagedMemoryCache *cache; + + if (Os->cacheSize >= gcdkUSE_NON_PAGED_MEMORY_CACHE) + { + return gcvFALSE; + } + + /* Allocate the cache record */ + cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC); + + if (cache == gcvNULL) return gcvFALSE; + +#ifndef NO_DMA_COHERENT + cache->size = Size; + cache->addr = Addr; + cache->dmaHandle = DmaHandle; +#else + cache->order = Order; + cache->page = Page; +#endif + + /* Add to list */ + if (Os->cacheHead == gcvNULL) + { + cache->prev = gcvNULL; + cache->next = gcvNULL; + Os->cacheHead = + Os->cacheTail = cache; + } + else + { + /* Add to the tail. */ + cache->prev = Os->cacheTail; + cache->next = gcvNULL; + Os->cacheTail->next = cache; + Os->cacheTail = cache; + } + + Os->cacheSize++; + //printk("+ Os->cacheSize = %d \n", Os->cacheSize); + + return gcvTRUE; +} + +#ifndef NO_DMA_COHERENT +static gctSTRING +_GetNonPagedMemoryCache( + gckOS Os, + gctINT Size, + dma_addr_t * DmaHandle + ) +#else +static struct page * +_GetNonPagedMemoryCache( + gckOS Os, + long Order + ) +#endif +{ + gcsNonPagedMemoryCache *cache; +#ifndef NO_DMA_COHERENT + gctSTRING addr; +#else + struct page * page; +#endif + + if (Os->cacheHead == gcvNULL) return gcvNULL; + + /* Find the right cache */ + cache = Os->cacheHead; + + while (cache != gcvNULL) + { +#ifndef NO_DMA_COHERENT + if (cache->size == Size) break; +#else + if (cache->order == Order) break; +#endif + + cache = cache->next; + } + + if (cache == gcvNULL) return gcvNULL; + + /* Remove the cache from list */ + if (cache == Os->cacheHead) + { + Os->cacheHead = cache->next; + + if (Os->cacheHead == gcvNULL) + { + Os->cacheTail = gcvNULL; + } + } + else + { + cache->prev->next = cache->next; + + if (cache == Os->cacheTail) + { + Os->cacheTail = cache->prev; + } + else + { + cache->next->prev = cache->prev; + } + } + + /* Destroy cache */ +#ifndef NO_DMA_COHERENT + addr = cache->addr; + *DmaHandle = cache->dmaHandle; +#else + page = cache->page; +#endif + + kfree(cache); + + Os->cacheSize--; + //printk("- Os->cacheSize = %d \n", Os->cacheSize); + +#ifndef NO_DMA_COHERENT + return addr; +#else + return page; +#endif +} + +static void +_FreeAllNonPagedMemoryCache( + gckOS Os + ) +{ + gcsNonPagedMemoryCache *cache, *nextCache; + + MEMORY_LOCK(Os); + + cache = Os->cacheHead; + + while (cache != gcvNULL) + { + if (cache != Os->cacheTail) + { + nextCache = cache->next; + } + else + { + nextCache = gcvNULL; + } + + /* Remove the cache from list */ + if (cache == Os->cacheHead) + { + Os->cacheHead = cache->next; + + if (Os->cacheHead == gcvNULL) + { + Os->cacheTail = gcvNULL; + } + } + else + { + cache->prev->next = cache->next; + + if (cache == Os->cacheTail) + { + Os->cacheTail = cache->prev; + } + else + { + cache->next->prev = cache->prev; + } + } + +#ifndef NO_DMA_COHERENT + dma_free_coherent(gcvNULL, + cache->size, + cache->addr, + cache->dmaHandle); +#else + free_pages((unsigned long)page_address(cache->page), cache->order); +#endif + + kfree(cache); + + cache = nextCache; + } + + MEMORY_UNLOCK(Os); +} + +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ + /******************************************************************************* ** ** gckOS_AllocateNonPagedMemory @@ -1278,15 +1517,37 @@ gckOS_AllocateNonPagedMemory( MEMORY_LOCK(Os); #ifndef NO_DMA_COHERENT +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + addr = _GetNonPagedMemoryCache(Os, + mdl->numPages * PAGE_SIZE, + &mdl->dmaHandle); + + if (addr == gcvNULL) + { + addr = dma_alloc_coherent(NULL, + mdl->numPages * PAGE_SIZE, + &mdl->dmaHandle, + GFP_ATOMIC); + } +#else addr = dma_alloc_coherent(NULL, mdl->numPages * PAGE_SIZE, &mdl->dmaHandle, GFP_ATOMIC); +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ #else size = mdl->numPages * PAGE_SIZE; order = get_order(size); - //page = alloc_pages(GFP_KERNEL | GFP_DMA, order); +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + page = _GetNonPagedMemoryCache(Os, order); + + if (page == gcvNULL) + { + page = alloc_pages(GFP_KERNEL, order); + } +#else page = alloc_pages(GFP_KERNEL , order); // dkm modify 110330 ½«GFP_DMAÈ¥µô,±ÜÃâ·ÖÅä²»µ½DMAÄÚ´æ +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ if (page == gcvNULL) { @@ -1560,10 +1821,23 @@ gceSTATUS gckOS_FreeNonPagedMemory( MEMORY_LOCK(Os); #ifndef NO_DMA_COHERENT +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + if (!_AddNonPagedMemoryCache(Os, + mdl->numPages * PAGE_SIZE, + mdl->addr, + mdl->dmaHandle)) + { + dma_free_coherent(gcvNULL, + mdl->numPages * PAGE_SIZE, + mdl->addr, + mdl->dmaHandle); + } +#else dma_free_coherent(gcvNULL, mdl->numPages * PAGE_SIZE, mdl->addr, mdl->dmaHandle); +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ #else size = mdl->numPages * PAGE_SIZE; vaddr = mdl->kaddr; @@ -1576,7 +1850,16 @@ gceSTATUS gckOS_FreeNonPagedMemory( size -= PAGE_SIZE; } +#if gcdkUSE_NON_PAGED_MEMORY_CACHE + if (!_AddNonPagedMemoryCache(Os, + get_order(mdl->numPages * PAGE_SIZE), + virt_to_page(mdl->kaddr))) + { + free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE)); + } +#else free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE)); +#endif /* gcdkUSE_NON_PAGED_MEMORY_CACHE */ iounmap(mdl->addr); #endif /* NO_DMA_COHERENT */ @@ -4769,7 +5052,7 @@ gckOS_DestroyAllUserSignals( if (Os->signal.table[signal] != gcvNULL && ((gcsSIGNAL_PTR)Os->signal.table[signal])->process == (gctHANDLE) current->tgid) { - gckOS_Signal(Os, Os->signal.table[signal], gcvTRUE); + gckOS_Signal(Os, Os->signal.table[signal], gcvTRUE); gckOS_DestroySignal(Os, Os->signal.table[signal]); @@ -5386,6 +5669,100 @@ gckOS_ZeroMemory( MEMORY_RECORD_PTR CreateMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR List, + gceMEMORY_TYPE Type, + gctSIZE_T Bytes, + gctPHYS_ADDR Physical, + gctPOINTER Logical + ) +{ + MEMORY_RECORD_PTR mr; + + gcmkASSERT(Type == gcvCONTIGUOUS_MEMORY || Type == gcvNON_PAGED_MEMORY); + + mr = (MEMORY_RECORD_PTR)kmalloc(sizeof(struct MEMORY_RECORD), GFP_ATOMIC); + if (mr == gcvNULL) return gcvNULL; + + MEMORY_LOCK(Os); + + mr->type = Type; + mr->u.Memory.bytes = Bytes; + mr->u.Memory.physical = Physical; + mr->u.Memory.logical = Logical; + + mr->prev = List->prev; + mr->next = List; + List->prev->next = mr; + List->prev = mr; + + MEMORY_UNLOCK(Os); + + return mr; +} + +void +DestroyMemoryRecord( + gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR Mr + ) +{ + gcmkASSERT(Mr->type == gcvCONTIGUOUS_MEMORY || Mr->type == gcvNON_PAGED_MEMORY); + + MEMORY_LOCK(Os); + + Mr->prev->next = Mr->next; + Mr->next->prev = Mr->prev; + + MEMORY_UNLOCK(Os); + + kfree(Mr); +} + +MEMORY_RECORD_PTR +FindMemoryRecord( + gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR List, + gceMEMORY_TYPE Type, + gctSIZE_T Bytes, + gctPHYS_ADDR Physical, + gctPOINTER Logical + ) +{ + MEMORY_RECORD_PTR mr; + + gcmkASSERT(Type == gcvCONTIGUOUS_MEMORY || Type == gcvNON_PAGED_MEMORY); + + MEMORY_LOCK(Os); + + mr = List->next; + + while (mr != List) + { + if (mr->type == Type + && mr->u.Memory.bytes == Bytes + && mr->u.Memory.physical == Physical + && mr->u.Memory.logical == Logical) + { + MEMORY_UNLOCK(Os); + + return mr; + } + + mr = mr->next; + } + + MEMORY_UNLOCK(Os); + + return gcvNULL; +} + +MEMORY_RECORD_PTR +CreateVideoMemoryRecord( + gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List, gcuVIDMEM_NODE_PTR Node, gceSURF_TYPE Type, @@ -5399,19 +5776,21 @@ CreateMemoryRecord( MEMORY_LOCK(Os); - mr->node = Node; - mr->type = Type; - mr->bytes = Bytes; + mr->type = gcvVIDEO_MEMORY; + mr->u.VideoMemory.node = Node; + mr->u.VideoMemory.type = Type; + mr->u.VideoMemory.bytes = Bytes; #if gcdkREPORT_VIDMEM_USAGE - AllocatedSurfaceTotal[Type] += Bytes; - AllocatedSurfaceMax[Type] = (AllocatedSurfaceMax[Type] > AllocatedSurfaceTotal[Type]) - ? AllocatedSurfaceMax[Type] : AllocatedSurfaceTotal[Type]; - AllocatedSurfaceMax[12] += Bytes; - if(AllocatedSurfaceMax[12] > AllocatedSurfaceMax[13]) - { - AllocatedSurfaceMax[13] = AllocatedSurfaceMax[12]; - } + private->allocatedMem[Type] += Bytes; + private->maxAllocatedMem[Type] = + (private->maxAllocatedMem[Type] > private->allocatedMem[Type]) + ? private->maxAllocatedMem[Type] : private->allocatedMem[Type]; + + private->totalAllocatedMem += Bytes; + private->maxTotalAllocatedMem = + (private->maxTotalAllocatedMem > private->totalAllocatedMem) + ? private->maxTotalAllocatedMem : private->totalAllocatedMem; #endif mr->prev = List->prev; @@ -5425,16 +5804,18 @@ CreateMemoryRecord( } void -DestoryMemoryRecord( +DestroyVideoMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR Mr ) { + gcmkASSERT(Mr->type == gcvVIDEO_MEMORY); MEMORY_LOCK(Os); #if gcdkREPORT_VIDMEM_USAGE - AllocatedSurfaceTotal[Mr->type] -= Mr->bytes; - AllocatedSurfaceMax[12] -= Mr->bytes; + private->allocatedMem[Mr->u.VideoMemory.type] -= Mr->u.VideoMemory.bytes; + private->totalAllocatedMem -= Mr->u.VideoMemory.bytes; #endif Mr->prev->next = Mr->next; @@ -5446,8 +5827,9 @@ DestoryMemoryRecord( } MEMORY_RECORD_PTR -FindMemoryRecord( +FindVideoMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List, gcuVIDMEM_NODE_PTR Node ) @@ -5460,7 +5842,7 @@ FindMemoryRecord( while (mr != List) { - if (mr->node == Node) + if (mr->type == gcvVIDEO_MEMORY && mr->u.VideoMemory.node == Node) { MEMORY_UNLOCK(Os); @@ -5478,6 +5860,7 @@ FindMemoryRecord( void FreeAllMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List ) { @@ -5486,20 +5869,6 @@ FreeAllMemoryRecord( MEMORY_LOCK(Os); -#if gcdkREPORT_VIDMEM_USAGE - for (; i < 12; i++) { - printk("AllocatedSurfaceTotal[%s]:\t %12lluK, AllocatedSurfaceMax[%s]:\t %12lluK\n", - pszSurfaceType[i], AllocatedSurfaceTotal[i]/1024, - pszSurfaceType[i], AllocatedSurfaceMax[i]/1024); - - AllocatedSurfaceTotal[i] = 0; - AllocatedSurfaceMax[i] = 0; - } - printk("AllocatedSurfaceMax[unfreed]:\t %12lluK\n", AllocatedSurfaceMax[12]/1024); - printk("AllocatedSurfaceMax[total]:\t %12lluK\n", AllocatedSurfaceMax[13]/1024); - AllocatedSurfaceMax[12] = AllocatedSurfaceMax[13] = 0; - i = 0; -#endif while (List->next != List) { @@ -5512,29 +5881,63 @@ FreeAllMemoryRecord( MEMORY_UNLOCK(Os); - gcmkTRACE_ZONE(gcvLEVEL_ERROR, - gcvZONE_OS, - "Unfreed %s memory: node: %p", - (mr->node->VidMem.memory->object.type == gcvOBJ_VIDMEM)? - "video" : (mr->node->Virtual.contiguous)? - "contiguous" : "virtual", - mr->node); - - while (gcvTRUE) + switch (mr->type) { - if (mr->node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - if (mr->node->VidMem.locked == 0) break; - } - else + case gcvNON_PAGED_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_ERROR, + gcvZONE_OS, + "Unfreed non-paged memory: physical: %p, logical: %p, bytes: %d", + mr->u.Memory.physical, mr->u.Memory.logical, mr->u.Memory.bytes); + + gckOS_FreeNonPagedMemory(Os, + mr->u.Memory.bytes, + mr->u.Memory.physical, + mr->u.Memory.logical); + break; + + case gcvCONTIGUOUS_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_ERROR, + gcvZONE_OS, + "Unfreed contiguous memory: physical: %p, logical: %p, bytes: %d", + mr->u.Memory.physical, mr->u.Memory.logical, mr->u.Memory.bytes); + + gckOS_FreeContiguous(Os, + mr->u.Memory.physical, + mr->u.Memory.logical, + mr->u.Memory.bytes); + break; + + case gcvVIDEO_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_ERROR, + gcvZONE_OS, + "Unfreed %s memory: node: %p", + (mr->u.VideoMemory.node->VidMem.memory->object.type == gcvOBJ_VIDMEM)? + "video" : (mr->u.VideoMemory.node->Virtual.contiguous)? + "virtual-contiguous" : "virtual", + mr->u.VideoMemory.node); + + while (gcvTRUE) { - if (mr->node->Virtual.locked == 0) break; + if (mr->u.VideoMemory.node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + if (mr->u.VideoMemory.node->VidMem.locked == 0) break; + } + else + { + if (mr->u.VideoMemory.node->Virtual.locked == 0) break; + } + + gckVIDMEM_Unlock(mr->u.VideoMemory.node, gcvSURF_TYPE_UNKNOWN, gcvNULL); } - gckVIDMEM_Unlock(mr->node, gcvSURF_TYPE_UNKNOWN, gcvNULL); + gckVIDMEM_Free(mr->u.VideoMemory.node); + break; + + default: + gcmkASSERT(0); + break; } - gckVIDMEM_Free(mr->node); kfree(mr); @@ -5547,7 +5950,7 @@ FreeAllMemoryRecord( { gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_OS, - "======== Total %d unfreed video/contiguous/virtual memory ========", i); + "======== Total %d unfreed memory block(s) ========", i); } } #endif diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.h index c436cd9e9bdf..5428259de8d1 100644 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.h +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.h @@ -76,7 +76,37 @@ gckOS_DestroyAllUserSignals( #ifdef gcdkUSE_MEMORY_RECORD MEMORY_RECORD_PTR CreateMemoryRecord( +gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR List, + gceMEMORY_TYPE Type, + gctSIZE_T Bytes, + gctPHYS_ADDR Physical, + gctPOINTER Logical + ); + +void +DestroyMemoryRecord( + gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR Mr + ); + +MEMORY_RECORD_PTR +FindMemoryRecord( + gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, + MEMORY_RECORD_PTR List, + gceMEMORY_TYPE Type, + gctSIZE_T Bytes, + gctPHYS_ADDR Physical, + gctPOINTER Logical + ); + +MEMORY_RECORD_PTR +CreateVideoMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List, gcuVIDMEM_NODE_PTR Node, gceSURF_TYPE Type, @@ -84,14 +114,16 @@ CreateMemoryRecord( ); void -DestoryMemoryRecord( +DestroyVideoMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR Mr ); MEMORY_RECORD_PTR -FindMemoryRecord( +FindVideoMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List, gcuVIDMEM_NODE_PTR Node ); @@ -99,6 +131,7 @@ FindMemoryRecord( void FreeAllMemoryRecord( gckOS Os, + gcsHAL_PRIVATE_DATA_PTR private, MEMORY_RECORD_PTR List ); #endif -- 2.34.1