summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c')
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
index 1fb18fbb87e2..bc5f0830a37b 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
@@ -26,6 +26,9 @@
/*******************************************************************************
***** Private fuctions ********************************************************/
+#define _GetSlot(database, x) \
+ (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
+
/*******************************************************************************
** gckKERNEL_NewDatabase
**
@@ -56,6 +59,7 @@ gckKERNEL_NewDatabase(
gcsDATABASE_PTR database;
gctBOOL acquired = gcvFALSE;
gctSIZE_T slot;
+ gcsDATABASE_PTR existingDatabase;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
@@ -63,6 +67,21 @@ gckKERNEL_NewDatabase(
gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
acquired = gcvTRUE;
+ /* Compute the hash for the database. */
+ slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+
+ /* Walk the hash list. */
+ for (existingDatabase = Kernel->db->db[slot];
+ existingDatabase != gcvNULL;
+ existingDatabase = existingDatabase->next)
+ {
+ if (existingDatabase->processID == ProcessID)
+ {
+ /* One process can't be added twice. */
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+ }
+
if (Kernel->db->freeDatabase != gcvNULL)
{
/* Allocate a database from the free list. */
@@ -81,9 +100,6 @@ gckKERNEL_NewDatabase(
database = pointer;
}
- /* Compute the hash for the database. */
- slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
-
/* Insert the database into the hash. */
database->next = Kernel->db->db[slot];
Kernel->db->db[slot] = database;
@@ -350,6 +366,7 @@ static gceSTATUS
gckKERNEL_NewRecord(
IN gckKERNEL Kernel,
IN gcsDATABASE_PTR Database,
+ IN gctUINT32 Slot,
OUT gcsDATABASE_RECORD_PTR * Record
)
{
@@ -383,8 +400,8 @@ gckKERNEL_NewRecord(
}
/* Insert the record in the database. */
- record->next = Database->list;
- Database->list = record;
+ record->next = Database->list[Slot];
+ Database->list[Slot] = record;
/* Release the database mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
@@ -449,6 +466,7 @@ gckKERNEL_DeleteRecord(
gceSTATUS status;
gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record, previous;
+ gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
@@ -458,8 +476,9 @@ gckKERNEL_DeleteRecord(
gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
acquired = gcvTRUE;
+
/* Scan the database for this record. */
- for (record = Database->list, previous = gcvNULL;
+ for (record = Database->list[slot], previous = gcvNULL;
record != gcvNULL;
record = record->next
)
@@ -490,7 +509,7 @@ gckKERNEL_DeleteRecord(
/* Remove record from database. */
if (previous == gcvNULL)
{
- Database->list = record->next;
+ Database->list[slot] = record->next;
}
else
{
@@ -557,6 +576,7 @@ gckKERNEL_FindRecord(
gceSTATUS status;
gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record;
+ gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
@@ -567,7 +587,7 @@ gckKERNEL_FindRecord(
acquired = gcvTRUE;
/* Scan the database for this record. */
- for (record = Database->list;
+ for (record = Database->list[slot];
record != gcvNULL;
record = record->next
)
@@ -642,6 +662,7 @@ gckKERNEL_CreateProcessDB(
{
gceSTATUS status;
gcsDATABASE_PTR database = gcvNULL;
+ gctUINT32 i;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
@@ -668,7 +689,11 @@ gckKERNEL_CreateProcessDB(
database->mapUserMemory.bytes = 0;
database->mapUserMemory.maxBytes = 0;
database->mapUserMemory.totalBytes = 0;
- database->list = gcvNULL;
+
+ for (i = 0; i < gcmCOUNTOF(database->list); i++)
+ {
+ database->list[i] = gcvNULL;
+ }
#if gcdSECURE_USER
{
@@ -848,7 +873,7 @@ gckKERNEL_AddProcessDB(
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
/* Create a new record in the database. */
- gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, &record));
+ gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
/* Initialize the record. */
record->kernel = Kernel;
@@ -1086,6 +1111,7 @@ gckKERNEL_DestroyProcessDB(
gctPHYS_ADDR physical;
gcuVIDMEM_NODE_PTR node;
gckKERNEL kernel = Kernel;
+ gctUINT32 i;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
@@ -1126,8 +1152,11 @@ gckKERNEL_DestroyProcessDB(
ProcessID);
}
+ for(i = 0; i < gcmCOUNTOF(database->list); i++)
+ {
+
/* Walk all records. */
- for (record = database->list; record != gcvNULL; record = next)
+ for (record = database->list[i]; record != gcvNULL; record = next)
{
/* Next next record. */
next = record->next;
@@ -1293,6 +1322,8 @@ gckKERNEL_DestroyProcessDB(
gcvNULL));
}
+ }
+
/* Delete the database. */
gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));