gpu_scheduler.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /*
  2. * Copyright 2015 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. */
  23. #ifndef _DRM_GPU_SCHEDULER_H_
  24. #define _DRM_GPU_SCHEDULER_H_
  25. #include <drm/spsc_queue.h>
  26. #include <linux/dma-fence.h>
  27. #include <linux/completion.h>
  28. #include <linux/xarray.h>
  29. #include <linux/workqueue.h>
  30. #define MAX_WAIT_SCHED_ENTITY_Q_EMPTY msecs_to_jiffies(1000)
  31. /**
  32. * DRM_SCHED_FENCE_DONT_PIPELINE - Prevent dependency pipelining
  33. *
  34. * Setting this flag on a scheduler fence prevents pipelining of jobs depending
  35. * on this fence. In other words we always insert a full CPU round trip before
  36. * dependent jobs are pushed to the hw queue.
  37. */
  38. #define DRM_SCHED_FENCE_DONT_PIPELINE DMA_FENCE_FLAG_USER_BITS
  39. /**
  40. * DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT - A fence deadline hint has been set
  41. *
  42. * Because we could have a deadline hint can be set before the backing hw
  43. * fence is created, we need to keep track of whether a deadline has already
  44. * been set.
  45. */
  46. #define DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT (DMA_FENCE_FLAG_USER_BITS + 1)
  47. enum dma_resv_usage;
  48. struct dma_resv;
  49. struct drm_gem_object;
  50. struct drm_gpu_scheduler;
  51. struct drm_sched_rq;
  52. struct drm_file;
  53. /* These are often used as an (initial) index
  54. * to an array, and as such should start at 0.
  55. */
  56. enum drm_sched_priority {
  57. DRM_SCHED_PRIORITY_KERNEL,
  58. DRM_SCHED_PRIORITY_HIGH,
  59. DRM_SCHED_PRIORITY_NORMAL,
  60. DRM_SCHED_PRIORITY_LOW,
  61. DRM_SCHED_PRIORITY_COUNT
  62. };
  63. /**
  64. * struct drm_sched_entity - A wrapper around a job queue (typically
  65. * attached to the DRM file_priv).
  66. *
  67. * Entities will emit jobs in order to their corresponding hardware
  68. * ring, and the scheduler will alternate between entities based on
  69. * scheduling policy.
  70. */
  71. struct drm_sched_entity {
  72. /**
  73. * @list:
  74. *
  75. * Used to append this struct to the list of entities in the runqueue
  76. * @rq under &drm_sched_rq.entities.
  77. *
  78. * Protected by &drm_sched_rq.lock of @rq.
  79. */
  80. struct list_head list;
  81. /**
  82. * @lock:
  83. *
  84. * Lock protecting the run-queue (@rq) to which this entity belongs,
  85. * @priority and the list of schedulers (@sched_list, @num_sched_list).
  86. */
  87. spinlock_t lock;
  88. /**
  89. * @rq:
  90. *
  91. * Runqueue on which this entity is currently scheduled.
  92. *
  93. * FIXME: Locking is very unclear for this. Writers are protected by
  94. * @lock, but readers are generally lockless and seem to just race with
  95. * not even a READ_ONCE.
  96. */
  97. struct drm_sched_rq *rq;
  98. /**
  99. * @sched_list:
  100. *
  101. * A list of schedulers (struct drm_gpu_scheduler). Jobs from this entity can
  102. * be scheduled on any scheduler on this list.
  103. *
  104. * This can be modified by calling drm_sched_entity_modify_sched().
  105. * Locking is entirely up to the driver, see the above function for more
  106. * details.
  107. *
  108. * This will be set to NULL if &num_sched_list equals 1 and @rq has been
  109. * set already.
  110. *
  111. * FIXME: This means priority changes through
  112. * drm_sched_entity_set_priority() will be lost henceforth in this case.
  113. */
  114. struct drm_gpu_scheduler **sched_list;
  115. /**
  116. * @num_sched_list:
  117. *
  118. * Number of drm_gpu_schedulers in the @sched_list.
  119. */
  120. unsigned int num_sched_list;
  121. /**
  122. * @priority:
  123. *
  124. * Priority of the entity. This can be modified by calling
  125. * drm_sched_entity_set_priority(). Protected by @lock.
  126. */
  127. enum drm_sched_priority priority;
  128. /**
  129. * @job_queue: the list of jobs of this entity.
  130. */
  131. struct spsc_queue job_queue;
  132. /**
  133. * @fence_seq:
  134. *
  135. * A linearly increasing seqno incremented with each new
  136. * &drm_sched_fence which is part of the entity.
  137. *
  138. * FIXME: Callers of drm_sched_job_arm() need to ensure correct locking,
  139. * this doesn't need to be atomic.
  140. */
  141. atomic_t fence_seq;
  142. /**
  143. * @fence_context:
  144. *
  145. * A unique context for all the fences which belong to this entity. The
  146. * &drm_sched_fence.scheduled uses the fence_context but
  147. * &drm_sched_fence.finished uses fence_context + 1.
  148. */
  149. uint64_t fence_context;
  150. /**
  151. * @dependency:
  152. *
  153. * The dependency fence of the job which is on the top of the job queue.
  154. */
  155. struct dma_fence *dependency;
  156. /**
  157. * @cb:
  158. *
  159. * Callback for the dependency fence above.
  160. */
  161. struct dma_fence_cb cb;
  162. /**
  163. * @guilty:
  164. *
  165. * Points to entities' guilty.
  166. */
  167. atomic_t *guilty;
  168. /**
  169. * @last_scheduled:
  170. *
  171. * Points to the finished fence of the last scheduled job. Only written
  172. * by drm_sched_entity_pop_job(). Can be accessed locklessly from
  173. * drm_sched_job_arm() if the queue is empty.
  174. */
  175. struct dma_fence __rcu *last_scheduled;
  176. /**
  177. * @last_user: last group leader pushing a job into the entity.
  178. */
  179. struct task_struct *last_user;
  180. /**
  181. * @stopped:
  182. *
  183. * Marks the enity as removed from rq and destined for
  184. * termination. This is set by calling drm_sched_entity_flush() and by
  185. * drm_sched_fini().
  186. */
  187. bool stopped;
  188. /**
  189. * @entity_idle:
  190. *
  191. * Signals when entity is not in use, used to sequence entity cleanup in
  192. * drm_sched_entity_fini().
  193. */
  194. struct completion entity_idle;
  195. /**
  196. * @oldest_job_waiting:
  197. *
  198. * Marks earliest job waiting in SW queue
  199. */
  200. ktime_t oldest_job_waiting;
  201. /**
  202. * @rb_tree_node:
  203. *
  204. * The node used to insert this entity into time based priority queue
  205. */
  206. struct rb_node rb_tree_node;
  207. };
  208. /**
  209. * struct drm_sched_rq - queue of entities to be scheduled.
  210. *
  211. * @sched: the scheduler to which this rq belongs to.
  212. * @lock: protects @entities, @rb_tree_root and @current_entity.
  213. * @current_entity: the entity which is to be scheduled.
  214. * @entities: list of the entities to be scheduled.
  215. * @rb_tree_root: root of time based priority queue of entities for FIFO scheduling
  216. *
  217. * Run queue is a set of entities scheduling command submissions for
  218. * one specific ring. It implements the scheduling policy that selects
  219. * the next entity to emit commands from.
  220. */
  221. struct drm_sched_rq {
  222. struct drm_gpu_scheduler *sched;
  223. spinlock_t lock;
  224. /* Following members are protected by the @lock: */
  225. struct drm_sched_entity *current_entity;
  226. struct list_head entities;
  227. struct rb_root_cached rb_tree_root;
  228. };
  229. /**
  230. * struct drm_sched_fence - fences corresponding to the scheduling of a job.
  231. */
  232. struct drm_sched_fence {
  233. /**
  234. * @scheduled: this fence is what will be signaled by the scheduler
  235. * when the job is scheduled.
  236. */
  237. struct dma_fence scheduled;
  238. /**
  239. * @finished: this fence is what will be signaled by the scheduler
  240. * when the job is completed.
  241. *
  242. * When setting up an out fence for the job, you should use
  243. * this, since it's available immediately upon
  244. * drm_sched_job_init(), and the fence returned by the driver
  245. * from run_job() won't be created until the dependencies have
  246. * resolved.
  247. */
  248. struct dma_fence finished;
  249. /**
  250. * @deadline: deadline set on &drm_sched_fence.finished which
  251. * potentially needs to be propagated to &drm_sched_fence.parent
  252. */
  253. ktime_t deadline;
  254. /**
  255. * @parent: the fence returned by &drm_sched_backend_ops.run_job
  256. * when scheduling the job on hardware. We signal the
  257. * &drm_sched_fence.finished fence once parent is signalled.
  258. */
  259. struct dma_fence *parent;
  260. /**
  261. * @sched: the scheduler instance to which the job having this struct
  262. * belongs to.
  263. */
  264. struct drm_gpu_scheduler *sched;
  265. /**
  266. * @lock: the lock used by the scheduled and the finished fences.
  267. */
  268. spinlock_t lock;
  269. /**
  270. * @owner: job owner for debugging
  271. */
  272. void *owner;
  273. /**
  274. * @drm_client_id:
  275. *
  276. * The client_id of the drm_file which owns the job.
  277. */
  278. uint64_t drm_client_id;
  279. };
  280. struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);
  281. /**
  282. * struct drm_sched_job - A job to be run by an entity.
  283. *
  284. * @queue_node: used to append this struct to the queue of jobs in an entity.
  285. * @list: a job participates in a "pending" and "done" lists.
  286. * @sched: the scheduler instance on which this job is scheduled.
  287. * @s_fence: contains the fences for the scheduling of job.
  288. * @finish_cb: the callback for the finished fence.
  289. * @credits: the number of credits this job contributes to the scheduler
  290. * @work: Helper to reschedule job kill to different context.
  291. * @karma: increment on every hang caused by this job. If this exceeds the hang
  292. * limit of the scheduler then the job is marked guilty and will not
  293. * be scheduled further.
  294. * @s_priority: the priority of the job.
  295. * @entity: the entity to which this job belongs.
  296. * @cb: the callback for the parent fence in s_fence.
  297. *
  298. * A job is created by the driver using drm_sched_job_init(), and
  299. * should call drm_sched_entity_push_job() once it wants the scheduler
  300. * to schedule the job.
  301. */
  302. struct drm_sched_job {
  303. /**
  304. * @submit_ts:
  305. *
  306. * When the job was pushed into the entity queue.
  307. */
  308. ktime_t submit_ts;
  309. /**
  310. * @sched:
  311. *
  312. * The scheduler this job is or will be scheduled on. Gets set by
  313. * drm_sched_job_arm(). Valid until drm_sched_backend_ops.free_job()
  314. * has finished.
  315. */
  316. struct drm_gpu_scheduler *sched;
  317. struct drm_sched_fence *s_fence;
  318. struct drm_sched_entity *entity;
  319. enum drm_sched_priority s_priority;
  320. u32 credits;
  321. /** @last_dependency: tracks @dependencies as they signal */
  322. unsigned int last_dependency;
  323. atomic_t karma;
  324. struct spsc_node queue_node;
  325. struct list_head list;
  326. /*
  327. * work is used only after finish_cb has been used and will not be
  328. * accessed anymore.
  329. */
  330. union {
  331. struct dma_fence_cb finish_cb;
  332. struct work_struct work;
  333. };
  334. struct dma_fence_cb cb;
  335. /**
  336. * @dependencies:
  337. *
  338. * Contains the dependencies as struct dma_fence for this job, see
  339. * drm_sched_job_add_dependency() and
  340. * drm_sched_job_add_implicit_dependencies().
  341. */
  342. struct xarray dependencies;
  343. };
  344. /**
  345. * enum drm_gpu_sched_stat - the scheduler's status
  346. *
  347. * @DRM_GPU_SCHED_STAT_NONE: Reserved. Do not use.
  348. * @DRM_GPU_SCHED_STAT_RESET: The GPU hung and successfully reset.
  349. * @DRM_GPU_SCHED_STAT_ENODEV: Error: Device is not available anymore.
  350. * @DRM_GPU_SCHED_STAT_NO_HANG: Contrary to scheduler's assumption, the GPU
  351. * did not hang and is still running.
  352. */
  353. enum drm_gpu_sched_stat {
  354. DRM_GPU_SCHED_STAT_NONE,
  355. DRM_GPU_SCHED_STAT_RESET,
  356. DRM_GPU_SCHED_STAT_ENODEV,
  357. DRM_GPU_SCHED_STAT_NO_HANG,
  358. };
  359. /**
  360. * struct drm_sched_backend_ops - Define the backend operations
  361. * called by the scheduler
  362. *
  363. * These functions should be implemented in the driver side.
  364. */
  365. struct drm_sched_backend_ops {
  366. /**
  367. * @prepare_job:
  368. *
  369. * Called when the scheduler is considering scheduling this job next, to
  370. * get another struct dma_fence for this job to block on. Once it
  371. * returns NULL, run_job() may be called.
  372. *
  373. * Can be NULL if no additional preparation to the dependencies are
  374. * necessary. Skipped when jobs are killed instead of run.
  375. */
  376. struct dma_fence *(*prepare_job)(struct drm_sched_job *sched_job,
  377. struct drm_sched_entity *s_entity);
  378. /**
  379. * @run_job: Called to execute the job once all of the dependencies
  380. * have been resolved.
  381. *
  382. * @sched_job: the job to run
  383. *
  384. * The deprecated drm_sched_resubmit_jobs() (called by &struct
  385. * drm_sched_backend_ops.timedout_job) can invoke this again with the
  386. * same parameters. Using this is discouraged because it violates
  387. * dma_fence rules, notably dma_fence_init() has to be called on
  388. * already initialized fences for a second time. Moreover, this is
  389. * dangerous because attempts to allocate memory might deadlock with
  390. * memory management code waiting for the reset to complete.
  391. *
  392. * TODO: Document what drivers should do / use instead.
  393. *
  394. * This method is called in a workqueue context - either from the
  395. * submit_wq the driver passed through drm_sched_init(), or, if the
  396. * driver passed NULL, a separate, ordered workqueue the scheduler
  397. * allocated.
  398. *
  399. * Note that the scheduler expects to 'inherit' its own reference to
  400. * this fence from the callback. It does not invoke an extra
  401. * dma_fence_get() on it. Consequently, this callback must take a
  402. * reference for the scheduler, and additional ones for the driver's
  403. * respective needs.
  404. *
  405. * Return:
  406. * * On success: dma_fence the driver must signal once the hardware has
  407. * completed the job ("hardware fence").
  408. * * On failure: NULL or an ERR_PTR.
  409. */
  410. struct dma_fence *(*run_job)(struct drm_sched_job *sched_job);
  411. /**
  412. * @timedout_job: Called when a job has taken too long to execute,
  413. * to trigger GPU recovery.
  414. *
  415. * @sched_job: The job that has timed out
  416. *
  417. * Drivers typically issue a reset to recover from GPU hangs.
  418. * This procedure looks very different depending on whether a firmware
  419. * or a hardware scheduler is being used.
  420. *
  421. * For a FIRMWARE SCHEDULER, each ring has one scheduler, and each
  422. * scheduler has one entity. Hence, the steps taken typically look as
  423. * follows:
  424. *
  425. * 1. Stop the scheduler using drm_sched_stop(). This will pause the
  426. * scheduler workqueues and cancel the timeout work, guaranteeing
  427. * that nothing is queued while the ring is being removed.
  428. * 2. Remove the ring. The firmware will make sure that the
  429. * corresponding parts of the hardware are resetted, and that other
  430. * rings are not impacted.
  431. * 3. Kill the entity and the associated scheduler.
  432. *
  433. *
  434. * For a HARDWARE SCHEDULER, a scheduler instance schedules jobs from
  435. * one or more entities to one ring. This implies that all entities
  436. * associated with the affected scheduler cannot be torn down, because
  437. * this would effectively also affect innocent userspace processes which
  438. * did not submit faulty jobs (for example).
  439. *
  440. * Consequently, the procedure to recover with a hardware scheduler
  441. * should look like this:
  442. *
  443. * 1. Stop all schedulers impacted by the reset using drm_sched_stop().
  444. * 2. Kill the entity the faulty job stems from.
  445. * 3. Issue a GPU reset on all faulty rings (driver-specific).
  446. * 4. Re-submit jobs on all schedulers impacted by re-submitting them to
  447. * the entities which are still alive.
  448. * 5. Restart all schedulers that were stopped in step #1 using
  449. * drm_sched_start().
  450. *
  451. * Note that some GPUs have distinct hardware queues but need to reset
  452. * the GPU globally, which requires extra synchronization between the
  453. * timeout handlers of different schedulers. One way to achieve this
  454. * synchronization is to create an ordered workqueue (using
  455. * alloc_ordered_workqueue()) at the driver level, and pass this queue
  456. * as drm_sched_init()'s @timeout_wq parameter. This will guarantee
  457. * that timeout handlers are executed sequentially.
  458. *
  459. * Return: The scheduler's status, defined by &enum drm_gpu_sched_stat
  460. *
  461. */
  462. enum drm_gpu_sched_stat (*timedout_job)(struct drm_sched_job *sched_job);
  463. /**
  464. * @free_job: Called once the job's finished fence has been signaled
  465. * and it's time to clean it up.
  466. */
  467. void (*free_job)(struct drm_sched_job *sched_job);
  468. /**
  469. * @cancel_job: Used by the scheduler to guarantee remaining jobs' fences
  470. * get signaled in drm_sched_fini().
  471. *
  472. * Used by the scheduler to cancel all jobs that have not been executed
  473. * with &struct drm_sched_backend_ops.run_job by the time
  474. * drm_sched_fini() gets invoked.
  475. *
  476. * Drivers need to signal the passed job's hardware fence with an
  477. * appropriate error code (e.g., -ECANCELED) in this callback. They
  478. * must not free the job.
  479. *
  480. * The scheduler will only call this callback once it stopped calling
  481. * all other callbacks forever, with the exception of &struct
  482. * drm_sched_backend_ops.free_job.
  483. */
  484. void (*cancel_job)(struct drm_sched_job *sched_job);
  485. };
  486. /**
  487. * struct drm_gpu_scheduler - scheduler instance-specific data
  488. *
  489. * @ops: backend operations provided by the driver.
  490. * @credit_limit: the credit limit of this scheduler
  491. * @credit_count: the current credit count of this scheduler
  492. * @timeout: the time after which a job is removed from the scheduler.
  493. * @name: name of the ring for which this scheduler is being used.
  494. * @num_rqs: Number of run-queues. This is at most DRM_SCHED_PRIORITY_COUNT,
  495. * as there's usually one run-queue per priority, but could be less.
  496. * @sched_rq: An allocated array of run-queues of size @num_rqs;
  497. * @job_scheduled: once drm_sched_entity_flush() is called the scheduler
  498. * waits on this wait queue until all the scheduled jobs are
  499. * finished.
  500. * @job_id_count: used to assign unique id to the each job.
  501. * @submit_wq: workqueue used to queue @work_run_job and @work_free_job
  502. * @timeout_wq: workqueue used to queue @work_tdr
  503. * @work_run_job: work which calls run_job op of each scheduler.
  504. * @work_free_job: work which calls free_job op of each scheduler.
  505. * @work_tdr: schedules a delayed call to @drm_sched_job_timedout after the
  506. * timeout interval is over.
  507. * @pending_list: the list of jobs which are currently in the job queue.
  508. * @job_list_lock: lock to protect the pending_list.
  509. * @hang_limit: once the hangs by a job crosses this limit then it is marked
  510. * guilty and it will no longer be considered for scheduling.
  511. * @score: score to help loadbalancer pick a idle sched
  512. * @_score: score used when the driver doesn't provide one
  513. * @ready: marks if the underlying HW is ready to work
  514. * @free_guilty: A hit to time out handler to free the guilty job.
  515. * @pause_submit: pause queuing of @work_run_job on @submit_wq
  516. * @own_submit_wq: scheduler owns allocation of @submit_wq
  517. * @dev: system &struct device
  518. *
  519. * One scheduler is implemented for each hardware ring.
  520. */
  521. struct drm_gpu_scheduler {
  522. const struct drm_sched_backend_ops *ops;
  523. u32 credit_limit;
  524. atomic_t credit_count;
  525. long timeout;
  526. const char *name;
  527. u32 num_rqs;
  528. struct drm_sched_rq **sched_rq;
  529. wait_queue_head_t job_scheduled;
  530. atomic64_t job_id_count;
  531. struct workqueue_struct *submit_wq;
  532. struct workqueue_struct *timeout_wq;
  533. struct work_struct work_run_job;
  534. struct work_struct work_free_job;
  535. struct delayed_work work_tdr;
  536. struct list_head pending_list;
  537. spinlock_t job_list_lock;
  538. int hang_limit;
  539. atomic_t *score;
  540. atomic_t _score;
  541. bool ready;
  542. bool free_guilty;
  543. bool pause_submit;
  544. bool own_submit_wq;
  545. struct device *dev;
  546. };
  547. /**
  548. * struct drm_sched_init_args - parameters for initializing a DRM GPU scheduler
  549. *
  550. * @ops: backend operations provided by the driver
  551. * @submit_wq: workqueue to use for submission. If NULL, an ordered wq is
  552. * allocated and used.
  553. * @num_rqs: Number of run-queues. This may be at most DRM_SCHED_PRIORITY_COUNT,
  554. * as there's usually one run-queue per priority, but may be less.
  555. * @credit_limit: the number of credits this scheduler can hold from all jobs
  556. * @hang_limit: number of times to allow a job to hang before dropping it.
  557. * This mechanism is DEPRECATED. Set it to 0.
  558. * @timeout: timeout value in jiffies for submitted jobs.
  559. * @timeout_wq: workqueue to use for timeout work. If NULL, the system_wq is used.
  560. * @score: score atomic shared with other schedulers. May be NULL.
  561. * @name: name (typically the driver's name). Used for debugging
  562. * @dev: associated device. Used for debugging
  563. */
  564. struct drm_sched_init_args {
  565. const struct drm_sched_backend_ops *ops;
  566. struct workqueue_struct *submit_wq;
  567. struct workqueue_struct *timeout_wq;
  568. u32 num_rqs;
  569. u32 credit_limit;
  570. unsigned int hang_limit;
  571. long timeout;
  572. atomic_t *score;
  573. const char *name;
  574. struct device *dev;
  575. };
  576. /* Scheduler operations */
  577. int drm_sched_init(struct drm_gpu_scheduler *sched,
  578. const struct drm_sched_init_args *args);
  579. void drm_sched_fini(struct drm_gpu_scheduler *sched);
  580. unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
  581. void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
  582. unsigned long remaining);
  583. void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
  584. bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
  585. void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
  586. void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
  587. void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);
  588. void drm_sched_start(struct drm_gpu_scheduler *sched, int errno);
  589. void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
  590. void drm_sched_fault(struct drm_gpu_scheduler *sched);
  591. bool drm_sched_is_stopped(struct drm_gpu_scheduler *sched);
  592. struct drm_gpu_scheduler *
  593. drm_sched_pick_best(struct drm_gpu_scheduler **sched_list,
  594. unsigned int num_sched_list);
  595. /* Jobs */
  596. int drm_sched_job_init(struct drm_sched_job *job,
  597. struct drm_sched_entity *entity,
  598. u32 credits, void *owner,
  599. u64 drm_client_id);
  600. void drm_sched_job_arm(struct drm_sched_job *job);
  601. void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
  602. int drm_sched_job_add_dependency(struct drm_sched_job *job,
  603. struct dma_fence *fence);
  604. int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
  605. struct drm_file *file,
  606. u32 handle,
  607. u32 point);
  608. int drm_sched_job_add_resv_dependencies(struct drm_sched_job *job,
  609. struct dma_resv *resv,
  610. enum dma_resv_usage usage);
  611. int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job,
  612. struct drm_gem_object *obj,
  613. bool write);
  614. bool drm_sched_job_has_dependency(struct drm_sched_job *job,
  615. struct dma_fence *fence);
  616. void drm_sched_job_cleanup(struct drm_sched_job *job);
  617. void drm_sched_increase_karma(struct drm_sched_job *bad);
  618. bool drm_sched_job_is_signaled(struct drm_sched_job *job);
  619. static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job,
  620. int threshold)
  621. {
  622. return s_job && atomic_inc_return(&s_job->karma) > threshold;
  623. }
  624. /* Entities */
  625. int drm_sched_entity_init(struct drm_sched_entity *entity,
  626. enum drm_sched_priority priority,
  627. struct drm_gpu_scheduler **sched_list,
  628. unsigned int num_sched_list,
  629. atomic_t *guilty);
  630. long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
  631. void drm_sched_entity_fini(struct drm_sched_entity *entity);
  632. void drm_sched_entity_destroy(struct drm_sched_entity *entity);
  633. void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
  634. enum drm_sched_priority priority);
  635. int drm_sched_entity_error(struct drm_sched_entity *entity);
  636. void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
  637. struct drm_gpu_scheduler **sched_list,
  638. unsigned int num_sched_list);
  639. /**
  640. * struct drm_sched_pending_job_iter - DRM scheduler pending job iterator state
  641. * @sched: DRM scheduler associated with pending job iterator
  642. */
  643. struct drm_sched_pending_job_iter {
  644. struct drm_gpu_scheduler *sched;
  645. };
  646. /* Drivers should never call this directly */
  647. static inline struct drm_sched_pending_job_iter
  648. __drm_sched_pending_job_iter_begin(struct drm_gpu_scheduler *sched)
  649. {
  650. struct drm_sched_pending_job_iter iter = {
  651. .sched = sched,
  652. };
  653. WARN_ON(!drm_sched_is_stopped(sched));
  654. return iter;
  655. }
  656. /* Drivers should never call this directly */
  657. static inline void
  658. __drm_sched_pending_job_iter_end(const struct drm_sched_pending_job_iter iter)
  659. {
  660. WARN_ON(!drm_sched_is_stopped(iter.sched));
  661. }
  662. DEFINE_CLASS(drm_sched_pending_job_iter, struct drm_sched_pending_job_iter,
  663. __drm_sched_pending_job_iter_end(_T),
  664. __drm_sched_pending_job_iter_begin(__sched),
  665. struct drm_gpu_scheduler *__sched);
  666. static inline void *
  667. class_drm_sched_pending_job_iter_lock_ptr(class_drm_sched_pending_job_iter_t *_T)
  668. { return _T; }
  669. #define class_drm_sched_pending_job_iter_is_conditional false
  670. /**
  671. * drm_sched_for_each_pending_job() - Iterator for each pending job in scheduler
  672. * @__job: Current pending job being iterated over
  673. * @__sched: DRM scheduler to iterate over pending jobs
  674. * @__entity: DRM scheduler entity to filter jobs, NULL indicates no filter
  675. *
  676. * Iterator for each pending job in scheduler, filtering on an entity, and
  677. * enforcing scheduler is fully stopped
  678. */
  679. #define drm_sched_for_each_pending_job(__job, __sched, __entity) \
  680. scoped_guard(drm_sched_pending_job_iter, (__sched)) \
  681. list_for_each_entry((__job), &(__sched)->pending_list, list) \
  682. for_each_if(!(__entity) || (__job)->entity == (__entity))
  683. #endif