void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
{
	_mali_uk_gp_job_suspended_s * jobres;
	_mali_osk_notification_t * notification;

	mali_gp_scheduler_lock();

	notification = job->oom_notification;
	job->oom_notification = NULL;
	slot.returned_cookie = mali_gp_job_get_id(job);

	jobres = (_mali_uk_gp_job_suspended_s *)notification->result_buffer;
	jobres->user_job_ptr = mali_gp_job_get_user_id(job);
	jobres->cookie = mali_gp_job_get_id(job);

	mali_gp_scheduler_unlock();

	jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;

	mali_session_send_notification(mali_gp_job_get_session(job), notification);

	/*
	* If this function failed, then we could return the job to user space right away,
	* but there is a job timer anyway that will do that eventually.
	* This is not exactly a common case anyway.
	*/
}
Пример #2
0
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);
}
Пример #3
0
static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
{
	_mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
	if (NULL != notobj)
	{
		_mali_uk_gp_job_finished_s *jobres = notobj->result_buffer;
		_mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
		jobres->user_job_ptr = mali_gp_job_get_user_id(job);
		if (MALI_TRUE == success)
		{
			jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
		}
		else
		{
			jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
		}

		jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job);
		jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job);
		jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job);

		mali_session_send_notification(mali_gp_job_get_session(job), notobj);
	}
	else
	{
		MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n"));
	}

	mali_gp_job_delete(job);
}
Пример #4
0
void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
{
	_mali_osk_notification_t *notobj;

	notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));

	if (NULL != notobj)
	{
		_mali_uk_gp_job_suspended_s * jobres;

		mali_gp_scheduler_lock();

		jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer;

		jobres->user_job_ptr = mali_gp_job_get_user_id(job);
		jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
		jobres->cookie = mali_gp_job_get_id(job);
		slot.returned_cookie = jobres->cookie;

		mali_session_send_notification(mali_gp_job_get_session(job), notobj);

		mali_gp_scheduler_unlock();
	}

	/*
	* If this function failed, then we could return the job to user space right away,
	* but there is a job timer anyway that will do that eventually.
	* This is not exactly a common case anyway.
	*/
}
Пример #5
0
void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
{
	_mali_osk_notification_t *notobj;

	notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));

	if (NULL != notobj)
	{
		_mali_uk_gp_job_suspended_s * jobres;

		mali_gp_scheduler_lock();

		jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer;

		jobres->user_job_ptr = mali_gp_job_get_user_id(job);
		jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
		jobres->cookie = mali_gp_job_get_id(job);
		slot.returned_cookie = jobres->cookie;

		mali_session_send_notification(mali_gp_job_get_session(job), notobj);

		mali_gp_scheduler_unlock();
	}

}
void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session)
{
	struct mali_gp_job *gp_job;
	struct mali_pp_job *pp_job;
	u32 gp_job_id = 0;
	u32 pp_job_id = 0;
	mali_bool abort_pp = MALI_FALSE;
	mali_bool abort_gp = MALI_FALSE;

	mali_group_lock(group);

	gp_job = group->gp_running_job;
	pp_job = group->pp_running_job;

	if (gp_job && mali_gp_job_get_session(gp_job) == session)
	{
		MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session));

		gp_job_id = mali_gp_job_get_id(gp_job);
		abort_gp = MALI_TRUE;
	}

	if (pp_job && mali_pp_job_get_session(pp_job) == session)
	{
		MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session));

		pp_job_id = mali_pp_job_get_id(pp_job);
		abort_pp = MALI_TRUE;
	}

	mali_group_unlock(group);

	/* These functions takes and releases the group lock */
	if (0 != abort_gp)
	{
		mali_group_abort_gp_job(group, gp_job_id);
	}
	if (0 != abort_pp)
	{
		mali_group_abort_pp_job(group, pp_job_id);
	}

	mali_group_lock(group);
	mali_group_remove_session_if_unused(group, session);
	mali_group_unlock(group);
}
_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job)
{
	struct mali_session_data *session;
	enum mali_group_activate_pd_status activate_status;

	MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);

	mali_pm_core_event(MALI_CORE_EVENT_GP_START);

	session = mali_gp_job_get_session(job);

	mali_group_lock(group);

	mali_cluster_l2_cache_invalidate_all(group->cluster, mali_gp_job_get_id(job));

	activate_status = mali_group_activate_page_directory(group, session);
	if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
	{
		/* if session is NOT kept Zapping is done as part of session switch */
		if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
		{
			mali_mmu_zap_tlb_without_stall(group->mmu);
		}
		mali_gp_job_start(group->gp_core, job);
		group->gp_running_job = job;
		group->gp_state = MALI_GROUP_CORE_STATE_WORKING;

		mali_group_unlock(group);

		return _MALI_OSK_ERR_OK;
	}

#if defined(USING_MALI200)
	group->pagedir_activation_failed = MALI_TRUE;
#endif

	mali_group_unlock(group);

	mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */
	return _MALI_OSK_ERR_FAULT;
}
Пример #8
0
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_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
{
	_mali_uk_gp_job_finished_s *jobres = job->finished_notification->result_buffer;
	_mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
	jobres->user_job_ptr = mali_gp_job_get_user_id(job);
	if (MALI_TRUE == success)
	{
		jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
	}
	else
	{
		jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
	}

	jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job);
	jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job);
	jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job);

	mali_session_send_notification(mali_gp_job_get_session(job), job->finished_notification);
	job->finished_notification = NULL;

	mali_gp_job_delete(job);
}
/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */
static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success)
{
	mali_bool need_group_reset = MALI_FALSE;
	mali_bool gp_success = success;
	mali_bool pp_success = success;

	MALI_ASSERT_GROUP_LOCKED(group);

	if (complete_gp && !complete_pp)
	{
		MALI_DEBUG_ASSERT_POINTER(group->gp_core);
		if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core))
		{
			struct mali_gp_job *gp_job_to_return = group->gp_running_job;
			group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
			group->gp_running_job = NULL;

			MALI_DEBUG_ASSERT_POINTER(gp_job_to_return);

			mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));

			if(mali_group_other_reschedule_needed(group))
			{
				mali_group_unlock(group);
				mali_pp_scheduler_do_schedule();
			}
			else
			{
				mali_group_unlock(group);
			}

			mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
			mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */

			return;
		}
		else
		{
			need_group_reset = MALI_TRUE;
			MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
			pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */
		}
	}
	if (complete_pp && !complete_gp)
	{
		MALI_DEBUG_ASSERT_POINTER(group->pp_core);
		if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core))
		{
			struct mali_pp_job *pp_job_to_return = group->pp_running_job;
			u32 pp_sub_job_to_return = group->pp_running_sub_job;
			group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
			group->pp_running_job = NULL;

			MALI_DEBUG_ASSERT_POINTER(pp_job_to_return);

			mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));

			if(mali_group_other_reschedule_needed(group))
			{
				mali_group_unlock(group);
				mali_gp_scheduler_do_schedule();
			}
			else
			{
				mali_group_unlock(group);
			}

			mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
			mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */

			return;
		}
		else
		{
			need_group_reset = MALI_TRUE;
			MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
			gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */
		}
	}
	else if (complete_gp && complete_pp)
	{
		need_group_reset = MALI_TRUE;
	}

	if (MALI_TRUE == need_group_reset)
	{
		struct mali_gp_job *gp_job_to_return = group->gp_running_job;
		struct mali_pp_job *pp_job_to_return = group->pp_running_job;
		u32 pp_sub_job_to_return = group->pp_running_sub_job;
		mali_bool schedule_other = MALI_FALSE;

		MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n"));

		group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
		group->gp_running_job = NULL;
		if (NULL != gp_job_to_return)
		{
			mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
		}

		group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
		group->pp_running_job = NULL;
		if (NULL != pp_job_to_return)
		{
			mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
		}

		/* The reset has to be done after mali_group_deactivate_page_directory() */
		mali_group_recovery_reset(group);

		if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return))
		{
			schedule_other = MALI_TRUE;
		}

		mali_group_unlock(group);

		if (NULL != gp_job_to_return)
		{
			mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
			mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
		}
		else if (schedule_other)
		{
			mali_pp_scheduler_do_schedule();
		}

		if (NULL != pp_job_to_return)
		{
			mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
			mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
		}
		else if (schedule_other)
		{
			mali_gp_scheduler_do_schedule();
		}

		return;
	}

	mali_group_unlock(group);
}