aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/mali/common/mali_pp_scheduler.c')
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.c248
1 files changed, 124 insertions, 124 deletions
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
index eedf661..a944055 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
+++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
@@ -17,8 +17,6 @@
#include "mali_pp_job.h"
#include "mali_group.h"
#include "mali_cluster.h"
-#include "mali_osk_profiling.h"
-
/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
#define MALI_MAX_NUMBER_OF_PP_GROUPS 8
@@ -41,14 +39,10 @@ struct mali_pp_slot
*/
enum mali_pp_slot_state state;
struct mali_session_data *session;
- struct mali_pp_job *job;
- u32 subjob;
};
static u32 pp_version = 0;
static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
-static u32 job_queue_depth;
-
static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS];
static u32 num_slots = 0;
static u32 num_slots_idle = 0;
@@ -67,7 +61,7 @@ _mali_osk_errcode_t mali_pp_scheduler_initialize(void)
_MALI_OSK_INIT_LIST_HEAD(&job_queue);
- pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
if (NULL == pp_scheduler_lock)
{
return _MALI_OSK_ERR_NOMEM;
@@ -160,7 +154,7 @@ static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_
for (i = 0; i < num_slots; i++)
{
if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
- {
+ {
if (slots[i].session == session)
{
return MALI_TRUE;
@@ -171,123 +165,131 @@ static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_
return MALI_FALSE;
}
-static mali_bool slots_available(void)
-{
- return num_slots_idle > 0;
-}
-
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 || 0 == job_queue_depth)
+ 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 */
}
- while(slots_available() && 0 < job_queue_depth)
+
+#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 i, slot_count;
- struct mali_pp_slot *reserved_slots[num_slots];
- struct mali_session_data *session;
+ u32 sub_job;
- mali_pp_scheduler_lock();
- /* Get job */
- if (_mali_osk_list_empty(&job_queue) || !slots_available())
+ if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */
{
- mali_pp_scheduler_unlock();
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 */
- session = mali_pp_job_get_session(job);
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 */
- mali_pp_scheduler_unlock();
+ /* 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 */
+ /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */
mali_pp_job_barrier_enforced(job);
}
}
- /* Reserve slots */
- for (i = 0, slot_count = 0; i < num_slots; i++)
+ #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))
{
- struct mali_pp_slot *slot = &slots[i];
-
- if (MALI_PP_SLOT_STATE_IDLE != slot->state) continue;
-
- slot->state = MALI_PP_SLOT_STATE_WORKING;
- slot->session = session;
- slot->job = job;
- slot->subjob = mali_pp_job_get_first_unstarted_sub_job(job);
- mali_pp_job_mark_sub_job_started(job, slot->subjob);
- --job_queue_depth;
-
- --num_slots_idle;
- reserved_slots[slot_count++] = slot;
-
- if (!mali_pp_job_has_unstarted_sub_jobs(job))
- {
- _mali_osk_list_del(&job->list);
- break;
- }
+ 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
- MALI_DEBUG_ASSERT(0 < slot_count);
+ #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
- mali_pp_scheduler_unlock();
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
- /* Start (sub)job(s) on core(s) */
- for(i = 0; i < slot_count; i++)
+ 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))
{
- struct mali_pp_slot *slot = reserved_slots[i];
- struct mali_pp_job *job;
- u32 subjob;
+ 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)));
- MALI_DEBUG_ASSERT_POINTER(slot);
- MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slot->state);
- MALI_DEBUG_ASSERT_POINTER(slot->job);
+ /* Mark this sub job as started */
+ mali_pp_job_mark_sub_job_started(job, sub_job);
- job = slot->job;
- subjob = slot->subjob;
+ /* 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_OSK_ERR_OK == mali_group_start_pp_job(slot->group, slot->job, slot->subjob))
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n",
- mali_pp_job_get_id(job), job, subjob + 1,
- mali_pp_job_get_sub_job_count(job)));
- }
- else
+ if (!mali_pp_job_has_unstarted_sub_jobs(job))
{
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
- /* This can only happen on Mali-200 */
-#if !defined(USING_MALI200)
- MALI_DEBUG_ASSERT(0);
+ /*
+ * 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
- mali_pp_scheduler_lock();
- /* Put job back on queue */
- mali_pp_job_mark_sub_job_not_stated(job, subjob);
- _mali_osk_list_add(&job->list, &job_queue);
- /* Set slot idle */
- slot->state = MALI_PP_SLOT_STATE_IDLE;
- slot->session = NULL;
- slot->job = NULL;
- slot->subjob = 0;
- mali_pp_scheduler_unlock();
}
}
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
+ return;
+ }
}
}
@@ -333,42 +335,35 @@ static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job)
void mali_pp_scheduler_do_schedule(void)
{
+ mali_pp_scheduler_lock();
+
mali_pp_scheduler_schedule();
+
+ mali_pp_scheduler_unlock();
}
void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
{
u32 i;
- struct mali_pp_slot *slot = NULL;
mali_bool job_is_done;
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n",
- mali_pp_job_get_id(job),
- job, sub_job + 1,
- mali_pp_job_get_sub_job_count(job),
- success ? "success" : "failure"));
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure"));
mali_pp_scheduler_lock();
- mali_pp_job_mark_sub_job_completed(job, success);
-
/* Find slot which was running this job */
for (i = 0; i < num_slots; i++)
{
- slot = &slots[i];
- if (slot->group == group)
- break;
+ if (slots[i].group == group)
+ {
+ MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state);
+ slots[i].state = MALI_PP_SLOT_STATE_IDLE;
+ slots[i].session = NULL;
+ num_slots_idle++;
+ mali_pp_job_mark_sub_job_completed(job, success);
+ }
}
- MALI_DEBUG_ASSERT_POINTER(slot);
-
- slot->state = MALI_PP_SLOT_STATE_IDLE;
- slot->session = NULL;
- slot->job = NULL;
- slot->subjob = 0;
-
- num_slots_idle++;
-
/* If paused, then this was the last job, so wake up sleeping workers */
if (pause_count > 0)
{
@@ -378,6 +373,10 @@ void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *jo
*/
_mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
}
+ else
+ {
+ mali_pp_scheduler_schedule();
+ }
job_is_done = mali_pp_job_is_complete(job);
@@ -389,8 +388,6 @@ void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *jo
MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job));
mali_pp_scheduler_return_job_to_user(job);
}
-
- mali_pp_scheduler_schedule();
}
void mali_pp_scheduler_suspend(void)
@@ -399,7 +396,11 @@ void mali_pp_scheduler_suspend(void)
pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
mali_pp_scheduler_unlock();
- /* Go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
+ /*mali_pp_scheduler_working_lock();*/
+ /* We have now aquired the working lock, which means that we have successfully paused the scheduler */
+ /*mali_pp_scheduler_working_unlock();*/
+
+ /* go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
* mali_pp_scheduler_suspended() function will be called. This will return true
* iff state is idle and pause_count > 0, so if the core is active this
* will not do anything.
@@ -418,17 +419,17 @@ void mali_pp_scheduler_resume(void)
mali_pp_scheduler_unlock();
}
-_mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *uargs)
+_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args)
{
struct mali_session_data *session;
struct mali_pp_job *job;
- MALI_DEBUG_ASSERT_POINTER(uargs);
- MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
- session = (struct mali_session_data*)ctx;
+ session = (struct mali_session_data*)args->ctx;
- job = mali_pp_job_create(session, uargs, mali_scheduler_get_new_id());
+ job = mali_pp_job_create(session, args, mali_scheduler_get_new_id());
if (NULL == job)
{
return _MALI_OSK_ERR_NOMEM;
@@ -450,15 +451,13 @@ _mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *u
mali_pp_scheduler_lock();
- job_queue_depth += mali_pp_job_get_sub_job_count(job);
_mali_osk_list_addtail(&job->list, &job_queue);
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n",
- mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
- mali_pp_scheduler_unlock();
+ mali_pp_scheduler_schedule();
- if (slots_available()) mali_pp_scheduler_schedule();
+ mali_pp_scheduler_unlock();
return _MALI_OSK_ERR_OK;
}
@@ -490,8 +489,9 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
session = (struct mali_session_data*)args->ctx;
- /* Check queue for jobs that match */
mali_pp_scheduler_lock();
+
+ /* Check queue for jobs that match */
_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
{
if (mali_pp_job_get_session(job) == session &&
@@ -513,6 +513,7 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
break;
}
}
+
mali_pp_scheduler_unlock();
}
@@ -530,7 +531,6 @@ void mali_pp_scheduler_abort_session(struct mali_session_data *session)
if (mali_pp_job_get_session(job) == session)
{
_mali_osk_list_del(&(job->list));
- job_queue_depth -= mali_pp_job_get_sub_job_count(job) - mali_pp_job_get_first_unstarted_sub_job(job);
if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) )
{
@@ -551,9 +551,14 @@ void mali_pp_scheduler_abort_session(struct mali_session_data *session)
{
struct mali_group *group = slots[i].group;
- MALI_DEBUG_PRINT(5, ("PP sched abort: Attempting abort for session 0x%08x on group 0x%08x\n", session, 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_group_abort_session(group, session);
+ }
}
}
@@ -568,11 +573,6 @@ static mali_bool mali_pp_scheduler_is_suspended(void)
return ret;
}
-int mali_pp_scheduler_get_queue_depth(void)
-{
- return job_queue_depth;
-}
-
#if MALI_STATE_TRACKING
u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
{