gpu: add allocnopage cache support for alloc_pages fail.
author杜坤明 <dkm@rockchip.com>
Sat, 14 May 2011 03:43:34 +0000 (11:43 +0800)
committer杜坤明 <dkm@rockchip.com>
Sat, 14 May 2011 03:43:34 +0000 (11:43 +0800)
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.h
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c [changed mode: 0755->0644]
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c [changed mode: 0755->0644]
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.h

index 13c70f32f2d0f0e4f9a1a646bcc9ddf81980a5b5..01629d99b85a4930b7a1498a9e8f2c42ffb223b2 100644 (file)
@@ -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;
old mode 100755 (executable)
new mode 100644 (file)
index 760a6fb..ea0de44
@@ -87,6 +87,90 @@ unsigned long coreClock = 552*1000000;
 module_param(coreClock, ulong, 0644);
 #endif
 
+#if gcdkREPORT_VIDMEM_USAGE
+#include <linux/proc_fs.h>
+
+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);
old mode 100755 (executable)
new mode 100644 (file)
index a839dfb..f211472
@@ -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
index c436cd9e9bdf5c0773e1acf62d82d975cb0d268b..5428259de8d190fa289f485f370672f8d8b50a5a 100644 (file)
@@ -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