FILE
sched_tests.h
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/scheduler/tests/sched_tests.h
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.