/* * Here we implement the mock "GPU" (or the scheduler backend) which is used by * the DRM scheduler unit tests in order to exercise the core functionality. * * Test cases are implemented in a separate file.
*/
/** * drm_mock_sched_entity_new - Create a new mock scheduler entity * * @test: KUnit test owning the entity * @priority: Scheduling priority * @sched: Mock scheduler on which the entity can be scheduled * * Returns: New mock scheduler entity with allocation managed by the test
*/ struct drm_mock_sched_entity *
drm_mock_sched_entity_new(struct kunit *test, enum drm_sched_priority priority, struct drm_mock_scheduler *sched)
{ struct drm_mock_sched_entity *entity; struct drm_gpu_scheduler *drm_sched; int ret;
/** * drm_mock_sched_entity_free - Destroys a mock scheduler entity * * @entity: Entity to destroy * * To be used from the test cases once done with the entity.
*/ void drm_mock_sched_entity_free(struct drm_mock_sched_entity *entity)
{
drm_sched_entity_destroy(&entity->base);
}
/** * drm_mock_sched_job_new - Create a new mock scheduler job * * @test: KUnit test owning the job * @entity: Scheduler entity of the job * * Returns: New mock scheduler job with allocation managed by the test
*/ struct drm_mock_sched_job *
drm_mock_sched_job_new(struct kunit *test, struct drm_mock_sched_entity *entity)
{ struct drm_mock_sched_job *job; int ret;
/* * Normally, drivers would take appropriate measures in this callback, such as * killing the entity the faulty job is associated with, resetting the hardware * and / or resubmitting non-faulty jobs. * * For the mock scheduler, there are no hardware rings to be resetted nor jobs * to be resubmitted. Thus, this function merely ensures that * a) timedout fences get signaled properly and removed from the pending list * b) the mock scheduler framework gets informed about the timeout via a flag * c) The drm_sched_job, not longer needed, gets freed
*/ staticenum drm_gpu_sched_stat
mock_sched_timedout_job(struct drm_sched_job *sched_job)
{ struct drm_mock_scheduler *sched = drm_sched_to_mock_sched(sched_job->sched); struct drm_mock_sched_job *job = drm_sched_job_to_mock_job(sched_job); unsignedlong flags;
/** * drm_mock_sched_fini - Destroys a mock scheduler * * @sched: Scheduler to destroy * * To be used from the test cases once done with the scheduler.
*/ void drm_mock_sched_fini(struct drm_mock_scheduler *sched)
{
drm_sched_fini(&sched->base);
}
/** * drm_mock_sched_advance - Advances the mock scheduler timeline * * @sched: Scheduler timeline to advance * @num: By how many jobs to advance * * Advancing the scheduler timeline by a number of seqnos will trigger * signalling of the hardware fences and unlinking the jobs from the internal * scheduler tracking. * * This can be used from test cases which want complete control of the simulated * job execution timing. For example submitting one job with no set duration * would never complete it before test cases advances the timeline by one.
*/ unsignedint drm_mock_sched_advance(struct drm_mock_scheduler *sched, unsignedint num)
{ struct drm_mock_sched_job *job, *next; unsignedint found = 0; unsignedlong flags;
LIST_HEAD(signal);
spin_lock_irqsave(&sched->lock, flags); if (WARN_ON_ONCE(sched->hw_timeline.cur_seqno + num <
sched->hw_timeline.cur_seqno)) goto unlock;
sched->hw_timeline.cur_seqno += num;
list_for_each_entry_safe(job, next, &sched->job_list, link) { if (sched->hw_timeline.cur_seqno < job->hw_fence.seqno) break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.