1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2010-2021 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 #include <linux/dma-buf.h>
23 #if IS_ENABLED(CONFIG_COMPAT)
24 #include <linux/compat.h>
25 #endif
26 #include <mali_kbase.h>
27 #include <linux/random.h>
28 #include <linux/version.h>
29 #include <linux/ratelimit.h>
30 #include <linux/priority_control_manager.h>
31
32 #include <mali_kbase_jm.h>
33 #include <mali_kbase_kinstr_jm.h>
34 #include <mali_kbase_hwaccess_jm.h>
35 #include <tl/mali_kbase_tracepoints.h>
36 #include <mali_linux_trace.h>
37
38 #include "mali_kbase_dma_fence.h"
39 #include <mali_kbase_cs_experimental.h>
40
41 #include <mali_kbase_caps.h>
42
43 #define beenthere(kctx, f, a...) dev_dbg(kctx->kbdev->dev, "%s:" f, __func__, ##a)
44
45 /* Return whether katom will run on the GPU or not. Currently only soft jobs and
46 * dependency-only atoms do not run on the GPU
47 */
48 #define IS_GPU_ATOM(katom) (!((katom->core_req & BASE_JD_REQ_SOFT_JOB) || \
49 ((katom->core_req & BASE_JD_REQ_ATOM_TYPE) == \
50 BASE_JD_REQ_DEP)))
51
52 /*
53 * This is the kernel side of the API. Only entry points are:
54 * - kbase_jd_submit(): Called from userspace to submit a single bag
55 * - kbase_jd_done(): Called from interrupt context to track the
56 * completion of a job.
57 * Callouts:
58 * - to the job manager (enqueue a job)
59 * - to the event subsystem (signals the completion/failure of bag/job-chains).
60 */
61
62 static void __user *
get_compat_pointer(struct kbase_context *kctx, const u64 p)63 get_compat_pointer(struct kbase_context *kctx, const u64 p)
64 {
65 #if IS_ENABLED(CONFIG_COMPAT)
66 if (kbase_ctx_flag(kctx, KCTX_COMPAT))
67 return compat_ptr(p);
68 #endif
69 return u64_to_user_ptr(p);
70 }
71
72 /* Mark an atom as complete, and trace it in kinstr_jm */
jd_mark_atom_complete(struct kbase_jd_atom *katom)73 static void jd_mark_atom_complete(struct kbase_jd_atom *katom)
74 {
75 katom->status = KBASE_JD_ATOM_STATE_COMPLETED;
76 kbase_kinstr_jm_atom_complete(katom);
77 dev_dbg(katom->kctx->kbdev->dev, "Atom %pK status to completed\n",
78 (void *)katom);
79 KBASE_TLSTREAM_TL_JD_ATOM_COMPLETE(katom->kctx->kbdev, katom);
80 }
81
82 /* Runs an atom, either by handing to the JS or by immediately running it in the case of soft-jobs
83 *
84 * Returns whether the JS needs a reschedule.
85 *
86 * Note that the caller must also check the atom status and
87 * if it is KBASE_JD_ATOM_STATE_COMPLETED must call jd_done_nolock
88 */
jd_run_atom(struct kbase_jd_atom *katom)89 static bool jd_run_atom(struct kbase_jd_atom *katom)
90 {
91 struct kbase_context *kctx = katom->kctx;
92
93 dev_dbg(kctx->kbdev->dev, "JD run atom %pK in kctx %pK\n",
94 (void *)katom, (void *)kctx);
95
96 KBASE_DEBUG_ASSERT(katom->status != KBASE_JD_ATOM_STATE_UNUSED);
97
98 if ((katom->core_req & BASE_JD_REQ_ATOM_TYPE) == BASE_JD_REQ_DEP) {
99 /* Dependency only atom */
100 trace_sysgraph(SGR_SUBMIT, kctx->id,
101 kbase_jd_atom_id(katom->kctx, katom));
102 jd_mark_atom_complete(katom);
103 return false;
104 } else if (katom->core_req & BASE_JD_REQ_SOFT_JOB) {
105 /* Soft-job */
106 if (katom->will_fail_event_code) {
107 kbase_finish_soft_job(katom);
108 jd_mark_atom_complete(katom);
109 return false;
110 }
111 if (kbase_process_soft_job(katom) == 0) {
112 kbase_finish_soft_job(katom);
113 jd_mark_atom_complete(katom);
114 }
115 return false;
116 }
117
118 katom->status = KBASE_JD_ATOM_STATE_IN_JS;
119 dev_dbg(kctx->kbdev->dev, "Atom %pK status to in JS\n", (void *)katom);
120 /* Queue an action about whether we should try scheduling a context */
121 return kbasep_js_add_job(kctx, katom);
122 }
123
kbase_jd_dep_clear_locked(struct kbase_jd_atom *katom)124 void kbase_jd_dep_clear_locked(struct kbase_jd_atom *katom)
125 {
126 struct kbase_device *kbdev;
127
128 KBASE_DEBUG_ASSERT(katom);
129 kbdev = katom->kctx->kbdev;
130 KBASE_DEBUG_ASSERT(kbdev);
131
132 /* Check whether the atom's other dependencies were already met. If
133 * katom is a GPU atom then the job scheduler may be able to represent
134 * the dependencies, hence we may attempt to submit it before they are
135 * met. Other atoms must have had both dependencies resolved.
136 */
137 if (IS_GPU_ATOM(katom) ||
138 (!kbase_jd_katom_dep_atom(&katom->dep[0]) &&
139 !kbase_jd_katom_dep_atom(&katom->dep[1]))) {
140 /* katom dep complete, attempt to run it */
141 bool resched = false;
142
143 KBASE_TLSTREAM_TL_RUN_ATOM_START(
144 katom->kctx->kbdev, katom,
145 kbase_jd_atom_id(katom->kctx, katom));
146 resched = jd_run_atom(katom);
147 KBASE_TLSTREAM_TL_RUN_ATOM_END(katom->kctx->kbdev, katom,
148 kbase_jd_atom_id(katom->kctx,
149 katom));
150
151 if (katom->status == KBASE_JD_ATOM_STATE_COMPLETED) {
152 /* The atom has already finished */
153 resched |= jd_done_nolock(katom, NULL);
154 }
155
156 if (resched)
157 kbase_js_sched_all(kbdev);
158 }
159 }
160
kbase_jd_free_external_resources(struct kbase_jd_atom *katom)161 void kbase_jd_free_external_resources(struct kbase_jd_atom *katom)
162 {
163 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
164 /* Flush dma-fence workqueue to ensure that any callbacks that may have
165 * been queued are done before continuing.
166 * Any successfully completed atom would have had all it's callbacks
167 * completed before the atom was run, so only flush for failed atoms.
168 */
169 if (katom->event_code != BASE_JD_EVENT_DONE)
170 flush_workqueue(katom->kctx->dma_fence.wq);
171 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
172 }
173
kbase_jd_post_external_resources(struct kbase_jd_atom *katom)174 static void kbase_jd_post_external_resources(struct kbase_jd_atom *katom)
175 {
176 KBASE_DEBUG_ASSERT(katom);
177 KBASE_DEBUG_ASSERT(katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES);
178
179 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
180 kbase_dma_fence_signal(katom);
181 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
182
183 kbase_gpu_vm_lock(katom->kctx);
184 /* only roll back if extres is non-NULL */
185 if (katom->extres) {
186 u32 res_no;
187
188 res_no = katom->nr_extres;
189 while (res_no-- > 0) {
190 struct kbase_mem_phy_alloc *alloc = katom->extres[res_no].alloc;
191 struct kbase_va_region *reg;
192
193 reg = kbase_region_tracker_find_region_base_address(
194 katom->kctx,
195 katom->extres[res_no].gpu_address);
196 kbase_unmap_external_resource(katom->kctx, reg, alloc);
197 }
198 kfree(katom->extres);
199 katom->extres = NULL;
200 }
201 kbase_gpu_vm_unlock(katom->kctx);
202 }
203
204 /*
205 * Set up external resources needed by this job.
206 *
207 * jctx.lock must be held when this is called.
208 */
209
kbase_jd_pre_external_resources(struct kbase_jd_atom *katom, const struct base_jd_atom *user_atom)210 static int kbase_jd_pre_external_resources(struct kbase_jd_atom *katom, const struct base_jd_atom *user_atom)
211 {
212 int err_ret_val = -EINVAL;
213 u32 res_no;
214 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
215 struct kbase_dma_fence_resv_info info = {
216 .resv_objs = NULL,
217 .dma_fence_resv_count = 0,
218 .dma_fence_excl_bitmap = NULL
219 };
220 #if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE)
221 /*
222 * When both dma-buf fence and Android native sync is enabled, we
223 * disable dma-buf fence for contexts that are using Android native
224 * fences.
225 */
226 const bool implicit_sync = !kbase_ctx_flag(katom->kctx,
227 KCTX_NO_IMPLICIT_SYNC);
228 #else /* CONFIG_SYNC || CONFIG_SYNC_FILE*/
229 const bool implicit_sync = true;
230 #endif /* CONFIG_SYNC || CONFIG_SYNC_FILE */
231 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
232 struct base_external_resource *input_extres;
233
234 KBASE_DEBUG_ASSERT(katom);
235 KBASE_DEBUG_ASSERT(katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES);
236
237 /* no resources encoded, early out */
238 if (!katom->nr_extres)
239 return -EINVAL;
240
241 katom->extres = kmalloc_array(katom->nr_extres, sizeof(*katom->extres), GFP_KERNEL);
242 if (!katom->extres)
243 return -ENOMEM;
244
245 /* copy user buffer to the end of our real buffer.
246 * Make sure the struct sizes haven't changed in a way
247 * we don't support
248 */
249 BUILD_BUG_ON(sizeof(*input_extres) > sizeof(*katom->extres));
250 input_extres = (struct base_external_resource *)
251 (((unsigned char *)katom->extres) +
252 (sizeof(*katom->extres) - sizeof(*input_extres)) *
253 katom->nr_extres);
254
255 if (copy_from_user(input_extres,
256 get_compat_pointer(katom->kctx, user_atom->extres_list),
257 sizeof(*input_extres) * katom->nr_extres) != 0) {
258 err_ret_val = -EINVAL;
259 goto early_err_out;
260 }
261
262 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
263 if (implicit_sync) {
264 info.resv_objs =
265 kmalloc_array(katom->nr_extres,
266 #if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
267 sizeof(struct reservation_object *),
268 #else
269 sizeof(struct dma_resv *),
270 #endif
271 GFP_KERNEL);
272 if (!info.resv_objs) {
273 err_ret_val = -ENOMEM;
274 goto early_err_out;
275 }
276
277 info.dma_fence_excl_bitmap =
278 kcalloc(BITS_TO_LONGS(katom->nr_extres),
279 sizeof(unsigned long), GFP_KERNEL);
280 if (!info.dma_fence_excl_bitmap) {
281 err_ret_val = -ENOMEM;
282 goto early_err_out;
283 }
284 }
285 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
286
287 /* Take the processes mmap lock */
288 down_read(kbase_mem_get_process_mmap_lock());
289
290 /* need to keep the GPU VM locked while we set up UMM buffers */
291 kbase_gpu_vm_lock(katom->kctx);
292 for (res_no = 0; res_no < katom->nr_extres; res_no++) {
293 struct base_external_resource *res = &input_extres[res_no];
294 struct kbase_va_region *reg;
295 struct kbase_mem_phy_alloc *alloc;
296 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
297 bool exclusive;
298 exclusive = (res->ext_resource & BASE_EXT_RES_ACCESS_EXCLUSIVE)
299 ? true : false;
300 #endif
301 reg = kbase_region_tracker_find_region_enclosing_address(
302 katom->kctx,
303 res->ext_resource & ~BASE_EXT_RES_ACCESS_EXCLUSIVE);
304 /* did we find a matching region object? */
305 if (kbase_is_region_invalid_or_free(reg)) {
306 /* roll back */
307 goto failed_loop;
308 }
309
310 if (!(katom->core_req & BASE_JD_REQ_SOFT_JOB) &&
311 (reg->flags & KBASE_REG_PROTECTED)) {
312 katom->atom_flags |= KBASE_KATOM_FLAG_PROTECTED;
313 }
314
315 alloc = kbase_map_external_resource(katom->kctx, reg,
316 current->mm);
317 if (!alloc) {
318 err_ret_val = -EINVAL;
319 goto failed_loop;
320 }
321
322 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
323 if (implicit_sync &&
324 reg->gpu_alloc->type == KBASE_MEM_TYPE_IMPORTED_UMM) {
325 #if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
326 struct reservation_object *resv;
327 #else
328 struct dma_resv *resv;
329 #endif
330 resv = reg->gpu_alloc->imported.umm.dma_buf->resv;
331 if (resv)
332 kbase_dma_fence_add_reservation(resv, &info,
333 exclusive);
334 }
335 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
336
337 /* finish with updating out array with the data we found */
338 /* NOTE: It is important that this is the last thing we do (or
339 * at least not before the first write) as we overwrite elements
340 * as we loop and could be overwriting ourself, so no writes
341 * until the last read for an element.
342 */
343 katom->extres[res_no].gpu_address = reg->start_pfn << PAGE_SHIFT; /* save the start_pfn (as an address, not pfn) to use fast lookup later */
344 katom->extres[res_no].alloc = alloc;
345 }
346 /* successfully parsed the extres array */
347 /* drop the vm lock now */
348 kbase_gpu_vm_unlock(katom->kctx);
349
350 /* Release the processes mmap lock */
351 up_read(kbase_mem_get_process_mmap_lock());
352
353 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
354 if (implicit_sync) {
355 if (info.dma_fence_resv_count) {
356 int ret;
357
358 ret = kbase_dma_fence_wait(katom, &info);
359 if (ret < 0)
360 goto failed_dma_fence_setup;
361 }
362
363 kfree(info.resv_objs);
364 kfree(info.dma_fence_excl_bitmap);
365 }
366 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
367
368 /* all done OK */
369 return 0;
370
371 /* error handling section */
372
373 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
374 failed_dma_fence_setup:
375 /* Lock the processes mmap lock */
376 down_read(kbase_mem_get_process_mmap_lock());
377
378 /* lock before we unmap */
379 kbase_gpu_vm_lock(katom->kctx);
380 #endif
381
382 failed_loop:
383 /* undo the loop work */
384 while (res_no-- > 0) {
385 struct kbase_mem_phy_alloc *alloc = katom->extres[res_no].alloc;
386
387 kbase_unmap_external_resource(katom->kctx, NULL, alloc);
388 }
389 kbase_gpu_vm_unlock(katom->kctx);
390
391 /* Release the processes mmap lock */
392 up_read(kbase_mem_get_process_mmap_lock());
393
394 early_err_out:
395 kfree(katom->extres);
396 katom->extres = NULL;
397 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
398 if (implicit_sync) {
399 kfree(info.resv_objs);
400 kfree(info.dma_fence_excl_bitmap);
401 }
402 #endif
403 return err_ret_val;
404 }
405
jd_resolve_dep(struct list_head *out_list, struct kbase_jd_atom *katom, u8 d, bool ctx_is_dying)406 static inline void jd_resolve_dep(struct list_head *out_list,
407 struct kbase_jd_atom *katom,
408 u8 d, bool ctx_is_dying)
409 {
410 u8 other_d = !d;
411
412 while (!list_empty(&katom->dep_head[d])) {
413 struct kbase_jd_atom *dep_atom;
414 struct kbase_jd_atom *other_dep_atom;
415 u8 dep_type;
416
417 dep_atom = list_entry(katom->dep_head[d].next,
418 struct kbase_jd_atom, dep_item[d]);
419 list_del(katom->dep_head[d].next);
420
421 dep_type = kbase_jd_katom_dep_type(&dep_atom->dep[d]);
422 kbase_jd_katom_dep_clear(&dep_atom->dep[d]);
423
424 if (katom->event_code != BASE_JD_EVENT_DONE &&
425 (dep_type != BASE_JD_DEP_TYPE_ORDER)) {
426 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
427 kbase_dma_fence_cancel_callbacks(dep_atom);
428 #endif
429
430 dep_atom->event_code = katom->event_code;
431 KBASE_DEBUG_ASSERT(dep_atom->status !=
432 KBASE_JD_ATOM_STATE_UNUSED);
433
434 dep_atom->will_fail_event_code = dep_atom->event_code;
435 }
436 other_dep_atom = (struct kbase_jd_atom *)
437 kbase_jd_katom_dep_atom(&dep_atom->dep[other_d]);
438
439 if (!dep_atom->in_jd_list && (!other_dep_atom ||
440 (IS_GPU_ATOM(dep_atom) && !ctx_is_dying &&
441 !dep_atom->will_fail_event_code &&
442 !other_dep_atom->will_fail_event_code))) {
443 bool dep_satisfied = true;
444 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
445 int dep_count;
446
447 dep_count = kbase_fence_dep_count_read(dep_atom);
448 if (likely(dep_count == -1)) {
449 dep_satisfied = true;
450 } else {
451 /*
452 * There are either still active callbacks, or
453 * all fences for this @dep_atom has signaled,
454 * but the worker that will queue the atom has
455 * not yet run.
456 *
457 * Wait for the fences to signal and the fence
458 * worker to run and handle @dep_atom. If
459 * @dep_atom was completed due to error on
460 * @katom, then the fence worker will pick up
461 * the complete status and error code set on
462 * @dep_atom above.
463 */
464 dep_satisfied = false;
465 }
466 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
467
468 if (dep_satisfied) {
469 dep_atom->in_jd_list = true;
470 list_add_tail(&dep_atom->jd_item, out_list);
471 }
472 }
473 }
474 }
475
476 /**
477 * is_dep_valid - Validate that a dependency is valid for early dependency
478 * submission
479 * @katom: Dependency atom to validate
480 *
481 * A dependency is valid if any of the following are true :
482 * - It does not exist (a non-existent dependency does not block submission)
483 * - It is in the job scheduler
484 * - It has completed, does not have a failure event code, and has not been
485 * marked to fail in the future
486 *
487 * Return: true if valid, false otherwise
488 */
is_dep_valid(struct kbase_jd_atom *katom)489 static bool is_dep_valid(struct kbase_jd_atom *katom)
490 {
491 /* If there's no dependency then this is 'valid' from the perspective of
492 * early dependency submission
493 */
494 if (!katom)
495 return true;
496
497 /* Dependency must have reached the job scheduler */
498 if (katom->status < KBASE_JD_ATOM_STATE_IN_JS)
499 return false;
500
501 /* If dependency has completed and has failed or will fail then it is
502 * not valid
503 */
504 if (katom->status >= KBASE_JD_ATOM_STATE_HW_COMPLETED &&
505 (katom->event_code != BASE_JD_EVENT_DONE ||
506 katom->will_fail_event_code))
507 return false;
508
509 return true;
510 }
511
jd_try_submitting_deps(struct list_head *out_list, struct kbase_jd_atom *node)512 static void jd_try_submitting_deps(struct list_head *out_list,
513 struct kbase_jd_atom *node)
514 {
515 int i;
516
517 for (i = 0; i < 2; i++) {
518 struct list_head *pos;
519
520 list_for_each(pos, &node->dep_head[i]) {
521 struct kbase_jd_atom *dep_atom = list_entry(pos,
522 struct kbase_jd_atom, dep_item[i]);
523
524 if (IS_GPU_ATOM(dep_atom) && !dep_atom->in_jd_list) {
525 /*Check if atom deps look sane*/
526 bool dep0_valid = is_dep_valid(
527 dep_atom->dep[0].atom);
528 bool dep1_valid = is_dep_valid(
529 dep_atom->dep[1].atom);
530 bool dep_satisfied = true;
531 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
532 int dep_count;
533
534 dep_count = kbase_fence_dep_count_read(
535 dep_atom);
536 if (likely(dep_count == -1)) {
537 dep_satisfied = true;
538 } else {
539 /*
540 * There are either still active callbacks, or
541 * all fences for this @dep_atom has signaled,
542 * but the worker that will queue the atom has
543 * not yet run.
544 *
545 * Wait for the fences to signal and the fence
546 * worker to run and handle @dep_atom. If
547 * @dep_atom was completed due to error on
548 * @katom, then the fence worker will pick up
549 * the complete status and error code set on
550 * @dep_atom above.
551 */
552 dep_satisfied = false;
553 }
554 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
555
556 if (dep0_valid && dep1_valid && dep_satisfied) {
557 dep_atom->in_jd_list = true;
558 list_add(&dep_atom->jd_item, out_list);
559 }
560 }
561 }
562 }
563 }
564
565 #if MALI_JIT_PRESSURE_LIMIT_BASE
566 /**
567 * jd_update_jit_usage - Update just-in-time physical memory usage for an atom.
568 *
569 * @katom: An atom that has just finished.
570 *
571 * Read back actual just-in-time memory region usage from atoms that provide
572 * this information, and update the current physical page pressure.
573 *
574 * The caller must hold the kbase_jd_context.lock.
575 */
jd_update_jit_usage(struct kbase_jd_atom *katom)576 static void jd_update_jit_usage(struct kbase_jd_atom *katom)
577 {
578 struct kbase_context *kctx = katom->kctx;
579 struct kbase_va_region *reg;
580 struct kbase_vmap_struct mapping;
581 u64 *ptr;
582 u64 used_pages;
583 unsigned int idx;
584
585 lockdep_assert_held(&kctx->jctx.lock);
586
587 /* If this atom wrote to JIT memory, find out how much it has written
588 * and update the usage information in the region.
589 */
590 for (idx = 0;
591 idx < ARRAY_SIZE(katom->jit_ids) && katom->jit_ids[idx];
592 idx++) {
593 enum heap_pointer { LOW = 0, HIGH, COUNT };
594 size_t size_to_read;
595 u64 read_val;
596
597 reg = kctx->jit_alloc[katom->jit_ids[idx]];
598
599 if (!reg) {
600 dev_warn(kctx->kbdev->dev,
601 "%s: JIT id[%u]=%u has no region\n",
602 __func__, idx, katom->jit_ids[idx]);
603 continue;
604 }
605
606 if (reg == KBASE_RESERVED_REG_JIT_ALLOC) {
607 dev_warn(kctx->kbdev->dev,
608 "%s: JIT id[%u]=%u has failed to allocate a region\n",
609 __func__, idx, katom->jit_ids[idx]);
610 continue;
611 }
612
613 if (!reg->heap_info_gpu_addr)
614 continue;
615
616 size_to_read = sizeof(*ptr);
617 if (reg->flags & KBASE_REG_HEAP_INFO_IS_SIZE)
618 size_to_read = sizeof(u32);
619 else if (reg->flags & KBASE_REG_TILER_ALIGN_TOP)
620 size_to_read = sizeof(u64[COUNT]);
621
622 ptr = kbase_vmap_prot(kctx, reg->heap_info_gpu_addr, size_to_read,
623 KBASE_REG_CPU_RD, &mapping);
624
625 if (!ptr) {
626 dev_warn(kctx->kbdev->dev,
627 "%s: JIT id[%u]=%u start=0x%llx unable to map end marker %llx\n",
628 __func__, idx, katom->jit_ids[idx],
629 reg->start_pfn << PAGE_SHIFT,
630 reg->heap_info_gpu_addr);
631 continue;
632 }
633
634 if (reg->flags & KBASE_REG_HEAP_INFO_IS_SIZE) {
635 read_val = READ_ONCE(*(u32 *)ptr);
636 used_pages = PFN_UP(read_val);
637 } else {
638 u64 addr_end;
639
640 if (reg->flags & KBASE_REG_TILER_ALIGN_TOP) {
641 const unsigned long extension_bytes =
642 reg->extension << PAGE_SHIFT;
643 const u64 low_ptr = ptr[LOW];
644 const u64 high_ptr = ptr[HIGH];
645
646 /* As either the low or high pointer could
647 * consume their partition and move onto the
648 * next chunk, we need to account for both.
649 * In the case where nothing has been allocated
650 * from the high pointer the whole chunk could
651 * be backed unnecessarily - but the granularity
652 * is the chunk size anyway and any non-zero
653 * offset of low pointer from the start of the
654 * chunk would result in the whole chunk being
655 * backed.
656 */
657 read_val = max(high_ptr, low_ptr);
658
659 /* kbase_check_alloc_sizes() already satisfies
660 * this, but here to avoid future maintenance
661 * hazards
662 */
663 WARN_ON(!is_power_of_2(extension_bytes));
664 addr_end = ALIGN(read_val, extension_bytes);
665 } else {
666 addr_end = read_val = READ_ONCE(*ptr);
667 }
668
669 if (addr_end >= (reg->start_pfn << PAGE_SHIFT))
670 used_pages = PFN_UP(addr_end) - reg->start_pfn;
671 else
672 used_pages = reg->used_pages;
673 }
674
675 trace_mali_jit_report(katom, reg, idx, read_val, used_pages);
676 kbase_trace_jit_report_gpu_mem(kctx, reg, 0u);
677
678 /* We can never have used more pages than the VA size of the
679 * region
680 */
681 if (used_pages > reg->nr_pages) {
682 dev_warn(kctx->kbdev->dev,
683 "%s: JIT id[%u]=%u start=0x%llx used_pages %llx > %zx (read 0x%llx as %s%s)\n",
684 __func__, idx, katom->jit_ids[idx],
685 reg->start_pfn << PAGE_SHIFT,
686 used_pages, reg->nr_pages, read_val,
687 (reg->flags & KBASE_REG_HEAP_INFO_IS_SIZE) ?
688 "size" : "addr",
689 (reg->flags & KBASE_REG_TILER_ALIGN_TOP) ?
690 " with align" : "");
691 used_pages = reg->nr_pages;
692 }
693 /* Note: one real use case has an atom correctly reporting 0
694 * pages in use. This happens in normal use-cases but may only
695 * happen for a few of the application's frames.
696 */
697
698 kbase_vunmap(kctx, &mapping);
699
700 kbase_jit_report_update_pressure(kctx, reg, used_pages, 0u);
701 }
702
703 kbase_jit_retry_pending_alloc(kctx);
704 }
705 #endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
706
707 /*
708 * Perform the necessary handling of an atom that has finished running
709 * on the GPU.
710 *
711 * Note that if this is a soft-job that has had kbase_prepare_soft_job called on it then the caller
712 * is responsible for calling kbase_finish_soft_job *before* calling this function.
713 *
714 * The caller must hold the kbase_jd_context.lock.
715 */
jd_done_nolock(struct kbase_jd_atom *katom, struct list_head *completed_jobs_ctx)716 bool jd_done_nolock(struct kbase_jd_atom *katom,
717 struct list_head *completed_jobs_ctx)
718 {
719 struct kbase_context *kctx = katom->kctx;
720 struct list_head completed_jobs;
721 struct list_head runnable_jobs;
722 bool need_to_try_schedule_context = false;
723 int i;
724
725 KBASE_TLSTREAM_TL_JD_DONE_NO_LOCK_START(kctx->kbdev, katom);
726
727 INIT_LIST_HEAD(&completed_jobs);
728 INIT_LIST_HEAD(&runnable_jobs);
729
730 KBASE_DEBUG_ASSERT(katom->status != KBASE_JD_ATOM_STATE_UNUSED);
731
732 #if MALI_JIT_PRESSURE_LIMIT_BASE
733 if (kbase_ctx_flag(kctx, KCTX_JPL_ENABLED))
734 jd_update_jit_usage(katom);
735 #endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
736
737 /* This is needed in case an atom is failed due to being invalid, this
738 * can happen *before* the jobs that the atom depends on have completed
739 */
740 for (i = 0; i < 2; i++) {
741 if (kbase_jd_katom_dep_atom(&katom->dep[i])) {
742 list_del(&katom->dep_item[i]);
743 kbase_jd_katom_dep_clear(&katom->dep[i]);
744 }
745 }
746
747 jd_mark_atom_complete(katom);
748
749 list_add_tail(&katom->jd_item, &completed_jobs);
750
751 while (!list_empty(&completed_jobs)) {
752 katom = list_entry(completed_jobs.prev, struct kbase_jd_atom, jd_item);
753 list_del(completed_jobs.prev);
754 KBASE_DEBUG_ASSERT(katom->status == KBASE_JD_ATOM_STATE_COMPLETED);
755
756 for (i = 0; i < 2; i++)
757 jd_resolve_dep(&runnable_jobs, katom, i,
758 kbase_ctx_flag(kctx, KCTX_DYING));
759
760 if (katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
761 kbase_jd_post_external_resources(katom);
762
763 while (!list_empty(&runnable_jobs)) {
764 struct kbase_jd_atom *node;
765
766 node = list_entry(runnable_jobs.next,
767 struct kbase_jd_atom, jd_item);
768 list_del(runnable_jobs.next);
769 node->in_jd_list = false;
770
771 dev_dbg(kctx->kbdev->dev, "List node %pK has status %d\n",
772 node, node->status);
773
774 KBASE_DEBUG_ASSERT(node->status != KBASE_JD_ATOM_STATE_UNUSED);
775 if (node->status == KBASE_JD_ATOM_STATE_IN_JS)
776 continue;
777
778 if (node->status != KBASE_JD_ATOM_STATE_COMPLETED &&
779 !kbase_ctx_flag(kctx, KCTX_DYING)) {
780 KBASE_TLSTREAM_TL_RUN_ATOM_START(
781 kctx->kbdev, node,
782 kbase_jd_atom_id(kctx, node));
783 need_to_try_schedule_context |= jd_run_atom(node);
784 KBASE_TLSTREAM_TL_RUN_ATOM_END(
785 kctx->kbdev, node,
786 kbase_jd_atom_id(kctx, node));
787 } else {
788 node->event_code = katom->event_code;
789
790 if (node->core_req &
791 BASE_JD_REQ_SOFT_JOB) {
792 WARN_ON(!list_empty(&node->queue));
793 kbase_finish_soft_job(node);
794 }
795 node->status = KBASE_JD_ATOM_STATE_COMPLETED;
796 }
797
798 if (node->status == KBASE_JD_ATOM_STATE_COMPLETED) {
799 list_add_tail(&node->jd_item, &completed_jobs);
800 } else if (node->status == KBASE_JD_ATOM_STATE_IN_JS &&
801 !node->will_fail_event_code) {
802 /* Node successfully submitted, try submitting
803 * dependencies as they may now be representable
804 * in JS
805 */
806 jd_try_submitting_deps(&runnable_jobs, node);
807 }
808 }
809
810 /* Register a completed job as a disjoint event when the GPU
811 * is in a disjoint state (ie. being reset).
812 */
813 kbase_disjoint_event_potential(kctx->kbdev);
814 if (completed_jobs_ctx)
815 list_add_tail(&katom->jd_item, completed_jobs_ctx);
816 else
817 kbase_event_post(kctx, katom);
818
819 /* Decrement and check the TOTAL number of jobs. This includes
820 * those not tracked by the scheduler: 'not ready to run' and
821 * 'dependency-only' jobs.
822 */
823 if (--kctx->jctx.job_nr == 0)
824 /* All events are safely queued now, and we can signal
825 * any waiter that we've got no more jobs (so we can be
826 * safely terminated)
827 */
828 wake_up(&kctx->jctx.zero_jobs_wait);
829 }
830 KBASE_TLSTREAM_TL_JD_DONE_NO_LOCK_END(kctx->kbdev, katom);
831 return need_to_try_schedule_context;
832 }
833
834 KBASE_EXPORT_TEST_API(jd_done_nolock);
835
836 #if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
837 enum {
838 CORE_REQ_DEP_ONLY,
839 CORE_REQ_SOFT,
840 CORE_REQ_COMPUTE,
841 CORE_REQ_FRAGMENT,
842 CORE_REQ_VERTEX,
843 CORE_REQ_TILER,
844 CORE_REQ_FRAGMENT_VERTEX,
845 CORE_REQ_FRAGMENT_VERTEX_TILER,
846 CORE_REQ_FRAGMENT_TILER,
847 CORE_REQ_VERTEX_TILER,
848 CORE_REQ_UNKNOWN
849 };
850 static const char * const core_req_strings[] = {
851 "Dependency Only Job",
852 "Soft Job",
853 "Compute Shader Job",
854 "Fragment Shader Job",
855 "Vertex/Geometry Shader Job",
856 "Tiler Job",
857 "Fragment Shader + Vertex/Geometry Shader Job",
858 "Fragment Shader + Vertex/Geometry Shader Job + Tiler Job",
859 "Fragment Shader + Tiler Job",
860 "Vertex/Geometry Shader Job + Tiler Job",
861 "Unknown Job"
862 };
kbasep_map_core_reqs_to_string(base_jd_core_req core_req)863 static const char *kbasep_map_core_reqs_to_string(base_jd_core_req core_req)
864 {
865 if (core_req & BASE_JD_REQ_SOFT_JOB)
866 return core_req_strings[CORE_REQ_SOFT];
867 if (core_req & BASE_JD_REQ_ONLY_COMPUTE)
868 return core_req_strings[CORE_REQ_COMPUTE];
869 switch (core_req & (BASE_JD_REQ_FS | BASE_JD_REQ_CS | BASE_JD_REQ_T)) {
870 case BASE_JD_REQ_DEP:
871 return core_req_strings[CORE_REQ_DEP_ONLY];
872 case BASE_JD_REQ_FS:
873 return core_req_strings[CORE_REQ_FRAGMENT];
874 case BASE_JD_REQ_CS:
875 return core_req_strings[CORE_REQ_VERTEX];
876 case BASE_JD_REQ_T:
877 return core_req_strings[CORE_REQ_TILER];
878 case (BASE_JD_REQ_FS | BASE_JD_REQ_CS):
879 return core_req_strings[CORE_REQ_FRAGMENT_VERTEX];
880 case (BASE_JD_REQ_FS | BASE_JD_REQ_T):
881 return core_req_strings[CORE_REQ_FRAGMENT_TILER];
882 case (BASE_JD_REQ_CS | BASE_JD_REQ_T):
883 return core_req_strings[CORE_REQ_VERTEX_TILER];
884 case (BASE_JD_REQ_FS | BASE_JD_REQ_CS | BASE_JD_REQ_T):
885 return core_req_strings[CORE_REQ_FRAGMENT_VERTEX_TILER];
886 }
887 return core_req_strings[CORE_REQ_UNKNOWN];
888 }
889 #endif
890
891 /* Trace an atom submission. */
jd_trace_atom_submit(struct kbase_context *const kctx, struct kbase_jd_atom *const katom, int *priority)892 static void jd_trace_atom_submit(struct kbase_context *const kctx,
893 struct kbase_jd_atom *const katom,
894 int *priority)
895 {
896 struct kbase_device *const kbdev = kctx->kbdev;
897
898 KBASE_TLSTREAM_TL_NEW_ATOM(kbdev, katom, kbase_jd_atom_id(kctx, katom));
899 KBASE_TLSTREAM_TL_RET_ATOM_CTX(kbdev, katom, kctx);
900 if (priority)
901 KBASE_TLSTREAM_TL_ATTRIB_ATOM_PRIORITY(kbdev, katom, *priority);
902 KBASE_TLSTREAM_TL_ATTRIB_ATOM_STATE(kbdev, katom, TL_ATOM_STATE_IDLE);
903 kbase_kinstr_jm_atom_queue(katom);
904 }
905
jd_submit_atom(struct kbase_context *const kctx, const struct base_jd_atom *const user_atom, const struct base_jd_fragment *const user_jc_incr, struct kbase_jd_atom *const katom)906 static bool jd_submit_atom(struct kbase_context *const kctx,
907 const struct base_jd_atom *const user_atom,
908 const struct base_jd_fragment *const user_jc_incr,
909 struct kbase_jd_atom *const katom)
910 {
911 struct kbase_device *kbdev = kctx->kbdev;
912 struct kbase_jd_context *jctx = &kctx->jctx;
913 int queued = 0;
914 int i;
915 int sched_prio;
916 bool will_fail = false;
917 unsigned long flags;
918 enum kbase_jd_atom_state status;
919
920 dev_dbg(kbdev->dev, "User did JD submit atom %pK\n", (void *)katom);
921
922 /* Update the TOTAL number of jobs. This includes those not tracked by
923 * the scheduler: 'not ready to run' and 'dependency-only' jobs.
924 */
925 jctx->job_nr++;
926
927 #if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
928 katom->start_timestamp.tv64 = 0;
929 #else
930 katom->start_timestamp = 0;
931 #endif
932 katom->udata = user_atom->udata;
933 katom->kctx = kctx;
934 katom->nr_extres = user_atom->nr_extres;
935 katom->extres = NULL;
936 katom->device_nr = user_atom->device_nr;
937 katom->jc = user_atom->jc;
938 katom->core_req = user_atom->core_req;
939 katom->jobslot = user_atom->jobslot;
940 katom->seq_nr = user_atom->seq_nr;
941 katom->atom_flags = 0;
942 katom->retry_count = 0;
943 katom->need_cache_flush_cores_retained = 0;
944 katom->pre_dep = NULL;
945 katom->post_dep = NULL;
946 katom->x_pre_dep = NULL;
947 katom->x_post_dep = NULL;
948 katom->will_fail_event_code = BASE_JD_EVENT_NOT_STARTED;
949 katom->softjob_data = NULL;
950
951 trace_sysgraph(SGR_ARRIVE, kctx->id, user_atom->atom_number);
952
953 #if MALI_JIT_PRESSURE_LIMIT_BASE
954 /* Older API version atoms might have random values where jit_id now
955 * lives, but we must maintain backwards compatibility - handle the
956 * issue.
957 */
958 if (!mali_kbase_supports_jit_pressure_limit(kctx->api_version)) {
959 katom->jit_ids[0] = 0;
960 katom->jit_ids[1] = 0;
961 } else {
962 katom->jit_ids[0] = user_atom->jit_id[0];
963 katom->jit_ids[1] = user_atom->jit_id[1];
964 }
965 #endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
966
967 katom->renderpass_id = user_atom->renderpass_id;
968
969 /* Implicitly sets katom->protected_state.enter as well. */
970 katom->protected_state.exit = KBASE_ATOM_EXIT_PROTECTED_CHECK;
971
972 katom->age = kctx->age_count++;
973
974 INIT_LIST_HEAD(&katom->queue);
975 INIT_LIST_HEAD(&katom->jd_item);
976 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
977 kbase_fence_dep_count_set(katom, -1);
978 #endif
979
980 /* Don't do anything if there is a mess up with dependencies.
981 This is done in a separate cycle to check both the dependencies at ones, otherwise
982 it will be extra complexity to deal with 1st dependency ( just added to the list )
983 if only the 2nd one has invalid config.
984 */
985 for (i = 0; i < 2; i++) {
986 int dep_atom_number = user_atom->pre_dep[i].atom_id;
987 base_jd_dep_type dep_atom_type = user_atom->pre_dep[i].dependency_type;
988
989 if (dep_atom_number) {
990 if (dep_atom_type != BASE_JD_DEP_TYPE_ORDER &&
991 dep_atom_type != BASE_JD_DEP_TYPE_DATA) {
992 katom->event_code = BASE_JD_EVENT_JOB_CONFIG_FAULT;
993 katom->status = KBASE_JD_ATOM_STATE_COMPLETED;
994 dev_dbg(kbdev->dev,
995 "Atom %pK status to completed\n",
996 (void *)katom);
997
998 /* Wrong dependency setup. Atom will be sent
999 * back to user space. Do not record any
1000 * dependencies.
1001 */
1002 jd_trace_atom_submit(kctx, katom, NULL);
1003 return jd_done_nolock(katom, NULL);
1004 }
1005 }
1006 }
1007
1008 /* Add dependencies */
1009 for (i = 0; i < 2; i++) {
1010 int dep_atom_number = user_atom->pre_dep[i].atom_id;
1011 base_jd_dep_type dep_atom_type;
1012 struct kbase_jd_atom *dep_atom = &jctx->atoms[dep_atom_number];
1013
1014 dep_atom_type = user_atom->pre_dep[i].dependency_type;
1015 kbase_jd_katom_dep_clear(&katom->dep[i]);
1016
1017 if (!dep_atom_number)
1018 continue;
1019
1020 if (dep_atom->status == KBASE_JD_ATOM_STATE_UNUSED ||
1021 dep_atom->status == KBASE_JD_ATOM_STATE_COMPLETED) {
1022
1023 if (dep_atom->event_code == BASE_JD_EVENT_DONE)
1024 continue;
1025 /* don't stop this atom if it has an order dependency
1026 * only to the failed one, try to submit it through
1027 * the normal path
1028 */
1029 if (dep_atom_type == BASE_JD_DEP_TYPE_ORDER &&
1030 dep_atom->event_code > BASE_JD_EVENT_ACTIVE) {
1031 continue;
1032 }
1033
1034 /* Atom has completed, propagate the error code if any */
1035 katom->event_code = dep_atom->event_code;
1036 katom->status = KBASE_JD_ATOM_STATE_QUEUED;
1037 dev_dbg(kbdev->dev, "Atom %pK status to queued\n",
1038 (void *)katom);
1039
1040 /* This atom will be sent back to user space.
1041 * Do not record any dependencies.
1042 */
1043 jd_trace_atom_submit(kctx, katom, NULL);
1044
1045 will_fail = true;
1046
1047 } else {
1048 /* Atom is in progress, add this atom to the list */
1049 list_add_tail(&katom->dep_item[i], &dep_atom->dep_head[i]);
1050 kbase_jd_katom_dep_set(&katom->dep[i], dep_atom, dep_atom_type);
1051 queued = 1;
1052 }
1053 }
1054
1055 if (will_fail) {
1056 if (!queued) {
1057 if (katom->core_req & BASE_JD_REQ_SOFT_JOB) {
1058 /* This softjob has failed due to a previous
1059 * dependency, however we should still run the
1060 * prepare & finish functions
1061 */
1062 int err = kbase_prepare_soft_job(katom);
1063
1064 if (err >= 0)
1065 kbase_finish_soft_job(katom);
1066 }
1067 return jd_done_nolock(katom, NULL);
1068 }
1069
1070 katom->will_fail_event_code = katom->event_code;
1071 }
1072
1073 /* These must occur after the above loop to ensure that an atom
1074 * that depends on a previous atom with the same number behaves
1075 * as expected
1076 */
1077 katom->event_code = BASE_JD_EVENT_DONE;
1078 katom->status = KBASE_JD_ATOM_STATE_QUEUED;
1079 dev_dbg(kbdev->dev, "Atom %pK status to queued\n", (void *)katom);
1080
1081 /* For invalid priority, be most lenient and choose the default */
1082 sched_prio = kbasep_js_atom_prio_to_sched_prio(user_atom->prio);
1083 if (sched_prio == KBASE_JS_ATOM_SCHED_PRIO_INVALID)
1084 sched_prio = KBASE_JS_ATOM_SCHED_PRIO_DEFAULT;
1085
1086 /* Cap the priority to jctx.max_priority */
1087 katom->sched_priority = (sched_prio < kctx->jctx.max_priority) ?
1088 kctx->jctx.max_priority : sched_prio;
1089
1090 /* Create a new atom. */
1091 jd_trace_atom_submit(kctx, katom, &katom->sched_priority);
1092
1093 #if !MALI_INCREMENTAL_RENDERING
1094 /* Reject atoms for incremental rendering if not supported */
1095 if (katom->core_req &
1096 (BASE_JD_REQ_START_RENDERPASS|BASE_JD_REQ_END_RENDERPASS)) {
1097 dev_err(kctx->kbdev->dev,
1098 "Rejecting atom with unsupported core_req 0x%x\n",
1099 katom->core_req);
1100 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1101 return jd_done_nolock(katom, NULL);
1102 }
1103 #endif /* !MALI_INCREMENTAL_RENDERING */
1104
1105 if (katom->core_req & BASE_JD_REQ_END_RENDERPASS) {
1106 WARN_ON(katom->jc != 0);
1107 katom->jc_fragment = *user_jc_incr;
1108 } else if (!katom->jc &&
1109 (katom->core_req & BASE_JD_REQ_ATOM_TYPE) != BASE_JD_REQ_DEP) {
1110 /* Reject atoms with job chain = NULL, as these cause issues
1111 * with soft-stop
1112 */
1113 dev_err(kctx->kbdev->dev, "Rejecting atom with jc = NULL\n");
1114 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1115 return jd_done_nolock(katom, NULL);
1116 }
1117
1118 /* Reject atoms with an invalid device_nr */
1119 if ((katom->core_req & BASE_JD_REQ_SPECIFIC_COHERENT_GROUP) &&
1120 (katom->device_nr >= kctx->kbdev->gpu_props.num_core_groups)) {
1121 dev_err(kctx->kbdev->dev,
1122 "Rejecting atom with invalid device_nr %d\n",
1123 katom->device_nr);
1124 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1125 return jd_done_nolock(katom, NULL);
1126 }
1127
1128 /* Reject atoms with invalid core requirements */
1129 if ((katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES) &&
1130 (katom->core_req & BASE_JD_REQ_EVENT_COALESCE)) {
1131 dev_err(kctx->kbdev->dev,
1132 "Rejecting atom with invalid core requirements\n");
1133 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1134 katom->core_req &= ~BASE_JD_REQ_EVENT_COALESCE;
1135 return jd_done_nolock(katom, NULL);
1136 }
1137
1138 /* Reject soft-job atom of certain types from accessing external resources */
1139 if ((katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES) &&
1140 (((katom->core_req & BASE_JD_REQ_SOFT_JOB_TYPE) == BASE_JD_REQ_SOFT_FENCE_WAIT) ||
1141 ((katom->core_req & BASE_JD_REQ_SOFT_JOB_TYPE) == BASE_JD_REQ_SOFT_JIT_ALLOC) ||
1142 ((katom->core_req & BASE_JD_REQ_SOFT_JOB_TYPE) == BASE_JD_REQ_SOFT_JIT_FREE))) {
1143 dev_err(kctx->kbdev->dev,
1144 "Rejecting soft-job atom accessing external resources\n");
1145 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1146 return jd_done_nolock(katom, NULL);
1147 }
1148
1149 if (katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES) {
1150 /* handle what we need to do to access the external resources */
1151 if (kbase_jd_pre_external_resources(katom, user_atom) != 0) {
1152 /* setup failed (no access, bad resource, unknown resource types, etc.) */
1153 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1154 return jd_done_nolock(katom, NULL);
1155 }
1156 }
1157
1158 #if !MALI_JIT_PRESSURE_LIMIT_BASE
1159 if (mali_kbase_supports_jit_pressure_limit(kctx->api_version) &&
1160 (user_atom->jit_id[0] || user_atom->jit_id[1])) {
1161 /* JIT pressure limit is disabled, but we are receiving non-0
1162 * JIT IDs - atom is invalid.
1163 */
1164 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1165 return jd_done_nolock(katom, NULL);
1166 }
1167 #endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
1168
1169 /* Validate the atom. Function will return error if the atom is
1170 * malformed.
1171 *
1172 * Soft-jobs never enter the job scheduler but have their own initialize method.
1173 *
1174 * If either fail then we immediately complete the atom with an error.
1175 */
1176 if ((katom->core_req & BASE_JD_REQ_SOFT_JOB) == 0) {
1177 if (!kbase_js_is_atom_valid(kctx->kbdev, katom)) {
1178 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1179 return jd_done_nolock(katom, NULL);
1180 }
1181 } else {
1182 /* Soft-job */
1183 if (kbase_prepare_soft_job(katom) != 0) {
1184 katom->event_code = BASE_JD_EVENT_JOB_INVALID;
1185 return jd_done_nolock(katom, NULL);
1186 }
1187 }
1188
1189 #if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
1190 katom->work_id = atomic_inc_return(&jctx->work_id);
1191 trace_gpu_job_enqueue(kctx->id, katom->work_id,
1192 kbasep_map_core_reqs_to_string(katom->core_req));
1193 #endif
1194
1195 if (queued && !IS_GPU_ATOM(katom))
1196 return false;
1197
1198 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
1199 if (kbase_fence_dep_count_read(katom) != -1)
1200 return false;
1201
1202 #endif /* CONFIG_MALI_BIFROST_DMA_FENCE */
1203
1204 if (katom->core_req & BASE_JD_REQ_SOFT_JOB) {
1205 if (kbase_process_soft_job(katom) == 0) {
1206 kbase_finish_soft_job(katom);
1207 return jd_done_nolock(katom, NULL);
1208 }
1209 return false;
1210 }
1211
1212 if ((katom->core_req & BASE_JD_REQ_ATOM_TYPE) != BASE_JD_REQ_DEP) {
1213 bool need_to_try_schedule_context;
1214
1215 katom->status = KBASE_JD_ATOM_STATE_IN_JS;
1216 dev_dbg(kctx->kbdev->dev, "Atom %pK status to in JS\n",
1217 (void *)katom);
1218
1219 need_to_try_schedule_context = kbasep_js_add_job(kctx, katom);
1220 /* If job was cancelled then resolve immediately */
1221 if (katom->event_code != BASE_JD_EVENT_JOB_CANCELLED)
1222 return need_to_try_schedule_context;
1223
1224 /* Synchronize with backend reset */
1225 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1226 status = katom->status;
1227 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1228 if (status == KBASE_JD_ATOM_STATE_HW_COMPLETED) {
1229 dev_dbg(kctx->kbdev->dev,
1230 "Atom %d cancelled on HW\n",
1231 kbase_jd_atom_id(katom->kctx, katom));
1232 return need_to_try_schedule_context;
1233 }
1234 }
1235
1236 /* This is a pure dependency. Resolve it immediately */
1237 return jd_done_nolock(katom, NULL);
1238 }
1239
kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_atoms, u32 stride, bool uk6_atom)1240 int kbase_jd_submit(struct kbase_context *kctx,
1241 void __user *user_addr, u32 nr_atoms, u32 stride,
1242 bool uk6_atom)
1243 {
1244 struct kbase_jd_context *jctx = &kctx->jctx;
1245 int err = 0;
1246 int i;
1247 bool need_to_try_schedule_context = false;
1248 struct kbase_device *kbdev;
1249 u32 latest_flush;
1250
1251 bool jd_atom_is_v2 = (stride == sizeof(struct base_jd_atom_v2) ||
1252 stride == offsetof(struct base_jd_atom_v2, renderpass_id));
1253
1254 /*
1255 * kbase_jd_submit isn't expected to fail and so all errors with the
1256 * jobs are reported by immediately failing them (through event system)
1257 */
1258 kbdev = kctx->kbdev;
1259
1260 beenthere(kctx, "%s", "Enter");
1261
1262 if (kbase_ctx_flag(kctx, KCTX_SUBMIT_DISABLED)) {
1263 dev_err(kbdev->dev, "Attempt to submit to a context that has SUBMIT_DISABLED set on it\n");
1264 return -EINVAL;
1265 }
1266
1267 if (stride != offsetof(struct base_jd_atom_v2, renderpass_id) &&
1268 stride != sizeof(struct base_jd_atom_v2) &&
1269 stride != offsetof(struct base_jd_atom, renderpass_id) &&
1270 stride != sizeof(struct base_jd_atom)) {
1271 dev_err(kbdev->dev,
1272 "Stride %u passed to job_submit isn't supported by the kernel\n",
1273 stride);
1274 return -EINVAL;
1275 }
1276
1277 /* All atoms submitted in this call have the same flush ID */
1278 latest_flush = kbase_backend_get_current_flush_id(kbdev);
1279
1280 for (i = 0; i < nr_atoms; i++) {
1281 struct base_jd_atom user_atom;
1282 struct base_jd_fragment user_jc_incr;
1283 struct kbase_jd_atom *katom;
1284
1285 if (unlikely(jd_atom_is_v2)) {
1286 if (copy_from_user(&user_atom.jc, user_addr, sizeof(struct base_jd_atom_v2)) != 0) {
1287 dev_dbg(kbdev->dev,
1288 "Invalid atom address %p passed to job_submit\n",
1289 user_addr);
1290 err = -EFAULT;
1291 break;
1292 }
1293
1294 /* no seq_nr in v2 */
1295 user_atom.seq_nr = 0;
1296 } else {
1297 if (copy_from_user(&user_atom, user_addr, stride) != 0) {
1298 dev_dbg(kbdev->dev,
1299 "Invalid atom address %p passed to job_submit\n",
1300 user_addr);
1301 err = -EFAULT;
1302 break;
1303 }
1304 }
1305
1306 if (stride == offsetof(struct base_jd_atom_v2, renderpass_id)) {
1307 dev_dbg(kbdev->dev, "No renderpass ID: use 0\n");
1308 user_atom.renderpass_id = 0;
1309 } else {
1310 /* Ensure all padding bytes are 0 for potential future
1311 * extension
1312 */
1313 size_t j;
1314
1315 dev_dbg(kbdev->dev, "Renderpass ID is %d\n",
1316 user_atom.renderpass_id);
1317 for (j = 0; j < sizeof(user_atom.padding); j++) {
1318 if (user_atom.padding[j]) {
1319 dev_err(kbdev->dev,
1320 "Bad padding byte %zu: %d\n",
1321 j, user_atom.padding[j]);
1322 err = -EINVAL;
1323 break;
1324 }
1325 }
1326 if (err)
1327 break;
1328 }
1329
1330 /* In this case 'jc' is the CPU address of a struct
1331 * instead of a GPU address of a job chain.
1332 */
1333 if (user_atom.core_req & BASE_JD_REQ_END_RENDERPASS) {
1334 if (copy_from_user(&user_jc_incr,
1335 u64_to_user_ptr(user_atom.jc),
1336 sizeof(user_jc_incr))) {
1337 dev_err(kbdev->dev,
1338 "Invalid jc address 0x%llx passed to job_submit\n",
1339 user_atom.jc);
1340 err = -EFAULT;
1341 break;
1342 }
1343 dev_dbg(kbdev->dev, "Copied IR jobchain addresses\n");
1344 user_atom.jc = 0;
1345 }
1346
1347 user_addr = (void __user *)((uintptr_t) user_addr + stride);
1348
1349 mutex_lock(&jctx->lock);
1350 #ifndef compiletime_assert
1351 #define compiletime_assert_defined
1352 #define compiletime_assert(x, msg) do { switch (0) { case 0: case (x):; } } \
1353 while (false)
1354 #endif
1355 compiletime_assert((1 << (8*sizeof(user_atom.atom_number))) ==
1356 BASE_JD_ATOM_COUNT,
1357 "BASE_JD_ATOM_COUNT and base_atom_id type out of sync");
1358 compiletime_assert(sizeof(user_atom.pre_dep[0].atom_id) ==
1359 sizeof(user_atom.atom_number),
1360 "BASE_JD_ATOM_COUNT and base_atom_id type out of sync");
1361 #ifdef compiletime_assert_defined
1362 #undef compiletime_assert
1363 #undef compiletime_assert_defined
1364 #endif
1365 katom = &jctx->atoms[user_atom.atom_number];
1366
1367 /* Record the flush ID for the cache flush optimisation */
1368 katom->flush_id = latest_flush;
1369
1370 while (katom->status != KBASE_JD_ATOM_STATE_UNUSED) {
1371 /* Atom number is already in use, wait for the atom to
1372 * complete
1373 */
1374 mutex_unlock(&jctx->lock);
1375
1376 /* This thread will wait for the atom to complete. Due
1377 * to thread scheduling we are not sure that the other
1378 * thread that owns the atom will also schedule the
1379 * context, so we force the scheduler to be active and
1380 * hence eventually schedule this context at some point
1381 * later.
1382 */
1383 kbase_js_sched_all(kbdev);
1384
1385 if (wait_event_killable(katom->completed,
1386 katom->status ==
1387 KBASE_JD_ATOM_STATE_UNUSED) != 0) {
1388 /* We're being killed so the result code
1389 * doesn't really matter
1390 */
1391 return 0;
1392 }
1393 mutex_lock(&jctx->lock);
1394 }
1395 KBASE_TLSTREAM_TL_JD_SUBMIT_ATOM_START(kbdev, katom);
1396 need_to_try_schedule_context |= jd_submit_atom(kctx, &user_atom,
1397 &user_jc_incr, katom);
1398 KBASE_TLSTREAM_TL_JD_SUBMIT_ATOM_END(kbdev, katom);
1399 /* Register a completed job as a disjoint event when the GPU is in a disjoint state
1400 * (ie. being reset).
1401 */
1402 kbase_disjoint_event_potential(kbdev);
1403
1404 mutex_unlock(&jctx->lock);
1405 }
1406
1407 if (need_to_try_schedule_context)
1408 kbase_js_sched_all(kbdev);
1409
1410 return err;
1411 }
1412
1413 KBASE_EXPORT_TEST_API(kbase_jd_submit);
1414
kbase_jd_done_worker(struct work_struct *data)1415 void kbase_jd_done_worker(struct work_struct *data)
1416 {
1417 struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom, work);
1418 struct kbase_jd_context *jctx;
1419 struct kbase_context *kctx;
1420 struct kbasep_js_kctx_info *js_kctx_info;
1421 struct kbase_device *kbdev;
1422 struct kbasep_js_device_data *js_devdata;
1423 u64 cache_jc = katom->jc;
1424 struct kbasep_js_atom_retained_state katom_retained_state;
1425 bool context_idle;
1426 base_jd_core_req core_req = katom->core_req;
1427
1428 /* Soft jobs should never reach this function */
1429 KBASE_DEBUG_ASSERT((katom->core_req & BASE_JD_REQ_SOFT_JOB) == 0);
1430
1431 kctx = katom->kctx;
1432 jctx = &kctx->jctx;
1433 kbdev = kctx->kbdev;
1434 js_kctx_info = &kctx->jctx.sched_info;
1435 js_devdata = &kbdev->js_data;
1436
1437 dev_dbg(kbdev->dev, "Enter atom %pK done worker for kctx %pK\n",
1438 (void *)katom, (void *)kctx);
1439
1440 KBASE_KTRACE_ADD_JM(kbdev, JD_DONE_WORKER, kctx, katom, katom->jc, 0);
1441
1442 kbase_backend_complete_wq(kbdev, katom);
1443
1444 /*
1445 * Begin transaction on JD context and JS context
1446 */
1447 mutex_lock(&jctx->lock);
1448 KBASE_TLSTREAM_TL_ATTRIB_ATOM_STATE(kbdev, katom, TL_ATOM_STATE_DONE);
1449 mutex_lock(&js_devdata->queue_mutex);
1450 mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1451
1452 /* This worker only gets called on contexts that are scheduled *in*. This is
1453 * because it only happens in response to an IRQ from a job that was
1454 * running.
1455 */
1456 KBASE_DEBUG_ASSERT(kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1457
1458 if (katom->event_code == BASE_JD_EVENT_STOPPED) {
1459 unsigned long flags;
1460
1461 dev_dbg(kbdev->dev, "Atom %pK has been promoted to stopped\n",
1462 (void *)katom);
1463 mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1464 mutex_unlock(&js_devdata->queue_mutex);
1465
1466 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1467
1468 katom->status = KBASE_JD_ATOM_STATE_IN_JS;
1469 dev_dbg(kctx->kbdev->dev, "Atom %pK status to in JS\n",
1470 (void *)katom);
1471 kbase_js_unpull(kctx, katom);
1472
1473 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1474 mutex_unlock(&jctx->lock);
1475
1476 return;
1477 }
1478
1479 if ((katom->event_code != BASE_JD_EVENT_DONE) &&
1480 (!kbase_ctx_flag(katom->kctx, KCTX_DYING)))
1481 dev_err(kbdev->dev,
1482 "t6xx: GPU fault 0x%02lx from job slot %d\n",
1483 (unsigned long)katom->event_code,
1484 katom->slot_nr);
1485
1486 /* Retain state before the katom disappears */
1487 kbasep_js_atom_retained_state_copy(&katom_retained_state, katom);
1488
1489 context_idle = kbase_js_complete_atom_wq(kctx, katom);
1490
1491 KBASE_DEBUG_ASSERT(kbasep_js_has_atom_finished(&katom_retained_state));
1492
1493 kbasep_js_remove_job(kbdev, kctx, katom);
1494 mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1495 mutex_unlock(&js_devdata->queue_mutex);
1496 /* jd_done_nolock() requires the jsctx_mutex lock to be dropped */
1497 jd_done_nolock(katom, &kctx->completed_jobs);
1498
1499 /* katom may have been freed now, do not use! */
1500
1501 if (context_idle) {
1502 unsigned long flags;
1503
1504 context_idle = false;
1505 mutex_lock(&js_devdata->queue_mutex);
1506 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1507
1508 /* If kbase_sched() has scheduled this context back in then
1509 * KCTX_ACTIVE will have been set after we marked it as
1510 * inactive, and another pm reference will have been taken, so
1511 * drop our reference. But do not call kbase_jm_idle_ctx(), as
1512 * the context is active and fast-starting is allowed.
1513 *
1514 * If an atom has been fast-started then
1515 * kbase_jsctx_atoms_pulled(kctx) will return non-zero but
1516 * KCTX_ACTIVE will still be false (as the previous pm
1517 * reference has been inherited). Do NOT drop our reference, as
1518 * it has been re-used, and leave the context as active.
1519 *
1520 * If no new atoms have been started then KCTX_ACTIVE will
1521 * still be false and kbase_jsctx_atoms_pulled(kctx) will
1522 * return zero, so drop the reference and call
1523 * kbase_jm_idle_ctx().
1524 *
1525 * As the checks are done under both the queue_mutex and
1526 * hwaccess_lock is should be impossible for this to race
1527 * with the scheduler code.
1528 */
1529 if (kbase_ctx_flag(kctx, KCTX_ACTIVE) ||
1530 !kbase_jsctx_atoms_pulled(kctx)) {
1531 /* Calling kbase_jm_idle_ctx() here will ensure that
1532 * atoms are not fast-started when we drop the
1533 * hwaccess_lock. This is not performed if
1534 * KCTX_ACTIVE is set as in that case another pm
1535 * reference has been taken and a fast-start would be
1536 * valid.
1537 */
1538 if (!kbase_ctx_flag(kctx, KCTX_ACTIVE))
1539 kbase_jm_idle_ctx(kbdev, kctx);
1540 context_idle = true;
1541 } else {
1542 kbase_ctx_flag_set(kctx, KCTX_ACTIVE);
1543 }
1544 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1545 mutex_unlock(&js_devdata->queue_mutex);
1546 }
1547
1548 /*
1549 * Transaction complete
1550 */
1551 mutex_unlock(&jctx->lock);
1552
1553 /* Job is now no longer running, so can now safely release the context
1554 * reference, and handle any actions that were logged against the
1555 * atom's retained state
1556 */
1557
1558 kbasep_js_runpool_release_ctx_and_katom_retained_state(kbdev, kctx, &katom_retained_state);
1559
1560 kbase_js_sched_all(kbdev);
1561
1562 if (!atomic_dec_return(&kctx->work_count)) {
1563 /* If worker now idle then post all events that jd_done_nolock()
1564 * has queued
1565 */
1566 mutex_lock(&jctx->lock);
1567 while (!list_empty(&kctx->completed_jobs)) {
1568 struct kbase_jd_atom *atom = list_entry(
1569 kctx->completed_jobs.next,
1570 struct kbase_jd_atom, jd_item);
1571 list_del(kctx->completed_jobs.next);
1572
1573 kbase_event_post(kctx, atom);
1574 }
1575 mutex_unlock(&jctx->lock);
1576 }
1577
1578 kbase_backend_complete_wq_post_sched(kbdev, core_req);
1579
1580 if (context_idle)
1581 kbase_pm_context_idle(kbdev);
1582
1583 KBASE_KTRACE_ADD_JM(kbdev, JD_DONE_WORKER_END, kctx, NULL, cache_jc, 0);
1584
1585 dev_dbg(kbdev->dev, "Leave atom %pK done worker for kctx %pK\n",
1586 (void *)katom, (void *)kctx);
1587 }
1588
1589 /**
1590 * jd_cancel_worker - Work queue job cancel function.
1591 * @data: a &struct work_struct
1592 *
1593 * Only called as part of 'Zapping' a context (which occurs on termination).
1594 * Operates serially with the kbase_jd_done_worker() on the work queue.
1595 *
1596 * This can only be called on contexts that aren't scheduled.
1597 *
1598 * We don't need to release most of the resources that would occur on
1599 * kbase_jd_done() or kbase_jd_done_worker(), because the atoms here must not be
1600 * running (by virtue of only being called on contexts that aren't
1601 * scheduled).
1602 */
jd_cancel_worker(struct work_struct *data)1603 static void jd_cancel_worker(struct work_struct *data)
1604 {
1605 struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom, work);
1606 struct kbase_jd_context *jctx;
1607 struct kbase_context *kctx;
1608 struct kbasep_js_kctx_info *js_kctx_info;
1609 bool need_to_try_schedule_context;
1610 bool attr_state_changed;
1611 struct kbase_device *kbdev;
1612
1613 /* Soft jobs should never reach this function */
1614 KBASE_DEBUG_ASSERT((katom->core_req & BASE_JD_REQ_SOFT_JOB) == 0);
1615
1616 kctx = katom->kctx;
1617 kbdev = kctx->kbdev;
1618 jctx = &kctx->jctx;
1619 js_kctx_info = &kctx->jctx.sched_info;
1620
1621 KBASE_KTRACE_ADD_JM(kbdev, JD_CANCEL_WORKER, kctx, katom, katom->jc, 0);
1622
1623 /* This only gets called on contexts that are scheduled out. Hence, we must
1624 * make sure we don't de-ref the number of running jobs (there aren't
1625 * any), nor must we try to schedule out the context (it's already
1626 * scheduled out).
1627 */
1628 KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1629
1630 /* Scheduler: Remove the job from the system */
1631 mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1632 attr_state_changed = kbasep_js_remove_cancelled_job(kbdev, kctx, katom);
1633 mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1634
1635 mutex_lock(&jctx->lock);
1636
1637 need_to_try_schedule_context = jd_done_nolock(katom, NULL);
1638 /* Because we're zapping, we're not adding any more jobs to this ctx, so no need to
1639 * schedule the context. There's also no need for the jsctx_mutex to have been taken
1640 * around this too.
1641 */
1642 KBASE_DEBUG_ASSERT(!need_to_try_schedule_context);
1643
1644 /* katom may have been freed now, do not use! */
1645 mutex_unlock(&jctx->lock);
1646
1647 if (attr_state_changed)
1648 kbase_js_sched_all(kbdev);
1649 }
1650
1651 /**
1652 * kbase_jd_done - Complete a job that has been removed from the Hardware
1653 * @katom: atom which has been completed
1654 * @slot_nr: slot the atom was on
1655 * @end_timestamp: completion time
1656 * @done_code: completion code
1657 *
1658 * This must be used whenever a job has been removed from the Hardware, e.g.:
1659 * An IRQ indicates that the job finished (for both error and 'done' codes), or
1660 * the job was evicted from the JS_HEAD_NEXT registers during a Soft/Hard stop.
1661 *
1662 * Some work is carried out immediately, and the rest is deferred onto a
1663 * workqueue
1664 *
1665 * Context:
1666 * This can be called safely from atomic context.
1667 * The caller must hold kbdev->hwaccess_lock
1668 */
kbase_jd_done(struct kbase_jd_atom *katom, int slot_nr, ktime_t *end_timestamp, kbasep_js_atom_done_code done_code)1669 void kbase_jd_done(struct kbase_jd_atom *katom, int slot_nr,
1670 ktime_t *end_timestamp, kbasep_js_atom_done_code done_code)
1671 {
1672 struct kbase_context *kctx;
1673 struct kbase_device *kbdev;
1674
1675 KBASE_DEBUG_ASSERT(katom);
1676 kctx = katom->kctx;
1677 KBASE_DEBUG_ASSERT(kctx);
1678 kbdev = kctx->kbdev;
1679 KBASE_DEBUG_ASSERT(kbdev);
1680
1681 if (done_code & KBASE_JS_ATOM_DONE_EVICTED_FROM_NEXT)
1682 katom->event_code = BASE_JD_EVENT_REMOVED_FROM_NEXT;
1683
1684 KBASE_KTRACE_ADD_JM(kbdev, JD_DONE, kctx, katom, katom->jc, 0);
1685
1686 kbase_job_check_leave_disjoint(kbdev, katom);
1687
1688 katom->slot_nr = slot_nr;
1689
1690 atomic_inc(&kctx->work_count);
1691
1692 #if IS_ENABLED(CONFIG_DEBUG_FS)
1693 /* a failed job happened and is waiting for dumping*/
1694 if (!katom->will_fail_event_code &&
1695 kbase_debug_job_fault_process(katom, katom->event_code))
1696 return;
1697 #endif
1698
1699 WARN_ON(work_pending(&katom->work));
1700 INIT_WORK(&katom->work, kbase_jd_done_worker);
1701 queue_work(kctx->jctx.job_done_wq, &katom->work);
1702 }
1703
1704 KBASE_EXPORT_TEST_API(kbase_jd_done);
1705
kbase_jd_cancel(struct kbase_device *kbdev, struct kbase_jd_atom *katom)1706 void kbase_jd_cancel(struct kbase_device *kbdev, struct kbase_jd_atom *katom)
1707 {
1708 struct kbase_context *kctx;
1709
1710 KBASE_DEBUG_ASSERT(kbdev != NULL);
1711 KBASE_DEBUG_ASSERT(katom != NULL);
1712 kctx = katom->kctx;
1713 KBASE_DEBUG_ASSERT(kctx != NULL);
1714
1715 dev_dbg(kbdev->dev, "JD: cancelling atom %pK\n", (void *)katom);
1716 KBASE_KTRACE_ADD_JM(kbdev, JD_CANCEL, kctx, katom, katom->jc, 0);
1717
1718 /* This should only be done from a context that is not scheduled */
1719 KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1720
1721 WARN_ON(work_pending(&katom->work));
1722
1723 katom->event_code = BASE_JD_EVENT_JOB_CANCELLED;
1724
1725 INIT_WORK(&katom->work, jd_cancel_worker);
1726 queue_work(kctx->jctx.job_done_wq, &katom->work);
1727 }
1728
1729
kbase_jd_zap_context(struct kbase_context *kctx)1730 void kbase_jd_zap_context(struct kbase_context *kctx)
1731 {
1732 struct kbase_jd_atom *katom;
1733 struct list_head *entry, *tmp;
1734 struct kbase_device *kbdev;
1735
1736 KBASE_DEBUG_ASSERT(kctx);
1737
1738 kbdev = kctx->kbdev;
1739
1740 KBASE_KTRACE_ADD_JM(kbdev, JD_ZAP_CONTEXT, kctx, NULL, 0u, 0u);
1741
1742 kbase_js_zap_context(kctx);
1743
1744 mutex_lock(&kctx->jctx.lock);
1745
1746 /*
1747 * While holding the struct kbase_jd_context lock clean up jobs which are known to kbase but are
1748 * queued outside the job scheduler.
1749 */
1750
1751 del_timer_sync(&kctx->soft_job_timeout);
1752 list_for_each_safe(entry, tmp, &kctx->waiting_soft_jobs) {
1753 katom = list_entry(entry, struct kbase_jd_atom, queue);
1754 kbase_cancel_soft_job(katom);
1755 }
1756
1757
1758 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
1759 kbase_dma_fence_cancel_all_atoms(kctx);
1760 #endif
1761
1762 mutex_unlock(&kctx->jctx.lock);
1763
1764 #ifdef CONFIG_MALI_BIFROST_DMA_FENCE
1765 /* Flush dma-fence workqueue to ensure that any callbacks that may have
1766 * been queued are done before continuing.
1767 */
1768 flush_workqueue(kctx->dma_fence.wq);
1769 #endif
1770
1771 #if IS_ENABLED(CONFIG_DEBUG_FS)
1772 kbase_debug_job_fault_kctx_unblock(kctx);
1773 #endif
1774
1775 kbase_jm_wait_for_zero_jobs(kctx);
1776 }
1777
1778 KBASE_EXPORT_TEST_API(kbase_jd_zap_context);
1779
kbase_jd_init(struct kbase_context *kctx)1780 int kbase_jd_init(struct kbase_context *kctx)
1781 {
1782 int i;
1783 int mali_err = 0;
1784 struct priority_control_manager_device *pcm_device = NULL;
1785
1786 KBASE_DEBUG_ASSERT(kctx);
1787 pcm_device = kctx->kbdev->pcm_dev;
1788 kctx->jctx.max_priority = KBASE_JS_ATOM_SCHED_PRIO_REALTIME;
1789
1790 kctx->jctx.job_done_wq = alloc_workqueue("mali_jd",
1791 WQ_HIGHPRI | WQ_UNBOUND, 1);
1792 if (kctx->jctx.job_done_wq == NULL) {
1793 mali_err = -ENOMEM;
1794 goto out1;
1795 }
1796
1797 for (i = 0; i < BASE_JD_ATOM_COUNT; i++) {
1798 init_waitqueue_head(&kctx->jctx.atoms[i].completed);
1799
1800 INIT_LIST_HEAD(&kctx->jctx.atoms[i].dep_head[0]);
1801 INIT_LIST_HEAD(&kctx->jctx.atoms[i].dep_head[1]);
1802
1803 /* Catch userspace attempting to use an atom which doesn't exist as a pre-dependency */
1804 kctx->jctx.atoms[i].event_code = BASE_JD_EVENT_JOB_INVALID;
1805 kctx->jctx.atoms[i].status = KBASE_JD_ATOM_STATE_UNUSED;
1806
1807 #if defined(CONFIG_MALI_BIFROST_DMA_FENCE) || defined(CONFIG_SYNC_FILE)
1808 kctx->jctx.atoms[i].dma_fence.context =
1809 dma_fence_context_alloc(1);
1810 atomic_set(&kctx->jctx.atoms[i].dma_fence.seqno, 0);
1811 INIT_LIST_HEAD(&kctx->jctx.atoms[i].dma_fence.callbacks);
1812 #endif
1813 }
1814
1815 for (i = 0; i < BASE_JD_RP_COUNT; i++)
1816 kctx->jctx.renderpasses[i].state = KBASE_JD_RP_COMPLETE;
1817
1818 mutex_init(&kctx->jctx.lock);
1819
1820 init_waitqueue_head(&kctx->jctx.zero_jobs_wait);
1821
1822 spin_lock_init(&kctx->jctx.tb_lock);
1823
1824 kctx->jctx.job_nr = 0;
1825 INIT_LIST_HEAD(&kctx->completed_jobs);
1826 atomic_set(&kctx->work_count, 0);
1827
1828 /* Check if there are platform rules for maximum priority */
1829 if (pcm_device)
1830 kctx->jctx.max_priority = pcm_device->ops.pcm_scheduler_priority_check(
1831 pcm_device, current, KBASE_JS_ATOM_SCHED_PRIO_REALTIME);
1832
1833 return 0;
1834
1835 out1:
1836 return mali_err;
1837 }
1838
1839 KBASE_EXPORT_TEST_API(kbase_jd_init);
1840
kbase_jd_exit(struct kbase_context *kctx)1841 void kbase_jd_exit(struct kbase_context *kctx)
1842 {
1843 KBASE_DEBUG_ASSERT(kctx);
1844
1845 /* Work queue is emptied by this */
1846 destroy_workqueue(kctx->jctx.job_done_wq);
1847 }
1848
1849 KBASE_EXPORT_TEST_API(kbase_jd_exit);
1850