GED_ERROR ged_monitor_3D_fence_add(int fence_fd) { int err; GED_MONITOR_3D_FENCE* psMonitor; psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE)); if (!psMonitor) { return GED_ERROR_OOM; } sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb); INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb); psMonitor->psSyncFence = sync_fence_fdget(fence_fd); if (NULL == psMonitor->psSyncFence) { ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); return GED_ERROR_INVALID_PARAMS; } err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter); if ((1 == err) || (0 > err)) { sync_fence_put(psMonitor->psSyncFence); ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); } else if (0 == err) { int iCount = atomic_add_return(1, &g_i32Count); if (iCount > 1) { if (0 == ged_monitor_3D_fence_disable) { //unsigned int uiFreqLevelID; //if (mtk_get_bottom_gpu_freq(&uiFreqLevelID)) { //if (uiFreqLevelID != 4) { #ifdef CONFIG_GPU_TRACEPOINTS if (ged_monitor_3D_fence_systrace) { unsigned long long t = cpu_clock(smp_processor_id()); trace_gpu_sched_switch("Smart Boost", t, 1, 0, 1); } #endif mtk_set_bottom_gpu_freq(4); } } } } } if (ged_monitor_3D_fence_debug > 0) { GED_LOGI("[+]3D fences count = %d\n", atomic_read(&g_i32Count)); } return GED_OK; }
static void ged_monitor_3D_fence_work_cb(struct work_struct *psWork) { GED_MONITOR_3D_FENCE *psMonitor; if (atomic_sub_return(1, &g_i32Count) < 1) { if (0 == ged_monitor_3D_fence_disable) { //unsigned int uiFreqLevelID; //if (mtk_get_bottom_gpu_freq(&uiFreqLevelID)) { //if (uiFreqLevelID > 0) { mtk_set_bottom_gpu_freq(0); #ifdef CONFIG_GPU_TRACEPOINTS if (ged_monitor_3D_fence_systrace) { unsigned long long t = cpu_clock(smp_processor_id()); trace_gpu_sched_switch("Smart Boost", t, 0, 0, 1); } #endif } } } } if (ged_monitor_3D_fence_debug > 0) { GED_LOGI("[-]3D fences count = %d\n", atomic_read(&g_i32Count)); } psMonitor = GED_CONTAINER_OF(psWork, GED_MONITOR_3D_FENCE, sWork); sync_fence_put(psMonitor->psSyncFence); ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); }
void PVRGpuTraceWorkSwitch( IMG_UINT64 ui64HWTimestampInOSTime, const IMG_UINT32 ui32Pid, const IMG_UINT32 ui32ExtJobRef, const IMG_UINT32 ui32IntJobRef, const IMG_CHAR* pszWorkType, PVR_GPUTRACE_SWITCH_TYPE eSwType) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_FTRACE_GPU_JOB* psJob = IMG_NULL; IMG_UINT32 ui32CtxId; PVR_ASSERT(pszWorkType); eError = GetCtxAndJobID(ui32Pid, ui32ExtJobRef, ui32IntJobRef, &ui32CtxId, &psJob); PVR_LOGRN_IF_ERROR(eError, "GetCtxAndJobID"); PVR_ASSERT(psJob); /* Only trace switch event if the job's enqueue event was traced. Necessary for when the GPU tracing is disabled, apps run and re-enabled to avoid orphan switch events from appearing in the trace file. */ if (PVRSRV_FTRACE_JOB_GET_FLAGS(psJob) & PVRSRV_FTRACE_JOB_FLAG_ENQUEUED) { if (eSwType == PVR_GPUTRACE_SWITCH_TYPE_END) { /* When the GPU goes idle, we need to trace a switch with a context * ID of 0. */ ui32CtxId = 0; } trace_gpu_sched_switch(pszWorkType, ui64HWTimestampInOSTime, ui32CtxId, KM_FTRACE_NO_PRIORITY, PVRSRV_FTRACE_JOB_GET_ID(psJob)); } }
/* Group and scheduler must be locked when entering this function. Both will be unlocked before * exiting. */ static void mali_gp_scheduler_schedule_internal_and_unlock(void) { struct mali_gp_job *job = NULL; MALI_DEBUG_ASSERT_LOCK_HELD(slot.group->lock); MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock); if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || (_mali_osk_list_empty(&job_queue) && _mali_osk_list_empty(&job_queue_high))) { mali_gp_scheduler_unlock(); mali_group_unlock(slot.group); MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0)); #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS) trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(), 0, 0, 0); #endif return; /* Nothing to do, so early out */ } /* Get next job in queue */ if (!_mali_osk_list_empty(&job_queue_high)) { job = _MALI_OSK_LIST_ENTRY(job_queue_high.next, struct mali_gp_job, list); } else {
void SystraceHWPerfPackets(PVRSRV_SGXDEV_INFO *psDevInfo, PVRSRV_SGX_HWPERF_CB_ENTRY* psSGXHWPerf, IMG_UINT32 ui32DataCount, IMG_UINT32 ui32SgxClockspeed) { IMG_UINT32 ui32PID, ui32FrameNo, ui32EvtType, ui32RTData, ui32Clocksx16Difference, ui32ClockMultiplier; IMG_UINT32 ui32SgxClocksx16 = 0; IMG_UINT32 i = 0; IMG_UINT64 ui64HostTimestamp = 0; IMG_UINT64 ui64TimeDifference = 0; IMG_UINT64 ui64PacketTimeStamp = 0; IMG_UINT32 ui32JobID = 0; IMG_UINT32 ui32CtxID = 0; IMG_UINT64 ui64LastHostTimestamp = 0; IMG_UINT32 ui32LastSGXClocksx16 = 0; ui64LastHostTimestamp = psDevInfo->psSystraceData->ui64LastHostTimestamp; ui32LastSGXClocksx16 = psDevInfo->psSystraceData->ui32LastSGXClocksx16; ui64HostTimestamp = sched_clock(); /*If this is the first packet read, use it as the initial reference*/ if (ui64LastHostTimestamp == 0) { if (ui32DataCount > 0) { ui64LastHostTimestamp = ui64HostTimestamp; ui32LastSGXClocksx16 = psSGXHWPerf[0].ui32Clocksx16; } } /* SGX clockspeed reported 307200000 HZ */ /* Get the ui32ClockMultipliertiplier per 1us*/ ui32ClockMultiplier = (ui32SgxClockspeed)/(1000*1000); for(i = 0; i < ui32DataCount; ++i) { ui32SgxClocksx16 = psSGXHWPerf[i].ui32Clocksx16; ui32EvtType = psSGXHWPerf[i].ui32Type; ui32FrameNo = psSGXHWPerf[i].ui32FrameNo; ui32PID = psSGXHWPerf[i].ui32PID; ui32RTData = psSGXHWPerf[i].ui32RTData; if ((ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_TA_START) || (ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_TA_END) || (ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_3D_START) || (ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_3D_END)) { /*Get the JobID*/ GetCtxAndJobID(psDevInfo->psSystraceData, ui32PID, ui32FrameNo, ui32RTData, &ui32CtxID, &ui32JobID); /* Calculate the time difference in ns*/ /* Get the clock difference */ ui32Clocksx16Difference = (ui32SgxClocksx16 - ui32LastSGXClocksx16); /* Multipy it by 16 and 1000 to convert from us to ns */ ui64TimeDifference = (16*ui32Clocksx16Difference*1000)/ui32ClockMultiplier; /* Add the time diff to the last time-stamp, in nanoseconds*/ ui64PacketTimeStamp = (unsigned long long) ui64LastHostTimestamp + (unsigned long long)ui64TimeDifference; switch(ui32EvtType) { case PVRSRV_SGX_HWPERF_TYPE_TA_START: trace_gpu_sched_switch("TA", ui64PacketTimeStamp, ui32CtxID, ui32FrameNo, ui32JobID); break; case PVRSRV_SGX_HWPERF_TYPE_TA_END: trace_gpu_sched_switch("TA", ui64PacketTimeStamp, 0, ui32FrameNo, ui32JobID); break; case PVRSRV_SGX_HWPERF_TYPE_3D_START: trace_gpu_sched_switch("3D", ui64PacketTimeStamp, ui32CtxID, ui32FrameNo, ui32JobID); break; case PVRSRV_SGX_HWPERF_TYPE_3D_END: trace_gpu_sched_switch("3D", ui64PacketTimeStamp, 0, ui32FrameNo, ui32JobID); break; default: break; } } } if(ui32DataCount > 0) { psDevInfo->psSystraceData->ui32LastSGXClocksx16 = ui32SgxClocksx16; } /* Get the last set of packets timestamp and sleep 1ms */ psDevInfo->psSystraceData->ui64LastHostTimestamp = ui64HostTimestamp; }