static void mali_gp_scheduler_schedule_on_group(struct mali_group *group) { struct mali_gp_job *job; MALI_DEBUG_ASSERT_LOCK_HELD(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_gp_scheduler_unlock(); 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)); return; /* Nothing to do, so early out */ } /* Get (and remove) next job in queue */ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list); _mali_osk_list_del(&job->list); /* Mark slot as busy */ slot.state = MALI_GP_SLOT_STATE_WORKING; mali_gp_scheduler_unlock(); MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job)); if (_MALI_OSK_ERR_OK != mali_group_start_gp_job(slot.group, job)) { MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n")); MALI_DEBUG_ASSERT(0); /* this cant fail on Mali-300+, no need to implement put back of job */ } }
void mali_gp_scheduler_abort_session(struct mali_session_data *session) { struct mali_gp_job *job, *tmp; mali_gp_scheduler_lock(); MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session)); /* Check queue for jobs and remove */ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list) { if (mali_gp_job_get_session(job) == session) { MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job)); _mali_osk_list_del(&(job->list)); mali_gp_job_delete(job); } } mali_gp_scheduler_unlock(); /* Abort running jobs from this session. It is safe to do this outside * the scheduler lock as there is only one GP core, and the queue has * already been emptied, as long as there are no new jobs coming in * from user space. */ mali_group_abort_session(slot.group, session); }
static void mali_gp_scheduler_schedule(void) { struct mali_gp_job *job; MALI_ASSERT_GP_SCHEDULER_LOCKED(); if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue)) { 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)); return; /* Nothing to do, so early out */ } job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list); MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job)); if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job)) { /* Mark slot as busy */ slot.state = MALI_GP_SLOT_STATE_WORKING; /* Remove from queue of unscheduled jobs */ _mali_osk_list_del(&job->list); } else { MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n")); } }
void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) { memory_engine * engine = (memory_engine*)mem_engine; mali_physical_memory_allocation * active_allocation_tracker; /* Remove this from a tracking list in session_data->memory_head */ if ( ! _mali_osk_list_empty( &descriptor->list ) ) { _mali_osk_list_del( &descriptor->list ); /* Clear the list for debug mode, catch use-after-free */ MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; ) }
void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) { memory_engine * engine = (memory_engine*)mem_engine; mali_physical_memory_allocation * active_allocation_tracker; MALI_DEBUG_ASSERT_POINTER(engine); MALI_DEBUG_ASSERT_POINTER(descriptor); /* Determine whether we need to remove this from a tracking list */ if ( ! _mali_osk_list_empty( &descriptor->list ) ) { _mali_osk_list_del( &descriptor->list ); /* Clear the list for debug mode, catch use-after-free */ MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; ) }
static void mali_soft_job_system_free_job(struct mali_soft_job_system *system, struct mali_soft_job *job) { MALI_DEBUG_ASSERT_POINTER(job); MALI_DEBUG_ASSERT_POINTER(system); mali_soft_job_system_lock(job->system); MALI_DEBUG_ASSERT(MALI_SOFT_JOB_INVALID_ID != job->id); MALI_DEBUG_ASSERT(system == job->system); _mali_osk_list_del(&(job->system_list)); mali_soft_job_system_unlock(job->system); _mali_osk_free(job); }
void mali_pp_scheduler_abort_session(struct mali_session_data *session) { struct mali_pp_job *job, *tmp; int i; mali_pp_scheduler_lock(); MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session)); /* Check queue for jobs and remove */ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list) { if (mali_pp_job_get_session(job) == session) { _mali_osk_list_del(&(job->list)); if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) ) { /* The job is in the render pipeline, we can not delete it yet. */ /* It will be deleted in the mali_group_abort_session() call below */ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in queue\n", job)); continue; } MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Removing PP job 0x%08x from queue\n", job)); mali_pp_job_delete(job); } } mali_pp_scheduler_unlock(); /* Abort running jobs from this session */ for (i = 0; i < num_slots; i++) { struct mali_group *group = slots[i].group; MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group)); if (MALI_PP_SLOT_STATE_WORKING == slots[i].state) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group)); mali_group_abort_session(group, session); } } }
_mali_osk_errcode_t _mali_ukk_close(void **context) { int i; #ifdef MALI_SESSION_MEMORY_USAGE struct mali_session_data_list * session_data_list; #endif struct mali_session_data * session_data; MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); session_data = (struct mali_session_data *)*context; #ifdef MALI_SESSION_MEMORY_USAGE session_data_list = (struct mali_session_data_list *)session_data->list; #endif MALI_DEBUG_PRINT(2, ("Session ending\n")); /* end subsystem sessions in the reverse order they where started in */ for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_lock_wait( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_list_del(&session_data_list->list_head); _mali_osk_lock_signal( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_free(session_data_list); #endif *context = NULL; MALI_DEBUG_PRINT(2, ("Session has ended\n")); MALI_SUCCESS; }
void mali_gp_scheduler_abort_session(struct mali_session_data *session) { struct mali_gp_job *job, *tmp; mali_gp_scheduler_lock(); MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session)); _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list) { if (mali_gp_job_get_session(job) == session) { MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job)); _mali_osk_list_del(&(job->list)); mali_gp_job_delete(job); } } mali_gp_scheduler_unlock(); mali_group_abort_session(slot.group, session); }
static void mali_pp_scheduler_schedule(void) { u32 i; struct mali_pp_job *job; #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS struct mali_session_data * session; #endif MALI_ASSERT_PP_SCHEDULER_LOCKED(); if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue)) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", pause_count, num_slots_idle)); return; /* Nothing to do, so early out */ } #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP if ( num_slots_idle < num_slots ) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots)); return; } #endif #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS /* Finding initial session for the PP cores */ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); session = job->session; if ( num_slots != num_slots_idle ) { for (i = 0; (i < num_slots) ; i++) { if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE ) { continue; } session = mali_group_get_session(slots[i].group); break; } } #endif for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++) { u32 sub_job; if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */ { break; /* No more jobs to schedule, so early out */ } if (MALI_PP_SLOT_STATE_IDLE != slots[i].state) { continue; } job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */ if (MALI_TRUE == mali_pp_job_has_active_barrier(job)) { if (MALI_TRUE == mali_pp_scheduler_session_has_running_jobs(mali_pp_job_get_session(job))) { /* There is already a running job from this session, so we need to enforce the barrier */ return; } else { /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */ mali_pp_job_barrier_enforced(job); } } #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle)) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots)); return; } #endif #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS if ( job->session != session ) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n")); return; } #endif sub_job = mali_pp_job_get_first_unstarted_sub_job(job); MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job)) { MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); /* Mark this sub job as started */ mali_pp_job_mark_sub_job_started(job, sub_job); /* Mark slot as busy */ slots[i].state = MALI_PP_SLOT_STATE_WORKING; slots[i].session = mali_pp_job_get_session(job); num_slots_idle--; if (!mali_pp_job_has_unstarted_sub_jobs(job)) { /* * All sub jobs have now started for this job, remove this job from the job queue. * The job will now only be referred to by the slots which are running it. * The last slot to complete will make sure it is returned to user space. */ _mali_osk_list_del(&job->list); #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n")); return; #endif } } else { MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n")); return; } } }