summaryrefslogtreecommitdiff
path: root/drivers/mxc/amd-gpu/common/gsl_memmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/amd-gpu/common/gsl_memmgr.c')
-rw-r--r--drivers/mxc/amd-gpu/common/gsl_memmgr.c97
1 files changed, 53 insertions, 44 deletions
diff --git a/drivers/mxc/amd-gpu/common/gsl_memmgr.c b/drivers/mxc/amd-gpu/common/gsl_memmgr.c
index 75f250ae59b1..3248f6d46554 100644
--- a/drivers/mxc/amd-gpu/common/gsl_memmgr.c
+++ b/drivers/mxc/amd-gpu/common/gsl_memmgr.c
@@ -479,6 +479,8 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m
unsigned int blksize;
unsigned int baseaddr, alignedbaseaddr, alignfragment;
int freeblk, alignmentshift;
+ memblk_t *ptrbest = NULL;
+ unsigned int fitsize = ~0UL;
kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_TRACE,
"--> int kgsl_memarena_alloc(gsl_memarena_t *memarena=0x%08x, gsl_flags_t flags=0x%08x, int size=%d, gsl_memdesc_t *memdesc=%M)\n", memarena, flags, size, memdesc );
@@ -542,17 +544,33 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m
do
{
+ int aba;
// align base address
- baseaddr = ptrfree->blkaddr + memarena->gpubaseaddr;
- alignedbaseaddr = gsl_memarena_alignaddr(baseaddr, alignmentshift);
+ baseaddr = ptrfree->blkaddr + memarena->gpubaseaddr;
+ aba = gsl_memarena_alignaddr(baseaddr, alignmentshift);
- alignfragment = alignedbaseaddr - baseaddr;
-
- if (ptrfree->blksize >= blksize + alignfragment)
- {
- result = GSL_SUCCESS;
- freeblk = 1;
-
+ if (aba - baseaddr == 0 && ptrfree->blksize == blksize) {
+ ptrbest = ptrfree;
+ alignfragment = aba - baseaddr;
+ alignedbaseaddr = aba;
+ result = GSL_SUCCESS;
+ break;
+ }
+
+ if ((ptrfree->blksize >= blksize + aba - baseaddr) &&
+ (fitsize > ptrfree->blksize)) {
+ fitsize = ptrfree->blksize;
+ alignfragment = aba - baseaddr;
+ alignedbaseaddr = aba;
+ result = GSL_SUCCESS;
+ ptrbest = ptrfree;
+ }
+
+ ptrfree = ptrfree->next;
+
+ } while (ptrfree != memarena->freelist.allocrover);
+
+ if (ptrbest) {
memdesc->gpuaddr = alignedbaseaddr;
memdesc->hostptr = kgsl_memarena_gethostptr(memarena, memdesc->gpuaddr);
memdesc->size = blksize;
@@ -561,50 +579,41 @@ kgsl_memarena_alloc(gsl_memarena_t *memarena, gsl_flags_t flags, int size, gsl_m
{
// insert new node to handle newly created (small) fragment
p = kgsl_memarena_getmemblknode(memarena);
- p->blkaddr = ptrfree->blkaddr;
+ p->blkaddr = ptrbest->blkaddr;
p->blksize = alignfragment;
- p->next = ptrfree;
- p->prev = ptrfree->prev;
- ptrfree->prev->next = p;
- ptrfree->prev = p;
+ p->next = ptrbest;
+ p->prev = ptrbest->prev;
+ ptrbest->prev->next = p;
+ ptrbest->prev = p;
- if (ptrfree == memarena->freelist.head)
- {
- memarena->freelist.head = p;
- }
+ if (ptrbest == memarena->freelist.head)
+ memarena->freelist.head = p;
}
- ptrfree->blkaddr += alignfragment + blksize;
- ptrfree->blksize -= alignfragment + blksize;
+ ptrbest->blkaddr += alignfragment + blksize;
+ ptrbest->blksize -= alignfragment + blksize;
- memarena->freelist.allocrover = ptrfree;
+ memarena->freelist.allocrover = ptrbest;
- if (ptrfree->blksize == 0 && ptrfree != ptrlast)
- {
- ptrfree->prev->next = ptrfree->next;
- ptrfree->next->prev = ptrfree->prev;
- if (ptrfree == memarena->freelist.head)
- {
- memarena->freelist.head = ptrfree->next;
- }
- if (ptrfree == memarena->freelist.allocrover)
- {
- memarena->freelist.allocrover = ptrfree->next;
- }
- if (ptrfree == memarena->freelist.freerover)
- {
- memarena->freelist.freerover = ptrfree->prev;
- }
- p = ptrfree;
- ptrfree = ptrfree->prev;
- kgsl_memarena_releasememblknode(memarena, p);
- }
- }
+ if (ptrbest->blksize == 0 && ptrbest != ptrlast) {
+ ptrbest->prev->next = ptrbest->next;
+ ptrbest->next->prev = ptrbest->prev;
- ptrfree = ptrfree->next;
+ if (ptrbest == memarena->freelist.head)
+ memarena->freelist.head = ptrbest->next;
+
+ if (ptrbest == memarena->freelist.allocrover)
+ memarena->freelist.allocrover = ptrbest->next;
+
+ if (ptrbest == memarena->freelist.freerover)
+ memarena->freelist.freerover = ptrbest->prev;
- } while (!freeblk && ptrfree != memarena->freelist.allocrover);
+ p = ptrbest;
+ ptrbest = ptrbest->prev;
+ kgsl_memarena_releasememblknode(memarena, p);
+ }
+ }
GSL_MEMARENA_UNLOCK();