/* ------------------------------------------------------------------------------ */ static MUINT32 SYSRAM_AllocUser(SYSRAM_USER_ENUM const User, MUINT32 Size, MUINT32 const Alignment) { MUINT32 Addr = 0; SYSRAM_MEM_BANK_ENUM const MemBankNo = SYSRAM_GetMemBankNo(User); /* */ if (SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT); return 0; } /* */ if (!SYSRAM_IsLegalSizeToAlloc(MemBankNo, User, Size)) { return 0; } /* */ switch (MemBankNo) { case SYSRAM_MEM_BANK_BAD: case SYSRAM_MEM_BANK_AMOUNT: { /* Do nothing. */ break; } default: { Addr = SYSRAM_AllocUserPhy(User, Size, Alignment, MemBankNo); break; } } /* */ if (0 < Addr) { SYSRAM_LockUser(User, Size); } /* */ return Addr; }
/* ------------------------------------------------------------------------------ */ static void SYSRAM_ResetUserTaskInfo(SYSRAM_USER_ENUM const User) { if (!SYSRAM_IsBadOwner(User)) { SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User]; memset(pUserInfo, 0, sizeof(*pUserInfo)); } }
//------------------------------------------------------------------------------ static void SYSRAM_DumpLayout(void) { MUINT32 Index = 0; SYSRAM_MEM_NODE_STRUCT* pCurrNode = NULL; // LOG_DMP("[SYSRAM_DumpLayout]\n"); LOG_DMP("AllocatedTbl = 0x%08lX\n",Sysram.AllocatedTbl); LOG_DMP("=========================================\n"); for (Index = 0; Index < SYSRAM_MEM_BANK_AMOUNT; Index++) { LOG_DMP("\n [Mem Pool %ld] (IndexTbl, UserCount)=(%lX, %ld)\n", Index, SysramMemPoolInfo[Index].IndexTbl, SysramMemPoolInfo[Index].UserCount); LOG_DMP("[Locked Time] [Owner Offset Size Index pCurrent pPrevious pNext] [pid tgid] [Proc Name / Owner Name]\n"); pCurrNode = &SysramMemPoolInfo[Index].pMemNode[0]; while(NULL != pCurrNode) { SYSRAM_USER_ENUM const User = pCurrNode->User; if(SYSRAM_IsBadOwner(User)) { LOG_DMP( "------------ --------" " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p\n", pCurrNode->User, pCurrNode->Offset, pCurrNode->Length, pCurrNode->Index, pCurrNode, pCurrNode->pPrev, pCurrNode->pNext); } else { SYSRAM_USER_STRUCT*const pUserInfo = &Sysram.UserInfo[User]; LOG_DMP("%5lu.%06lu" " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p" " %-4d %-4d \"%s\" / \"%s\"\n", pUserInfo->TimeS, pUserInfo->TimeUS, User, pCurrNode->Offset, pCurrNode->Length, pCurrNode->Index, pCurrNode, pCurrNode->pPrev, pCurrNode->pNext, pUserInfo->pid, pUserInfo->tgid, pUserInfo->ProcName, SysramUserName[User]); } pCurrNode = pCurrNode->pNext; }; } LOG_DMP("\n"); SYSRAM_DumpResMgr(); }
/* ------------------------------------------------------------------------------ */ static void SYSRAM_SetUserTaskInfo(SYSRAM_USER_ENUM const User) { if (!SYSRAM_IsBadOwner(User)) { SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User]; /* */ pUserInfo->pid = current->pid; pUserInfo->tgid = current->tgid; memcpy(pUserInfo->ProcName, current->comm, sizeof(pUserInfo->ProcName)); /* */ SYSRAM_GetTime(&(pUserInfo->Time64), &(pUserInfo->TimeS), &(pUserInfo->TimeUS)); } }
/* ------------------------------------------------------------------------------ */ static void SYSRAM_IOC_Free(SYSRAM_USER_ENUM User) { if (SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT); return; } /* */ SYSRAM_SpinLock(); SYSRAM_FreeUser(User); wake_up_interruptible(&Sysram.WaitQueueHead); SYSRAM_CheckClock(); SYSRAM_SpinUnlock(); /* */ if ((1 << User) & SysramLogUserMask) { LOG_MSG("[User:%s]Done", SysramUserName[User]); } }
/* ------------------------------------------------------------------------------ */ static MUINT32 SYSRAM_IOC_Alloc(SYSRAM_USER_ENUM const User, MUINT32 const Size, MUINT32 Alignment, MUINT32 const TimeoutMS) { MUINT32 Addr = 0; MINT32 TimeOut = 0; /* */ if (SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT); return 0; } /* */ if (0 == Size) { LOG_ERR("[User:%s]allocates 0 size!", SysramUserName[User]); return 0; } /* */ Addr = SYSRAM_TryAllocUser(User, Size, Alignment); if (0 != Addr /* success */ || 0 == TimeoutMS /* failure without a timeout specified */ ) { goto EXIT; } /* */ TimeOut = wait_event_interruptible_timeout(Sysram.WaitQueueHead, 0 != (Addr = SYSRAM_TryAllocUser(User, Size, Alignment)), SYSRAM_MsToJiffies(TimeoutMS)); /* */ if (0 == TimeOut && 0 == Addr) { LOG_ERR("[User:%s]allocate timeout", SysramUserName[User]); } /* */ EXIT: if (0 == Addr) { /* Failure */ LOG_ERR("[User:%s]fails to allocate.Size(%lu),Alignment(%lu),TimeoutMS(%lu)", SysramUserName[User], Size, Alignment, TimeoutMS); SYSRAM_DumpLayout(); } else { /* Success */ if ((1 << User) & SysramLogUserMask) { LOG_MSG("[User:%s]%lu bytes OK", SysramUserName[User], Size); } } /* */ return Addr; }
//------------------------------------------------------------------------------ static long SYSRAM_Ioctl( struct file* pFile, unsigned int Cmd, unsigned long Param) { MINT32 Ret = 0; MUINT32 Sec = 0,USec = 0; MUINT64 Time64 = 0; SYSRAM_PROC_STRUCT* pProc = (SYSRAM_PROC_STRUCT*)pFile->private_data; SYSRAM_ALLOC_STRUCT Alloc; SYSRAM_USER_ENUM User; // SYSRAM_GetTime(&Time64, &Sec, &USec); /* LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); */ if(pFile->private_data == NULL) { LOG_WRN("private_data is NULL."); Ret = -EFAULT; goto EXIT; } // switch(Cmd) { case SYSRAM_ALLOC: { if(copy_from_user(&Alloc, (void*)Param, sizeof(SYSRAM_ALLOC_STRUCT)) == 0) { if(SYSRAM_IsBadOwner(Alloc.User)) { LOG_ERR("User(%d) out of range(%d)",Alloc.User,SYSRAM_USER_AMOUNT); Ret = -EFAULT; goto EXIT; } // Alloc.Addr = SYSRAM_IOC_Alloc( Alloc.User, Alloc.Size, Alloc.Alignment, Alloc.TimeoutMS); if(Alloc.Addr != 0) { SYSRAM_SpinLock(); pProc->Table |= (1 << Alloc.User); if(pProc->Tgid == 0) { pProc->Pid = current->pid; pProc->Tgid = current->tgid; strcpy(pProc->ProcName,current->comm); SYSRAM_SpinUnlock(); } else { SYSRAM_SpinUnlock(); if(pProc->Tgid != current->tgid) { LOG_ERR("Tgid is inconsistent"); Ret = -EFAULT; } } } else { Ret = -EFAULT; } // if(copy_to_user((void*)Param, &Alloc, sizeof(SYSRAM_ALLOC_STRUCT)) ) { LOG_ERR("copy to user failed"); Ret = -EFAULT; } } else { LOG_ERR("copy_from_user fail"); Ret = -EFAULT; } break; } // case SYSRAM_FREE: { if(copy_from_user(&User, (void*)Param, sizeof(SYSRAM_USER_ENUM)) == 0) { if(SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)",User,SYSRAM_USER_AMOUNT); Ret = -EFAULT; goto EXIT; } // SYSRAM_SpinLock(); if((pProc->Table) & (1 << User)) { SYSRAM_SpinUnlock(); SYSRAM_IOC_Free(User); SYSRAM_SpinLock(); // pProc->Table &= (~(1 << User)); if(pProc->Table == 0) { pProc->Pid = 0; pProc->Tgid = 0; strcpy(pProc->ProcName,SYSRAM_PROC_NAME); } SYSRAM_SpinUnlock(); } else { SYSRAM_SpinUnlock(); LOG_WRN("Freeing unallocated buffer user(%d)",User); Ret = -EFAULT; } } else { LOG_ERR("copy_from_user fail"); Ret = -EFAULT; } break; } case SYSRAM_DUMP: { SYSRAM_DumpLayout(); break; } default: { LOG_WRN("No such command"); Ret = -EINVAL; break; } } // EXIT: if(Ret != 0) { LOG_ERR("Fail"); LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); if(pFile->private_data != NULL) { LOG_ERR("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, Sec, USec); } } // return Ret; }
//------------------------------------------------------------------------------ static int SYSRAM_DumpLayoutToProc( char* pPage, char** ppStart, off_t Off, int Count, int* pEof, void* pData) { char *p = pPage; MUINT32 len = 0; MUINT32 Index = 0; SYSRAM_MEM_NODE_STRUCT* pCurrNode = NULL; // p += sprintf(p, "\n[SYSRAM_DumpLayoutToProc]\n"); p += sprintf(p, "AllocatedTbl = 0x%08lX\n",Sysram.AllocatedTbl); p += sprintf(p, "=========================================\n" ); for (Index = 0; Index < SYSRAM_MEM_BANK_AMOUNT; Index++) { p += sprintf(p, "\n [Mem Pool %ld] (IndexTbl, UserCount)=(%lX, %ld)\n", Index, SysramMemPoolInfo[Index].IndexTbl, SysramMemPoolInfo[Index].UserCount); p += sprintf(p, "[Locked Time] [Owner Offset Size Index pCurrent pPrevious pNext] [pid tgid] [Proc Name / Owner Name]\n"); pCurrNode = &SysramMemPoolInfo[Index].pMemNode[0]; while ( NULL != pCurrNode ) { SYSRAM_USER_ENUM const User = pCurrNode->User; if ( SYSRAM_IsBadOwner(User) ) { p += sprintf(p, "------------ --------" " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p\n", pCurrNode->User, pCurrNode->Offset, pCurrNode->Length, pCurrNode->Index, pCurrNode, pCurrNode->pPrev, pCurrNode->pNext ); } else { SYSRAM_USER_STRUCT*const pUserInfo = &Sysram.UserInfo[User]; p += sprintf(p, "%5lu.%06lu" " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p" " %-4d %-4d \"%s\" / \"%s\"\n", pUserInfo->TimeS, pUserInfo->TimeUS, User, pCurrNode->Offset, pCurrNode->Length, pCurrNode->Index, pCurrNode, pCurrNode->pPrev, pCurrNode->pNext, pUserInfo->pid, pUserInfo->tgid, pUserInfo->ProcName, SysramUserName[User]); } pCurrNode = pCurrNode->pNext; }; } // *ppStart = pPage + Off; len = p - pPage; if(len > Off) { len -= Off; } else { len = 0; } // return len < Count ? len : Count; }