1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2 /*
3 *
4 * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved.
5 *
6 * This program is free software and is provided to you under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation, and any use by you of this program is subject to the terms
9 * of such GNU license.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can access it online at
18 * http://www.gnu.org/licenses/gpl-2.0.html.
19 *
20 */
21
22 /*
23 * Job Scheduler Interface.
24 * These interfaces are Internal to KBase.
25 */
26
27 #ifndef _KBASE_JM_JS_H_
28 #define _KBASE_JM_JS_H_
29
30 #include "mali_kbase_js_ctx_attr.h"
31
32 #define JS_MAX_RUNNING_JOBS 8
33
34 /**
35 * kbasep_js_devdata_init - Initialize the Job Scheduler
36 * @kbdev: The kbase_device to operate on
37 *
38 * The struct kbasep_js_device_data sub-structure of kbdev must be zero
39 * initialized before passing to the kbasep_js_devdata_init() function. This is
40 * to give efficient error path code.
41 *
42 * Return: 0 on success, error code otherwise.
43 */
44 int kbasep_js_devdata_init(struct kbase_device * const kbdev);
45
46 /**
47 * kbasep_js_devdata_halt - Halt the Job Scheduler.
48 * @kbdev: The kbase_device to operate on
49 *
50 * It is safe to call this on kbdev even if it the kbasep_js_device_data
51 * sub-structure was never initialized/failed initialization, to give efficient
52 * error-path code.
53 *
54 * For this to work, the struct kbasep_js_device_data sub-structure of kbdev
55 * must be zero initialized before passing to the kbasep_js_devdata_init()
56 * function. This is to give efficient error path code.
57 *
58 * It is a programming error to call this whilst there are still kbase_context
59 * structures registered with this scheduler.
60 *
61 */
62 void kbasep_js_devdata_halt(struct kbase_device *kbdev);
63
64 /**
65 * kbasep_js_devdata_term - Terminate the Job Scheduler
66 * @kbdev: The kbase_device to operate on
67 *
68 * It is safe to call this on kbdev even if it the kbasep_js_device_data
69 * sub-structure was never initialized/failed initialization, to give efficient
70 * error-path code.
71 *
72 * For this to work, the struct kbasep_js_device_data sub-structure of kbdev
73 * must be zero initialized before passing to the kbasep_js_devdata_init()
74 * function. This is to give efficient error path code.
75 *
76 * It is a programming error to call this whilst there are still kbase_context
77 * structures registered with this scheduler.
78 */
79 void kbasep_js_devdata_term(struct kbase_device *kbdev);
80
81 /**
82 * kbasep_js_kctx_init - Initialize the Scheduling Component of a
83 * struct kbase_context on the Job Scheduler.
84 * @kctx: The kbase_context to operate on
85 *
86 * This effectively registers a struct kbase_context with a Job Scheduler.
87 *
88 * It does not register any jobs owned by the struct kbase_context with
89 * the scheduler. Those must be separately registered by kbasep_js_add_job().
90 *
91 * The struct kbase_context must be zero initialized before passing to the
92 * kbase_js_init() function. This is to give efficient error path code.
93 *
94 * Return: 0 on success, error code otherwise.
95 */
96 int kbasep_js_kctx_init(struct kbase_context *const kctx);
97
98 /**
99 * kbasep_js_kctx_term - Terminate the Scheduling Component of a
100 * struct kbase_context on the Job Scheduler
101 * @kctx: The kbase_context to operate on
102 *
103 * This effectively de-registers a struct kbase_context from its Job Scheduler
104 *
105 * It is safe to call this on a struct kbase_context that has never had or
106 * failed initialization of its jctx.sched_info member, to give efficient
107 * error-path code.
108 *
109 * For this to work, the struct kbase_context must be zero intitialized before
110 * passing to the kbase_js_init() function.
111 *
112 * It is a Programming Error to call this whilst there are still jobs
113 * registered with this context.
114 */
115 void kbasep_js_kctx_term(struct kbase_context *kctx);
116
117 /* kbase_jsctx_slot_prio_blocked_set - Set a context as being blocked for a job
118 * slot at and below a given priority level
119 * @kctx: The kbase_context
120 * @js: The job slot
121 * @sched_prio: The priority levels that the context is blocked at for @js (all
122 * priority levels at this level and below will be blocked)
123 *
124 * To preserve ordering and dependencies of atoms on soft-stopping (both within
125 * an between priority levels), a context must be marked as blocked for that
126 * atom's job slot, for all priority levels at or below the atom's priority.
127 *
128 * This must only be called due to an atom that was pulled from the context,
129 * otherwise there will be no way of unblocking the context when the atom is
130 * completed/unpulled.
131 *
132 * Atoms of higher priority might still be able to be pulled from the context
133 * on @js. This helps with starting a high priority atom as soon as possible.
134 */
kbase_jsctx_slot_prio_blocked_set(struct kbase_context * kctx,unsigned int js,int sched_prio)135 static inline void kbase_jsctx_slot_prio_blocked_set(struct kbase_context *kctx, unsigned int js,
136 int sched_prio)
137 {
138 struct kbase_jsctx_slot_tracking *slot_tracking =
139 &kctx->slot_tracking[js];
140
141 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
142 WARN(!slot_tracking->atoms_pulled_pri[sched_prio],
143 "When marking slot %u as blocked for priority %d on a kctx, no atoms were pulled - the slot cannot become unblocked",
144 js, sched_prio);
145
146 slot_tracking->blocked |= ((kbase_js_prio_bitmap_t)1) << sched_prio;
147 KBASE_KTRACE_ADD_JM_SLOT_INFO(kctx->kbdev, JS_SLOT_PRIO_BLOCKED, kctx,
148 NULL, 0, js, (unsigned int)sched_prio);
149 }
150
151 /* kbase_jsctx_atoms_pulled - Return number of atoms pulled on a context
152 * @kctx: The kbase_context
153 *
154 * Having atoms pulled indicates the context is not idle.
155 *
156 * Return: the number of atoms pulled on @kctx
157 */
kbase_jsctx_atoms_pulled(struct kbase_context * kctx)158 static inline int kbase_jsctx_atoms_pulled(struct kbase_context *kctx)
159 {
160 return atomic_read(&kctx->atoms_pulled_all_slots);
161 }
162
163 /**
164 * kbasep_js_add_job - Add a job chain to the Job Scheduler,
165 * and take necessary actions to
166 * schedule the context/run the job.
167 * @kctx: The kbase_context to operate on
168 * @atom: Atom to add
169 *
170 * This atomically does the following:
171 * * Update the numbers of jobs information
172 * * Add the job to the run pool if necessary (part of init_job)
173 *
174 * Once this is done, then an appropriate action is taken:
175 * * If the ctx is scheduled, it attempts to start the next job (which might be
176 * this added job)
177 * * Otherwise, and if this is the first job on the context, it enqueues it on
178 * the Policy Queue
179 *
180 * The Policy's Queue can be updated by this in the following ways:
181 * * In the above case that this is the first job on the context
182 * * If the context is high priority and the context is not scheduled, then it
183 * could cause the Policy to schedule out a low-priority context, allowing
184 * this context to be scheduled in.
185 *
186 * If the context is already scheduled on the RunPool, then adding a job to it
187 * is guaranteed not to update the Policy Queue. And so, the caller is
188 * guaranteed to not need to try scheduling a context from the Run Pool - it
189 * can safely assert that the result is false.
190 *
191 * It is a programming error to have more than U32_MAX jobs in flight at a time.
192 *
193 * The following locking conditions are made on the caller:
194 * * it must not hold kbasep_js_kctx_info::ctx::jsctx_mutex.
195 * * it must not hold hwaccess_lock (as this will be obtained internally)
196 * * it must not hold kbasep_js_device_data::runpool_mutex (as this will be
197 * obtained internally)
198 * * it must not hold kbasep_jd_device_data::queue_mutex (again, it's used
199 * internally).
200 *
201 * Return: true indicates that the Policy Queue was updated, and so the
202 * caller will need to try scheduling a context onto the Run Pool,
203 * false indicates that no updates were made to the Policy Queue,
204 * so no further action is required from the caller. This is always returned
205 * when the context is currently scheduled.
206 */
207 bool kbasep_js_add_job(struct kbase_context *kctx, struct kbase_jd_atom *atom);
208
209 /**
210 * kbasep_js_remove_job - Remove a job chain from the Job Scheduler,
211 * except for its 'retained state'.
212 * @kbdev: The kbase_device to operate on
213 * @kctx: The kbase_context to operate on
214 * @atom: Atom to remove
215 *
216 * Completely removing a job requires several calls:
217 * * kbasep_js_copy_atom_retained_state(), to capture the 'retained state' of
218 * the atom
219 * * kbasep_js_remove_job(), to partially remove the atom from the Job Scheduler
220 * * kbasep_js_runpool_release_ctx_and_katom_retained_state(), to release the
221 * remaining state held as part of the job having been run.
222 *
223 * In the common case of atoms completing normally, this set of actions is more
224 * optimal for spinlock purposes than having kbasep_js_remove_job() handle all
225 * of the actions.
226 *
227 * In the case of canceling atoms, it is easier to call
228 * kbasep_js_remove_cancelled_job(), which handles all the necessary actions.
229 *
230 * It is a programming error to call this when:
231 * * a atom is not a job belonging to kctx.
232 * * a atom has already been removed from the Job Scheduler.
233 * * a atom is still in the runpool
234 *
235 * Do not use this for removing jobs being killed by kbase_jd_cancel() - use
236 * kbasep_js_remove_cancelled_job() instead.
237 *
238 * The following locking conditions are made on the caller:
239 * * it must hold kbasep_js_kctx_info::ctx::jsctx_mutex.
240 *
241 */
242 void kbasep_js_remove_job(struct kbase_device *kbdev,
243 struct kbase_context *kctx, struct kbase_jd_atom *atom);
244
245 /**
246 * kbasep_js_remove_cancelled_job - Completely remove a job chain from the
247 * Job Scheduler, in the case
248 * where the job chain was cancelled.
249 * @kbdev: The kbase_device to operate on
250 * @kctx: The kbase_context to operate on
251 * @katom: Atom to remove
252 *
253 * This is a variant of kbasep_js_remove_job() that takes care of removing all
254 * of the retained state too. This is generally useful for cancelled atoms,
255 * which need not be handled in an optimal way.
256 *
257 * It is a programming error to call this when:
258 * * a atom is not a job belonging to kctx.
259 * * a atom has already been removed from the Job Scheduler.
260 * * a atom is still in the runpool:
261 * * it is not being killed with kbasep_jd_cancel()
262 *
263 * The following locking conditions are made on the caller:
264 * * it must hold kbasep_js_kctx_info::ctx::jsctx_mutex.
265 * * it must not hold the hwaccess_lock, (as this will be obtained
266 * internally)
267 * * it must not hold kbasep_js_device_data::runpool_mutex (as this could be
268 * obtained internally)
269 *
270 * Return: true indicates that ctx attributes have changed and the caller
271 * should call kbase_js_sched_all() to try to run more jobs and
272 * false otherwise.
273 */
274 bool kbasep_js_remove_cancelled_job(struct kbase_device *kbdev,
275 struct kbase_context *kctx,
276 struct kbase_jd_atom *katom);
277
278 /**
279 * kbasep_js_runpool_requeue_or_kill_ctx - Handling the requeuing/killing of a
280 * context that was evicted from the
281 * policy queue or runpool.
282 * @kbdev: The kbase_device to operate on
283 * @kctx: The kbase_context to operate on
284 * @has_pm_ref: tells whether to release Power Manager active reference
285 *
286 * This should be used whenever handing off a context that has been evicted
287 * from the policy queue or the runpool:
288 * * If the context is not dying and has jobs, it gets re-added to the policy
289 * queue
290 * * Otherwise, it is not added
291 *
292 * In addition, if the context is dying the jobs are killed asynchronously.
293 *
294 * In all cases, the Power Manager active reference is released
295 * (kbase_pm_context_idle()) whenever the has_pm_ref parameter is true.
296 * has_pm_ref must be set to false whenever the context was not previously in
297 * the runpool and does not hold a Power Manager active refcount. Note that
298 * contexts in a rollback of kbasep_js_try_schedule_head_ctx() might have an
299 * active refcount even though they weren't in the runpool.
300 *
301 * The following locking conditions are made on the caller:
302 * * it must hold kbasep_js_kctx_info::ctx::jsctx_mutex.
303 * * it must not hold kbasep_jd_device_data::queue_mutex (as this will be
304 * obtained internally)
305 */
306 void kbasep_js_runpool_requeue_or_kill_ctx(struct kbase_device *kbdev,
307 struct kbase_context *kctx, bool has_pm_ref);
308
309 /**
310 * kbasep_js_runpool_release_ctx - Release a refcount of a context being busy,
311 * allowing it to be scheduled out.
312 * @kbdev: The kbase_device to operate on
313 * @kctx: The kbase_context to operate on
314 *
315 * When the refcount reaches zero and the context might be scheduled out
316 * (depending on whether the Scheduling Policy has deemed it so, or if it has
317 * run out of jobs).
318 *
319 * If the context does get scheduled out, then The following actions will be
320 * taken as part of deschduling a context:
321 * For the context being descheduled:
322 * * If the context is in the processing of dying (all the jobs are being
323 * removed from it), then descheduling also kills off any jobs remaining in the
324 * context.
325 * * If the context is not dying, and any jobs remain after descheduling the
326 * context then it is re-enqueued to the Policy's Queue.
327 * * Otherwise, the context is still known to the scheduler, but remains absent
328 * from the Policy Queue until a job is next added to it.
329 * * In all descheduling cases, the Power Manager active reference (obtained
330 * during kbasep_js_try_schedule_head_ctx()) is released
331 * (kbase_pm_context_idle()).
332 *
333 * Whilst the context is being descheduled, this also handles actions that
334 * cause more atoms to be run:
335 * * Attempt submitting atoms when the Context Attributes on the Runpool have
336 * changed. This is because the context being scheduled out could mean that
337 * there are more opportunities to run atoms.
338 * * Attempt submitting to a slot that was previously blocked due to affinity
339 * restrictions. This is usually only necessary when releasing a context
340 * happens as part of completing a previous job, but is harmless nonetheless.
341 * * Attempt scheduling in a new context (if one is available), and if
342 * necessary, running a job from that new context.
343 *
344 * Unlike retaining a context in the runpool, this function cannot be called
345 * from IRQ context.
346 *
347 * It is a programming error to call this on a kctx that is not currently
348 * scheduled, or that already has a zero refcount.
349 *
350 * The following locking conditions are made on the caller:
351 * * it must not hold the hwaccess_lock, because it will be used internally.
352 * * it must not hold kbasep_js_kctx_info::ctx::jsctx_mutex.
353 * * it must not hold kbasep_js_device_data::runpool_mutex (as this will be
354 * obtained internally)
355 * * it must not hold the kbase_device::mmu_hw_mutex (as this will be
356 * obtained internally)
357 * * it must not hold kbasep_jd_device_data::queue_mutex (as this will be
358 * obtained internally)
359 *
360 */
361 void kbasep_js_runpool_release_ctx(struct kbase_device *kbdev,
362 struct kbase_context *kctx);
363
364 /**
365 * kbasep_js_runpool_release_ctx_and_katom_retained_state - Variant of
366 * kbasep_js_runpool_release_ctx() that handles additional
367 * actions from completing an atom.
368 *
369 * @kbdev: KBase device
370 * @kctx: KBase context
371 * @katom_retained_state: Retained state from the atom
372 *
373 * This is usually called as part of completing an atom and releasing the
374 * refcount on the context held by the atom.
375 *
376 * Therefore, the extra actions carried out are part of handling actions queued
377 * on a completed atom, namely:
378 * * Releasing the atom's context attributes
379 * * Retrying the submission on a particular slot, because we couldn't submit
380 * on that slot from an IRQ handler.
381 *
382 * The locking conditions of this function are the same as those for
383 * kbasep_js_runpool_release_ctx()
384 */
385 void kbasep_js_runpool_release_ctx_and_katom_retained_state(
386 struct kbase_device *kbdev,
387 struct kbase_context *kctx,
388 struct kbasep_js_atom_retained_state *katom_retained_state);
389
390 /**
391 * kbasep_js_runpool_release_ctx_nolock - Variant of kbase_js_runpool_release_ctx()
392 * without locks
393 * @kbdev: KBase device
394 * @kctx: KBase context
395 *
396 * Variant of kbase_js_runpool_release_ctx() that assumes that
397 * kbasep_js_device_data::runpool_mutex and
398 * kbasep_js_kctx_info::ctx::jsctx_mutex are held by the caller, and does not
399 * attempt to schedule new contexts.
400 */
401 void kbasep_js_runpool_release_ctx_nolock(struct kbase_device *kbdev,
402 struct kbase_context *kctx);
403
404 /**
405 * kbasep_js_schedule_privileged_ctx - Schedule in a privileged context
406 *
407 * @kbdev: KBase device
408 * @kctx: KBase context
409 *
410 * This schedules a context in regardless of the context priority.
411 * If the runpool is full, a context will be forced out of the runpool and the
412 * function will wait for the new context to be scheduled in.
413 * The context will be kept scheduled in (and the corresponding address space
414 * reserved) until kbasep_js_release_privileged_ctx is called).
415 *
416 * The following locking conditions are made on the caller:
417 * * it must not hold the hwaccess_lock, because it will be used internally.
418 * * it must not hold kbasep_js_device_data::runpool_mutex (as this will be
419 * obtained internally)
420 * * it must not hold the kbase_device::mmu_hw_mutex (as this will be
421 * obtained internally)
422 * * it must not hold kbasep_jd_device_data::queue_mutex (again, it's used
423 * internally).
424 * * it must not hold kbasep_js_kctx_info::ctx::jsctx_mutex, because it will
425 * be used internally.
426 *
427 */
428 void kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev,
429 struct kbase_context *kctx);
430
431 /**
432 * kbasep_js_release_privileged_ctx - Release a privileged context,
433 * allowing it to be scheduled out.
434 * @kbdev: KBase device
435 * @kctx: KBase context
436 *
437 * See kbasep_js_runpool_release_ctx for potential side effects.
438 *
439 * The following locking conditions are made on the caller:
440 * * it must not hold the hwaccess_lock, because it will be used internally.
441 * * it must not hold kbasep_js_kctx_info::ctx::jsctx_mutex.
442 * * it must not hold kbasep_js_device_data::runpool_mutex (as this will be
443 * obtained internally)
444 * * it must not hold the kbase_device::mmu_hw_mutex (as this will be
445 * obtained internally)
446 *
447 */
448 void kbasep_js_release_privileged_ctx(struct kbase_device *kbdev,
449 struct kbase_context *kctx);
450
451 /**
452 * kbase_js_try_run_jobs - Try to submit the next job on each slot
453 * @kbdev: KBase device
454 *
455 * The following locks may be used:
456 * * kbasep_js_device_data::runpool_mutex
457 * * hwaccess_lock
458 */
459 void kbase_js_try_run_jobs(struct kbase_device *kbdev);
460
461 /**
462 * kbasep_js_suspend - Suspend the job scheduler during a Power Management
463 * Suspend event.
464 * @kbdev: KBase device
465 *
466 * Causes all contexts to be removed from the runpool, and prevents any
467 * contexts from (re)entering the runpool.
468 *
469 * This does not handle suspending the one privileged context: the caller must
470 * instead do this by suspending the GPU HW Counter Instrumentation.
471 *
472 * This will eventually cause all Power Management active references held by
473 * contexts on the runpool to be released, without running any more atoms.
474 *
475 * The caller must then wait for all Power Management active refcount to become
476 * zero before completing the suspend.
477 *
478 * The emptying mechanism may take some time to complete, since it can wait for
479 * jobs to complete naturally instead of forcing them to end quickly. However,
480 * this is bounded by the Job Scheduler's Job Timeouts. Hence, this
481 * function is guaranteed to complete in a finite time.
482 */
483 void kbasep_js_suspend(struct kbase_device *kbdev);
484
485 /**
486 * kbasep_js_resume - Resume the Job Scheduler after a Power Management
487 * Resume event.
488 * @kbdev: KBase device
489 *
490 * This restores the actions from kbasep_js_suspend():
491 * * Schedules contexts back into the runpool
492 * * Resumes running atoms on the GPU
493 */
494 void kbasep_js_resume(struct kbase_device *kbdev);
495
496 /**
497 * kbase_js_dep_resolved_submit - Submit an atom to the job scheduler.
498 *
499 * @kctx: Context pointer
500 * @katom: Pointer to the atom to submit
501 *
502 * The atom is enqueued on the context's ringbuffer. The caller must have
503 * ensured that all dependencies can be represented in the ringbuffer.
504 *
505 * Caller must hold jctx->lock
506 *
507 * Return: true if the context requires to be enqueued, otherwise false.
508 */
509 bool kbase_js_dep_resolved_submit(struct kbase_context *kctx,
510 struct kbase_jd_atom *katom);
511
512 /**
513 * kbase_js_pull - Pull an atom from a context in the job scheduler for
514 * execution.
515 *
516 * @kctx: Context to pull from
517 * @js: Job slot to pull from
518 *
519 * The atom will not be removed from the ringbuffer at this stage.
520 *
521 * The HW access lock must be held when calling this function.
522 *
523 * Return: a pointer to an atom, or NULL if there are no atoms for this
524 * slot that can be currently run.
525 */
526 struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, unsigned int js);
527
528 /**
529 * kbase_js_unpull - Return an atom to the job scheduler ringbuffer.
530 *
531 * @kctx: Context pointer
532 * @katom: Pointer to the atom to unpull
533 *
534 * An atom is 'unpulled' if execution is stopped but intended to be returned to
535 * later. The most common reason for this is that the atom has been
536 * soft-stopped. Another reason is if an end-of-renderpass atom completed
537 * but will need to be run again as part of the same renderpass.
538 *
539 * Note that if multiple atoms are to be 'unpulled', they must be returned in
540 * the reverse order to which they were originally pulled. It is a programming
541 * error to return atoms in any other order.
542 *
543 * The HW access lock must be held when calling this function.
544 *
545 */
546 void kbase_js_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom);
547
548 /**
549 * kbase_js_complete_atom_wq - Complete an atom from jd_done_worker(),
550 * removing it from the job
551 * scheduler ringbuffer.
552 * @kctx: Context pointer
553 * @katom: Pointer to the atom to complete
554 *
555 * If the atom failed then all dependee atoms marked for failure propagation
556 * will also fail.
557 *
558 * Return: true if the context is now idle (no jobs pulled) false otherwise.
559 */
560 bool kbase_js_complete_atom_wq(struct kbase_context *kctx,
561 struct kbase_jd_atom *katom);
562
563 /**
564 * kbase_js_complete_atom - Complete an atom.
565 *
566 * @katom: Pointer to the atom to complete
567 * @end_timestamp: The time that the atom completed (may be NULL)
568 *
569 * Most of the work required to complete an atom will be performed by
570 * jd_done_worker().
571 *
572 * The HW access lock must be held when calling this function.
573 *
574 * Return: a atom that has now been unblocked and can now be run, or NULL
575 * if none
576 */
577 struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom,
578 ktime_t *end_timestamp);
579
580 /**
581 * kbase_js_atom_blocked_on_x_dep - Decide whether to ignore a cross-slot
582 * dependency
583 * @katom: Pointer to an atom in the slot ringbuffer
584 *
585 * A cross-slot dependency is ignored if necessary to unblock incremental
586 * rendering. If the atom at the start of a renderpass used too much memory
587 * and was soft-stopped then the atom at the end of a renderpass is submitted
588 * to hardware regardless of its dependency on the start-of-renderpass atom.
589 * This can happen multiple times for the same pair of atoms.
590 *
591 * Return: true to block the atom or false to allow it to be submitted to
592 * hardware.
593 */
594 bool kbase_js_atom_blocked_on_x_dep(struct kbase_jd_atom *katom);
595
596 /**
597 * kbase_js_sched - Submit atoms from all available contexts.
598 *
599 * @kbdev: Device pointer
600 * @js_mask: Mask of job slots to submit to
601 *
602 * This will attempt to submit as many jobs as possible to the provided job
603 * slots. It will exit when either all job slots are full, or all contexts have
604 * been used.
605 *
606 */
607 void kbase_js_sched(struct kbase_device *kbdev, unsigned int js_mask);
608
609 /**
610 * kbase_js_zap_context - Attempt to deschedule a context that is being
611 * destroyed
612 * @kctx: Context pointer
613 *
614 * This will attempt to remove a context from any internal job scheduler queues
615 * and perform any other actions to ensure a context will not be submitted
616 * from.
617 *
618 * If the context is currently scheduled, then the caller must wait for all
619 * pending jobs to complete before taking any further action.
620 */
621 void kbase_js_zap_context(struct kbase_context *kctx);
622
623 /**
624 * kbase_js_is_atom_valid - Validate an atom
625 *
626 * @kbdev: Device pointer
627 * @katom: Atom to validate
628 *
629 * This will determine whether the atom can be scheduled onto the GPU. Atoms
630 * with invalid combinations of core requirements will be rejected.
631 *
632 * Return: true if atom is valid false otherwise.
633 */
634 bool kbase_js_is_atom_valid(struct kbase_device *kbdev,
635 struct kbase_jd_atom *katom);
636
637 /**
638 * kbase_js_set_timeouts - update all JS timeouts with user specified data
639 *
640 * @kbdev: Device pointer
641 *
642 * Timeouts are specified through the 'js_timeouts' sysfs file. If a timeout is
643 * set to a positive number then that becomes the new value used, if a timeout
644 * is negative then the default is set.
645 */
646 void kbase_js_set_timeouts(struct kbase_device *kbdev);
647
648 /**
649 * kbase_js_set_ctx_priority - set the context priority
650 *
651 * @kctx: Context pointer
652 * @new_priority: New priority value for the Context
653 *
654 * The context priority is set to a new value and it is moved to the
655 * pullable/unpullable list as per the new priority.
656 */
657 void kbase_js_set_ctx_priority(struct kbase_context *kctx, int new_priority);
658
659 /**
660 * kbase_js_update_ctx_priority - update the context priority
661 *
662 * @kctx: Context pointer
663 *
664 * The context priority gets updated as per the priority of atoms currently in
665 * use for that context, but only if system priority mode for context scheduling
666 * is being used.
667 */
668 void kbase_js_update_ctx_priority(struct kbase_context *kctx);
669
670 /*
671 * Helpers follow
672 */
673
674 /**
675 * kbasep_js_is_submit_allowed - Check that a context is allowed to submit
676 * jobs on this policy
677 * @js_devdata: KBase Job Scheduler Device Data
678 * @kctx: KBase context
679 *
680 * The purpose of this abstraction is to hide the underlying data size,
681 * and wrap up the long repeated line of code.
682 *
683 * As with any bool, never test the return value with true.
684 *
685 * The caller must hold hwaccess_lock.
686 *
687 * Return: true if the context is allowed to submit jobs, false otherwise.
688 */
kbasep_js_is_submit_allowed(struct kbasep_js_device_data * js_devdata,struct kbase_context * kctx)689 static inline bool kbasep_js_is_submit_allowed(
690 struct kbasep_js_device_data *js_devdata,
691 struct kbase_context *kctx)
692 {
693 u16 test_bit;
694 bool is_allowed;
695
696 /* Ensure context really is scheduled in */
697 if (WARN((kctx->as_nr == KBASEP_AS_NR_INVALID) || !kbase_ctx_flag(kctx, KCTX_SCHEDULED),
698 "%s: kctx %pK has assigned AS %d and context flag %d\n", __func__, (void *)kctx,
699 kctx->as_nr, atomic_read(&kctx->flags)))
700 return false;
701
702 test_bit = (u16) (1u << kctx->as_nr);
703
704 is_allowed = (bool) (js_devdata->runpool_irq.submit_allowed & test_bit);
705 dev_dbg(kctx->kbdev->dev, "JS: submit %s allowed on %pK (as=%d)",
706 is_allowed ? "is" : "isn't", (void *)kctx, kctx->as_nr);
707 return is_allowed;
708 }
709
710 /**
711 * kbasep_js_set_submit_allowed - Allow a context to submit jobs on this policy
712 * @js_devdata: KBase Job Scheduler Device Data
713 * @kctx: KBase context
714 *
715 * The purpose of this abstraction is to hide the underlying data size,
716 * and wrap up the long repeated line of code.
717 *
718 * The caller must hold hwaccess_lock.
719 */
kbasep_js_set_submit_allowed(struct kbasep_js_device_data * js_devdata,struct kbase_context * kctx)720 static inline void kbasep_js_set_submit_allowed(
721 struct kbasep_js_device_data *js_devdata,
722 struct kbase_context *kctx)
723 {
724 u16 set_bit;
725
726 /* Ensure context really is scheduled in */
727 if (WARN((kctx->as_nr == KBASEP_AS_NR_INVALID) || !kbase_ctx_flag(kctx, KCTX_SCHEDULED),
728 "%s: kctx %pK has assigned AS %d and context flag %d\n", __func__, (void *)kctx,
729 kctx->as_nr, atomic_read(&kctx->flags)))
730 return;
731
732 set_bit = (u16) (1u << kctx->as_nr);
733
734 dev_dbg(kctx->kbdev->dev, "JS: Setting Submit Allowed on %pK (as=%d)",
735 kctx, kctx->as_nr);
736
737 js_devdata->runpool_irq.submit_allowed |= set_bit;
738 }
739
740 /**
741 * kbasep_js_clear_submit_allowed - Prevent a context from submitting more
742 * jobs on this policy
743 * @js_devdata: KBase Job Scheduler Device Data
744 * @kctx: KBase context
745 *
746 * The purpose of this abstraction is to hide the underlying data size,
747 * and wrap up the long repeated line of code.
748 *
749 * The caller must hold hwaccess_lock.
750 */
kbasep_js_clear_submit_allowed(struct kbasep_js_device_data * js_devdata,struct kbase_context * kctx)751 static inline void kbasep_js_clear_submit_allowed(
752 struct kbasep_js_device_data *js_devdata,
753 struct kbase_context *kctx)
754 {
755 u16 clear_bit;
756 u16 clear_mask;
757
758 /* Ensure context really is scheduled in */
759 if (WARN((kctx->as_nr == KBASEP_AS_NR_INVALID) || !kbase_ctx_flag(kctx, KCTX_SCHEDULED),
760 "%s: kctx %pK has assigned AS %d and context flag %d\n", __func__, (void *)kctx,
761 kctx->as_nr, atomic_read(&kctx->flags)))
762 return;
763
764 clear_bit = (u16) (1u << kctx->as_nr);
765 clear_mask = ~clear_bit;
766
767 dev_dbg(kctx->kbdev->dev, "JS: Clearing Submit Allowed on %pK (as=%d)",
768 kctx, kctx->as_nr);
769
770 js_devdata->runpool_irq.submit_allowed &= clear_mask;
771 }
772
773 /**
774 * kbasep_js_atom_retained_state_init_invalid - Create an initial 'invalid'
775 * atom retained state
776 *
777 * @retained_state: pointer where to create and initialize the state
778 *
779 * Create an initial 'invalid' atom retained state, that requires no
780 * atom-related work to be done on releasing with
781 * kbasep_js_runpool_release_ctx_and_katom_retained_state()
782 */
kbasep_js_atom_retained_state_init_invalid(struct kbasep_js_atom_retained_state * retained_state)783 static inline void kbasep_js_atom_retained_state_init_invalid(
784 struct kbasep_js_atom_retained_state *retained_state)
785 {
786 retained_state->event_code = BASE_JD_EVENT_NOT_STARTED;
787 retained_state->core_req =
788 KBASEP_JS_ATOM_RETAINED_STATE_CORE_REQ_INVALID;
789 }
790
791 /**
792 * kbasep_js_atom_retained_state_copy() - Copy atom state
793 * @retained_state: where to copy
794 * @katom: where to copy from
795 *
796 * Copy atom state that can be made available after kbase_jd_done_nolock() is called
797 * on that atom.
798 */
kbasep_js_atom_retained_state_copy(struct kbasep_js_atom_retained_state * retained_state,const struct kbase_jd_atom * katom)799 static inline void kbasep_js_atom_retained_state_copy(
800 struct kbasep_js_atom_retained_state *retained_state,
801 const struct kbase_jd_atom *katom)
802 {
803 retained_state->event_code = katom->event_code;
804 retained_state->core_req = katom->core_req;
805 retained_state->sched_priority = katom->sched_priority;
806 retained_state->device_nr = katom->device_nr;
807 }
808
809 /**
810 * kbasep_js_has_atom_finished - Determine whether an atom has finished
811 * (given its retained state),
812 * and so should be given back to
813 * userspace/removed from the system.
814 *
815 * @katom_retained_state: the retained state of the atom to check
816 *
817 * Reasons for an atom not finishing include:
818 * * Being soft-stopped (and so, the atom should be resubmitted sometime later)
819 * * It is an end of renderpass atom that was run to consume the output of a
820 * start-of-renderpass atom that was soft-stopped because it used too much
821 * memory. In this case, it will have to be run again later.
822 *
823 * Return: false if the atom has not finished, true otherwise.
824 */
kbasep_js_has_atom_finished(const struct kbasep_js_atom_retained_state * katom_retained_state)825 static inline bool kbasep_js_has_atom_finished(
826 const struct kbasep_js_atom_retained_state *katom_retained_state)
827 {
828 return (bool) (katom_retained_state->event_code !=
829 BASE_JD_EVENT_STOPPED &&
830 katom_retained_state->event_code !=
831 BASE_JD_EVENT_REMOVED_FROM_NEXT &&
832 katom_retained_state->event_code !=
833 BASE_JD_EVENT_END_RP_DONE);
834 }
835
836 /**
837 * kbasep_js_atom_retained_state_is_valid - Determine whether a struct
838 * kbasep_js_atom_retained_state
839 * is valid
840 * @katom_retained_state: the atom's retained state to check
841 *
842 * An invalid struct kbasep_js_atom_retained_state is allowed, and indicates
843 * that the code should just ignore it.
844 *
845 * Return: false if the retained state is invalid, true otherwise.
846 */
kbasep_js_atom_retained_state_is_valid(const struct kbasep_js_atom_retained_state * katom_retained_state)847 static inline bool kbasep_js_atom_retained_state_is_valid(
848 const struct kbasep_js_atom_retained_state *katom_retained_state)
849 {
850 return (bool) (katom_retained_state->core_req !=
851 KBASEP_JS_ATOM_RETAINED_STATE_CORE_REQ_INVALID);
852 }
853
854 /**
855 * kbase_js_runpool_inc_context_count - Increment number of running contexts.
856 * @kbdev: KBase device
857 * @kctx: KBase context
858 *
859 * The following locking conditions are made on the caller:
860 * * The caller must hold the kbasep_js_kctx_info::ctx::jsctx_mutex.
861 * * The caller must hold the kbasep_js_device_data::runpool_mutex
862 */
kbase_js_runpool_inc_context_count(struct kbase_device * kbdev,struct kbase_context * kctx)863 static inline void kbase_js_runpool_inc_context_count(
864 struct kbase_device *kbdev,
865 struct kbase_context *kctx)
866 {
867 struct kbasep_js_device_data *js_devdata;
868 struct kbasep_js_kctx_info *js_kctx_info;
869
870 js_devdata = &kbdev->js_data;
871 js_kctx_info = &kctx->jctx.sched_info;
872
873 lockdep_assert_held(&js_kctx_info->ctx.jsctx_mutex);
874 lockdep_assert_held(&js_devdata->runpool_mutex);
875
876 /* Track total contexts */
877 WARN_ON_ONCE(js_devdata->nr_all_contexts_running >= JS_MAX_RUNNING_JOBS);
878 ++(js_devdata->nr_all_contexts_running);
879
880 if (!kbase_ctx_flag(kctx, KCTX_SUBMIT_DISABLED)) {
881 /* Track contexts that can submit jobs */
882 WARN_ON_ONCE(js_devdata->nr_user_contexts_running >= JS_MAX_RUNNING_JOBS);
883 ++(js_devdata->nr_user_contexts_running);
884 }
885 }
886
887 /**
888 * kbase_js_runpool_dec_context_count - decrement number of running contexts.
889 *
890 * @kbdev: KBase device
891 * @kctx: KBase context
892 * The following locking conditions are made on the caller:
893 * * The caller must hold the kbasep_js_kctx_info::ctx::jsctx_mutex.
894 * * The caller must hold the kbasep_js_device_data::runpool_mutex
895 */
kbase_js_runpool_dec_context_count(struct kbase_device * kbdev,struct kbase_context * kctx)896 static inline void kbase_js_runpool_dec_context_count(
897 struct kbase_device *kbdev,
898 struct kbase_context *kctx)
899 {
900 struct kbasep_js_device_data *js_devdata;
901 struct kbasep_js_kctx_info *js_kctx_info;
902
903 js_devdata = &kbdev->js_data;
904 js_kctx_info = &kctx->jctx.sched_info;
905
906 lockdep_assert_held(&js_kctx_info->ctx.jsctx_mutex);
907 lockdep_assert_held(&js_devdata->runpool_mutex);
908
909 /* Track total contexts */
910 --(js_devdata->nr_all_contexts_running);
911 WARN_ON_ONCE(js_devdata->nr_all_contexts_running < 0);
912
913 if (!kbase_ctx_flag(kctx, KCTX_SUBMIT_DISABLED)) {
914 /* Track contexts that can submit jobs */
915 --(js_devdata->nr_user_contexts_running);
916 WARN_ON_ONCE(js_devdata->nr_user_contexts_running < 0);
917 }
918 }
919
920 /**
921 * kbase_js_sched_all - Submit atoms from all available contexts to all
922 * job slots.
923 *
924 * @kbdev: Device pointer
925 *
926 * This will attempt to submit as many jobs as possible. It will exit when
927 * either all job slots are full, or all contexts have been used.
928 */
kbase_js_sched_all(struct kbase_device * kbdev)929 static inline void kbase_js_sched_all(struct kbase_device *kbdev)
930 {
931 kbase_js_sched(kbdev, (1 << kbdev->gpu_props.num_job_slots) - 1);
932 }
933
934 extern const int
935 kbasep_js_atom_priority_to_relative[BASE_JD_NR_PRIO_LEVELS];
936
937 extern const base_jd_prio
938 kbasep_js_relative_priority_to_atom[KBASE_JS_ATOM_SCHED_PRIO_COUNT];
939
940 /**
941 * kbasep_js_atom_prio_to_sched_prio - Convert atom priority (base_jd_prio)
942 * to relative ordering.
943 * @atom_prio: Priority ID to translate.
944 *
945 * Atom priority values for @ref base_jd_prio cannot be compared directly to
946 * find out which are higher or lower.
947 *
948 * This function will convert base_jd_prio values for successively lower
949 * priorities into a monotonically increasing sequence. That is, the lower the
950 * base_jd_prio priority, the higher the value produced by this function. This
951 * is in accordance with how the rest of the kernel treats priority.
952 *
953 * The mapping is 1:1 and the size of the valid input range is the same as the
954 * size of the valid output range, i.e.
955 * KBASE_JS_ATOM_SCHED_PRIO_COUNT == BASE_JD_NR_PRIO_LEVELS
956 *
957 * Note This must be kept in sync with BASE_JD_PRIO_<...> definitions
958 *
959 * Return: On success: a value in the inclusive range
960 * 0..KBASE_JS_ATOM_SCHED_PRIO_COUNT-1. On failure:
961 * KBASE_JS_ATOM_SCHED_PRIO_INVALID
962 */
kbasep_js_atom_prio_to_sched_prio(base_jd_prio atom_prio)963 static inline int kbasep_js_atom_prio_to_sched_prio(base_jd_prio atom_prio)
964 {
965 if (atom_prio >= BASE_JD_NR_PRIO_LEVELS)
966 return KBASE_JS_ATOM_SCHED_PRIO_INVALID;
967
968 return kbasep_js_atom_priority_to_relative[atom_prio];
969 }
970
971 /**
972 * kbasep_js_sched_prio_to_atom_prio - Convert relative scheduler priority
973 * to atom priority (base_jd_prio).
974 *
975 * @kbdev: Device pointer
976 * @sched_prio: Relative scheduler priority to translate.
977 *
978 * This function will convert relative scheduler priority back into base_jd_prio
979 * values. It takes values which priorities are monotonically increasing
980 * and converts them to the corresponding base_jd_prio values. If an invalid number is
981 * passed in (i.e. not within the expected range) an error code is returned instead.
982 *
983 * The mapping is 1:1 and the size of the valid input range is the same as the
984 * size of the valid output range, i.e.
985 * KBASE_JS_ATOM_SCHED_PRIO_COUNT == BASE_JD_NR_PRIO_LEVELS
986 *
987 * Return: On success: a value in the inclusive range
988 * 0..BASE_JD_NR_PRIO_LEVELS-1. On failure: BASE_JD_PRIO_INVALID.
989 */
kbasep_js_sched_prio_to_atom_prio(struct kbase_device * kbdev,int sched_prio)990 static inline base_jd_prio kbasep_js_sched_prio_to_atom_prio(struct kbase_device *kbdev,
991 int sched_prio)
992 {
993 if (likely(sched_prio >= 0 && sched_prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT))
994 return kbasep_js_relative_priority_to_atom[sched_prio];
995 /* Invalid priority value if reached here */
996 dev_warn(kbdev->dev, "Unknown JS scheduling priority %d", sched_prio);
997 return BASE_JD_PRIO_INVALID;
998 }
999
1000 /**
1001 * kbase_js_priority_check - Check the priority requested
1002 *
1003 * @kbdev: Device pointer
1004 * @priority: Requested priority
1005 *
1006 * This will determine whether the requested priority can be satisfied.
1007 *
1008 * Return: The same or lower priority than requested.
1009 */
1010 base_jd_prio kbase_js_priority_check(struct kbase_device *kbdev, base_jd_prio priority);
1011
1012 /**
1013 * kbase_js_atom_runs_before - determine if atoms for the same slot have an
1014 * ordering relation
1015 * @kbdev: kbase device
1016 * @katom_a: the first atom
1017 * @katom_b: the second atom.
1018 * @order_flags: combination of KBASE_ATOM_ORDERING_FLAG_<...> for the ordering
1019 * relation
1020 *
1021 * This is for making consistent decisions about the ordering of atoms when we
1022 * need to do pre-emption on a slot, which includes stopping existing atoms
1023 * when a new atom is ready to run, and also which other atoms to remove from
1024 * the slot when the atom in JSn_HEAD is being pre-empted.
1025 *
1026 * This only handles @katom_a and @katom_b being for the same job slot, as
1027 * pre-emption only operates within a slot.
1028 *
1029 * Note: there is currently no use-case for this as a sorting comparison
1030 * functions, hence only a boolean returned instead of int -1, 0, +1 return. If
1031 * required in future, a modification to do so would be better than calling
1032 * twice with katom_a and katom_b swapped.
1033 *
1034 * Return:
1035 * true if @katom_a should run before @katom_b, false otherwise.
1036 * A false return value does not distinguish between "no ordering relation" and
1037 * "@katom_a should run after @katom_b".
1038 */
1039 bool kbase_js_atom_runs_before(struct kbase_device *kbdev,
1040 const struct kbase_jd_atom *katom_a,
1041 const struct kbase_jd_atom *katom_b,
1042 const kbase_atom_ordering_flag_t order_flags);
1043
1044 #endif /* _KBASE_JM_JS_H_ */
1045