File Index
Files and directories
Sign in
FILE

sched_tests.h

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/scheduler/tests/sched_tests.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/* Copyright (c) 2025 Valve Corporation */
  3
  4#ifndef _SCHED_TESTS_H_
  5#define _SCHED_TESTS_H_
  6
  7#include <kunit/test.h>
  8#include <linux/atomic.h>
  9#include <linux/completion.h>
 10#include <linux/dma-fence.h>
 11#include <linux/hrtimer.h>
 12#include <linux/ktime.h>
 13#include <linux/list.h>
 14#include <linux/mutex.h>
 15#include <linux/types.h>
 16
 17#include <drm/gpu_scheduler.h>
 18
 19/*
 20 * DOC: Mock DRM scheduler data structures
 21 *
 22 * drm_mock_* data structures are used to implement a mock "GPU".
 23 *
 24 * They subclass the core DRM scheduler objects and add their data on top, which
 25 * enables tracking the submitted jobs and simulating their execution with the
 26 * attributes as specified by the test case.
 27 */
 28
 29/**
 30 * struct drm_mock_scheduler - implements a trivial mock GPU execution engine
 31 *
 32 * @base: DRM scheduler base class
 33 * @test: Backpointer to owning the kunit test case
 34 * @lock: Lock to protect the simulated @hw_timeline and @job_list
 35 * @job_list: List of jobs submitted to the mock GPU
 36 * @hw_timeline: Simulated hardware timeline has a @context, @next_seqno and
 37 *		 @cur_seqno for implementing a struct dma_fence signaling the
 38 *		 simulated job completion.
 39 *
 40 * Trivial mock GPU execution engine tracks submitted jobs and enables
 41 * completing them strictly in submission order.
 42 */
 43struct drm_mock_scheduler {
 44	struct drm_gpu_scheduler base;
 45
 46	struct kunit		*test;
 47
 48	spinlock_t		lock;
 49	struct list_head	job_list;
 50
 51	struct {
 52		u64		context;
 53		atomic_t	next_seqno;
 54		unsigned int	cur_seqno;
 55	} hw_timeline;
 56};
 57
 58/**
 59 * struct drm_mock_sched_entity - implements a mock GPU sched entity
 60 *
 61 * @base: DRM scheduler entity base class
 62 * @test: Backpointer to owning the kunit test case
 63 *
 64 * Mock GPU sched entity is used by the test cases to submit jobs to the mock
 65 * scheduler.
 66 */
 67struct drm_mock_sched_entity {
 68	struct drm_sched_entity base;
 69
 70	struct kunit		*test;
 71};
 72
 73/**
 74 * struct drm_mock_sched_job - implements a mock GPU job
 75 *
 76 * @base: DRM sched job base class
 77 * @done: Completion signaling job completion.
 78 * @flags: Flags designating job state.
 79 * @link: List head element used by job tracking by the drm_mock_scheduler
 80 * @timer: Timer used for simulating job execution duration
 81 * @duration_us: Simulated job duration in micro seconds, or zero if in manual
 82 *		 timeline advance mode
 83 * @finish_at: Absolute time when the jobs with set duration will complete
 84 * @lock: Lock used for @hw_fence
 85 * @hw_fence: Fence returned to DRM scheduler as the hardware fence
 86 * @test: Backpointer to owning the kunit test case
 87 *
 88 * Mock GPU sched job is used by the test cases to submit jobs to the mock
 89 * scheduler.
 90 */
 91struct drm_mock_sched_job {
 92	struct drm_sched_job	base;
 93
 94	struct completion	done;
 95
 96#define DRM_MOCK_SCHED_JOB_DONE			0x1
 97#define DRM_MOCK_SCHED_JOB_TIMEDOUT		0x2
 98#define DRM_MOCK_SCHED_JOB_DONT_RESET		0x4
 99#define DRM_MOCK_SCHED_JOB_RESET_SKIPPED	0x8
100	unsigned long		flags;
101
102	struct list_head	link;
103	struct hrtimer		timer;
104
105	unsigned int		duration_us;
106	ktime_t			finish_at;
107
108	struct dma_fence	hw_fence;
109
110	struct kunit		*test;
111};
112
113static inline struct drm_mock_scheduler *
114drm_sched_to_mock_sched(struct drm_gpu_scheduler *sched)
115{
116	return container_of(sched, struct drm_mock_scheduler, base);
117};
118
119static inline struct drm_mock_sched_entity *
120drm_sched_entity_to_mock_entity(struct drm_sched_entity *sched_entity)
121{
122	return container_of(sched_entity, struct drm_mock_sched_entity, base);
123};
124
125static inline struct drm_mock_sched_job *
126drm_sched_job_to_mock_job(struct drm_sched_job *sched_job)
127{
128	return container_of(sched_job, struct drm_mock_sched_job, base);
129};
130
131struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test,
132					      long timeout);
133void drm_mock_sched_fini(struct drm_mock_scheduler *sched);
134unsigned int drm_mock_sched_advance(struct drm_mock_scheduler *sched,
135				    unsigned int num);
136
137struct drm_mock_sched_entity *
138drm_mock_sched_entity_new(struct kunit *test,
139			  enum drm_sched_priority priority,
140			  struct drm_mock_scheduler *sched);
141void drm_mock_sched_entity_free(struct drm_mock_sched_entity *entity);
142
143struct drm_mock_sched_job *
144drm_mock_sched_job_new(struct kunit *test,
145		       struct drm_mock_sched_entity *entity);
146
147/**
148 * drm_mock_sched_job_submit - Arm and submit a job in one go
149 *
150 * @job: Job to arm and submit
151 */
152static inline void drm_mock_sched_job_submit(struct drm_mock_sched_job *job)
153{
154	drm_sched_job_arm(&job->base);
155	drm_sched_entity_push_job(&job->base);
156}
157
158/**
159 * drm_mock_sched_job_set_duration_us - Set a job duration
160 *
161 * @job: Job to set the duration for
162 * @duration_us: Duration in micro seconds
163 *
164 * Jobs with duration set will be automatically completed by the mock scheduler
165 * as the timeline progresses, unless a job without a set duration is
166 * encountered in the timelime in which case calling drm_mock_sched_advance()
167 * will be required to bump the timeline.
168 */
169static inline void
170drm_mock_sched_job_set_duration_us(struct drm_mock_sched_job *job,
171				   unsigned int duration_us)
172{
173	job->duration_us = duration_us;
174}
175
176/**
177 * drm_mock_sched_job_is_finished - Check if a job is finished
178 *
179 * @job: Job to check
180 *
181 * Returns: true if finished
182 */
183static inline bool
184drm_mock_sched_job_is_finished(struct drm_mock_sched_job *job)
185{
186	return job->flags & DRM_MOCK_SCHED_JOB_DONE;
187}
188
189/**
190 * drm_mock_sched_job_wait_finished - Wait until a job is finished
191 *
192 * @job: Job to wait for
193 * @timeout: Wait time in jiffies
194 *
195 * Returns: true if finished within the timeout provided, otherwise false
196 */
197static inline bool
198drm_mock_sched_job_wait_finished(struct drm_mock_sched_job *job, long timeout)
199{
200	if (job->flags & DRM_MOCK_SCHED_JOB_DONE)
201		return true;
202
203	return wait_for_completion_timeout(&job->done, timeout) != 0;
204}
205
206/**
207 * drm_mock_sched_job_wait_scheduled - Wait until a job is scheduled
208 *
209 * @job: Job to wait for
210 * @timeout: Wait time in jiffies
211 *
212 * Returns: true if scheduled within the timeout provided, otherwise false
213 */
214static inline bool
215drm_mock_sched_job_wait_scheduled(struct drm_mock_sched_job *job, long timeout)
216{
217	KUNIT_ASSERT_EQ(job->test, job->flags & DRM_MOCK_SCHED_JOB_DONE, 0);
218
219	return dma_fence_wait_timeout(&job->base.s_fence->scheduled,
220				      false,
221				      timeout) != 0;
222}
223
224#endif
~/ Read-only file preview.