hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_jm_rb.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
55 *
66 * This program is free software and is provided to you under the terms of the
77 * GNU General Public License version 2 as published by the Free Software
....@@ -29,7 +29,7 @@
2929 #include <mali_kbase_jm.h>
3030 #include <mali_kbase_js.h>
3131 #include <tl/mali_kbase_tracepoints.h>
32
-#include <mali_kbase_hwcnt_context.h>
32
+#include <hwcnt/mali_kbase_hwcnt_context.h>
3333 #include <mali_kbase_reset_gpu.h>
3434 #include <mali_kbase_kinstr_jm.h>
3535 #include <backend/gpu/mali_kbase_cache_policy_backend.h>
....@@ -37,14 +37,23 @@
3737 #include <backend/gpu/mali_kbase_jm_internal.h>
3838 #include <backend/gpu/mali_kbase_pm_internal.h>
3939
40
-/* Return whether the specified ringbuffer is empty. HW access lock must be
41
- * held
40
+/**
41
+ * SLOT_RB_EMPTY - Return whether the specified ringbuffer is empty.
42
+ *
43
+ * @rb: ring buffer
44
+ *
45
+ * Note: HW access lock must be held
4246 */
4347 #define SLOT_RB_EMPTY(rb) (rb->write_idx == rb->read_idx)
44
-/* Return number of atoms currently in the specified ringbuffer. HW access lock
45
- * must be held
48
+
49
+/**
50
+ * SLOT_RB_ENTRIES - Return number of atoms currently in the specified ringbuffer.
51
+ *
52
+ * @rb: ring buffer
53
+ *
54
+ * Note: HW access lock must be held
4655 */
47
-#define SLOT_RB_ENTRIES(rb) (int)(s8)(rb->write_idx - rb->read_idx)
56
+#define SLOT_RB_ENTRIES(rb) ((int)(s8)(rb->write_idx - rb->read_idx))
4857
4958 static void kbase_gpu_release_atom(struct kbase_device *kbdev,
5059 struct kbase_jd_atom *katom,
....@@ -84,9 +93,8 @@
8493 *
8594 * Return: Atom removed from ringbuffer
8695 */
87
-static struct kbase_jd_atom *kbase_gpu_dequeue_atom(struct kbase_device *kbdev,
88
- int js,
89
- ktime_t *end_timestamp)
96
+static struct kbase_jd_atom *kbase_gpu_dequeue_atom(struct kbase_device *kbdev, unsigned int js,
97
+ ktime_t *end_timestamp)
9098 {
9199 struct slot_rb *rb = &kbdev->hwaccess.backend.slot_rb[js];
92100 struct kbase_jd_atom *katom;
....@@ -109,8 +117,7 @@
109117 return katom;
110118 }
111119
112
-struct kbase_jd_atom *kbase_gpu_inspect(struct kbase_device *kbdev, int js,
113
- int idx)
120
+struct kbase_jd_atom *kbase_gpu_inspect(struct kbase_device *kbdev, unsigned int js, int idx)
114121 {
115122 struct slot_rb *rb = &kbdev->hwaccess.backend.slot_rb[js];
116123
....@@ -122,8 +129,7 @@
122129 return rb->entries[(rb->read_idx + idx) & SLOT_RB_MASK].katom;
123130 }
124131
125
-struct kbase_jd_atom *kbase_backend_inspect_tail(struct kbase_device *kbdev,
126
- int js)
132
+struct kbase_jd_atom *kbase_backend_inspect_tail(struct kbase_device *kbdev, unsigned int js)
127133 {
128134 struct slot_rb *rb = &kbdev->hwaccess.backend.slot_rb[js];
129135
....@@ -135,12 +141,13 @@
135141
136142 bool kbase_gpu_atoms_submitted_any(struct kbase_device *kbdev)
137143 {
138
- int js;
139
- int i;
144
+ unsigned int js;
140145
141146 lockdep_assert_held(&kbdev->hwaccess_lock);
142147
143148 for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
149
+ int i;
150
+
144151 for (i = 0; i < SLOT_RB_SIZE; i++) {
145152 struct kbase_jd_atom *katom = kbase_gpu_inspect(kbdev, js, i);
146153
....@@ -151,7 +158,7 @@
151158 return false;
152159 }
153160
154
-int kbase_backend_nr_atoms_submitted(struct kbase_device *kbdev, int js)
161
+int kbase_backend_nr_atoms_submitted(struct kbase_device *kbdev, unsigned int js)
155162 {
156163 int nr = 0;
157164 int i;
....@@ -169,7 +176,7 @@
169176 return nr;
170177 }
171178
172
-int kbase_backend_nr_atoms_on_slot(struct kbase_device *kbdev, int js)
179
+int kbase_backend_nr_atoms_on_slot(struct kbase_device *kbdev, unsigned int js)
173180 {
174181 int nr = 0;
175182 int i;
....@@ -184,8 +191,8 @@
184191 return nr;
185192 }
186193
187
-static int kbase_gpu_nr_atoms_on_slot_min(struct kbase_device *kbdev, int js,
188
- enum kbase_atom_gpu_rb_state min_rb_state)
194
+static int kbase_gpu_nr_atoms_on_slot_min(struct kbase_device *kbdev, unsigned int js,
195
+ enum kbase_atom_gpu_rb_state min_rb_state)
189196 {
190197 int nr = 0;
191198 int i;
....@@ -235,9 +242,11 @@
235242 static bool kbase_gpu_check_secure_atoms(struct kbase_device *kbdev,
236243 bool secure)
237244 {
238
- int js, i;
245
+ unsigned int js;
239246
240247 for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
248
+ int i;
249
+
241250 for (i = 0; i < SLOT_RB_SIZE; i++) {
242251 struct kbase_jd_atom *katom = kbase_gpu_inspect(kbdev,
243252 js, i);
....@@ -252,7 +261,7 @@
252261 return false;
253262 }
254263
255
-int kbase_backend_slot_free(struct kbase_device *kbdev, int js)
264
+int kbase_backend_slot_free(struct kbase_device *kbdev, unsigned int js)
256265 {
257266 lockdep_assert_held(&kbdev->hwaccess_lock);
258267
....@@ -304,10 +313,10 @@
304313 [katom->slot_nr]);
305314
306315 /* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
307
-
316
+ fallthrough;
308317 case KBASE_ATOM_GPU_RB_READY:
309318 /* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
310
-
319
+ fallthrough;
311320 case KBASE_ATOM_GPU_RB_WAITING_FOR_CORE_AVAILABLE:
312321 break;
313322
....@@ -338,16 +347,35 @@
338347 katom->protected_state.exit !=
339348 KBASE_ATOM_EXIT_PROTECTED_CHECK)
340349 kbdev->protected_mode_transition = false;
350
+
351
+ /* If the atom is at KBASE_ATOM_ENTER_PROTECTED_HWCNT state, it means
352
+ * one of two events prevented it from progressing to the next state and
353
+ * ultimately reach protected mode:
354
+ * - hwcnts were enabled, and the atom had to schedule a worker to
355
+ * disable them.
356
+ * - the hwcnts were already disabled, but some other error occurred.
357
+ * In the first case, if the worker has not yet completed
358
+ * (kbdev->protected_mode_hwcnt_disabled == false), we need to re-enable
359
+ * them and signal to the worker they have already been enabled
360
+ */
361
+ if (kbase_jd_katom_is_protected(katom) &&
362
+ (katom->protected_state.enter == KBASE_ATOM_ENTER_PROTECTED_HWCNT)) {
363
+ kbdev->protected_mode_hwcnt_desired = true;
364
+ if (kbdev->protected_mode_hwcnt_disabled) {
365
+ kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
366
+ kbdev->protected_mode_hwcnt_disabled = false;
367
+ }
368
+ }
369
+
341370 /* If the atom has suspended hwcnt but has not yet entered
342371 * protected mode, then resume hwcnt now. If the GPU is now in
343372 * protected mode then hwcnt will be resumed by GPU reset so
344373 * don't resume it here.
345374 */
346375 if (kbase_jd_katom_is_protected(katom) &&
347
- ((katom->protected_state.enter ==
348
- KBASE_ATOM_ENTER_PROTECTED_IDLE_L2) ||
349
- (katom->protected_state.enter ==
350
- KBASE_ATOM_ENTER_PROTECTED_SET_COHERENCY))) {
376
+ ((katom->protected_state.enter == KBASE_ATOM_ENTER_PROTECTED_IDLE_L2) ||
377
+ (katom->protected_state.enter == KBASE_ATOM_ENTER_PROTECTED_SET_COHERENCY) ||
378
+ (katom->protected_state.enter == KBASE_ATOM_ENTER_PROTECTED_FINISHED))) {
351379 WARN_ON(!kbdev->protected_mode_hwcnt_disabled);
352380 kbdev->protected_mode_hwcnt_desired = true;
353381 if (kbdev->protected_mode_hwcnt_disabled) {
....@@ -367,13 +395,13 @@
367395 }
368396
369397 /* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
370
-
398
+ fallthrough;
371399 case KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_PREV:
372400 /* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
373
-
401
+ fallthrough;
374402 case KBASE_ATOM_GPU_RB_WAITING_BLOCKED:
375403 /* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
376
-
404
+ fallthrough;
377405 case KBASE_ATOM_GPU_RB_RETURN_TO_JS:
378406 break;
379407 }
....@@ -387,6 +415,9 @@
387415 {
388416 lockdep_assert_held(&kbdev->hwaccess_lock);
389417
418
+ KBASE_KTRACE_ADD_JM_SLOT_INFO(kbdev, JM_MARK_FOR_RETURN_TO_JS,
419
+ katom->kctx, katom, katom->jc,
420
+ katom->slot_nr, katom->event_code);
390421 kbase_gpu_release_atom(kbdev, katom, NULL);
391422 katom->gpu_rb_state = KBASE_ATOM_GPU_RB_RETURN_TO_JS;
392423 }
....@@ -399,9 +430,9 @@
399430 *
400431 * Return: true if any slots other than @js are busy, false otherwise
401432 */
402
-static inline bool other_slots_busy(struct kbase_device *kbdev, int js)
433
+static inline bool other_slots_busy(struct kbase_device *kbdev, unsigned int js)
403434 {
404
- int slot;
435
+ unsigned int slot;
405436
406437 for (slot = 0; slot < kbdev->gpu_props.num_job_slots; slot++) {
407438 if (slot == js)
....@@ -495,17 +526,14 @@
495526 KBASE_TLSTREAM_AUX_PROTECTED_ENTER_END(kbdev, kbdev);
496527 if (err) {
497528 /*
498
- * Failed to switch into protected mode, resume
499
- * GPU hwcnt and fail atom.
529
+ * Failed to switch into protected mode.
530
+ *
531
+ * At this point we expect:
532
+ * katom->gpu_rb_state = KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_TRANSITION &&
533
+ * katom->protected_state.enter = KBASE_ATOM_ENTER_PROTECTED_FINISHED
534
+ * ==>
535
+ * kbdev->protected_mode_hwcnt_disabled = false
500536 */
501
- WARN_ON(!kbdev->protected_mode_hwcnt_disabled);
502
- kbdev->protected_mode_hwcnt_desired = true;
503
- if (kbdev->protected_mode_hwcnt_disabled) {
504
- kbase_hwcnt_context_enable(
505
- kbdev->hwcnt_gpu_ctx);
506
- kbdev->protected_mode_hwcnt_disabled = false;
507
- }
508
-
509537 katom[idx]->event_code = BASE_JD_EVENT_JOB_INVALID;
510538 kbase_gpu_mark_atom_for_return(kbdev, katom[idx]);
511539 /*
....@@ -525,12 +553,9 @@
525553 /*
526554 * Protected mode sanity checks.
527555 */
528
- KBASE_DEBUG_ASSERT_MSG(
529
- kbase_jd_katom_is_protected(katom[idx]) ==
530
- kbase_gpu_in_protected_mode(kbdev),
531
- "Protected mode of atom (%d) doesn't match protected mode of GPU (%d)",
532
- kbase_jd_katom_is_protected(katom[idx]),
533
- kbase_gpu_in_protected_mode(kbdev));
556
+ WARN(kbase_jd_katom_is_protected(katom[idx]) != kbase_gpu_in_protected_mode(kbdev),
557
+ "Protected mode of atom (%d) doesn't match protected mode of GPU (%d)",
558
+ kbase_jd_katom_is_protected(katom[idx]), kbase_gpu_in_protected_mode(kbdev));
534559 katom[idx]->gpu_rb_state =
535560 KBASE_ATOM_GPU_RB_READY;
536561
....@@ -564,7 +589,7 @@
564589 kbdev->protected_mode_transition = true;
565590
566591 /* ***TRANSITION TO HIGHER STATE*** */
567
- /* fallthrough */
592
+ fallthrough;
568593 case KBASE_ATOM_ENTER_PROTECTED_HWCNT:
569594 /* See if we can get away with disabling hwcnt atomically */
570595 kbdev->protected_mode_hwcnt_desired = false;
....@@ -607,7 +632,7 @@
607632 kbase_pm_update_cores_state_nolock(kbdev);
608633
609634 /* ***TRANSITION TO HIGHER STATE*** */
610
- /* fallthrough */
635
+ fallthrough;
611636 case KBASE_ATOM_ENTER_PROTECTED_IDLE_L2:
612637 /* Avoid unnecessary waiting on non-ACE platforms. */
613638 if (kbdev->system_coherency == COHERENCY_ACE) {
....@@ -638,7 +663,7 @@
638663 KBASE_ATOM_ENTER_PROTECTED_SET_COHERENCY;
639664
640665 /* ***TRANSITION TO HIGHER STATE*** */
641
- /* fallthrough */
666
+ fallthrough;
642667 case KBASE_ATOM_ENTER_PROTECTED_SET_COHERENCY:
643668 /*
644669 * When entering into protected mode, we must ensure that the
....@@ -671,7 +696,7 @@
671696 return -EAGAIN;
672697
673698 /* ***TRANSITION TO HIGHER STATE*** */
674
- /* fallthrough */
699
+ fallthrough;
675700 case KBASE_ATOM_ENTER_PROTECTED_FINISHED:
676701 if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TGOX_R1_1234)) {
677702 /*
....@@ -742,7 +767,7 @@
742767 kbase_pm_update_cores_state_nolock(kbdev);
743768
744769 /* ***TRANSITION TO HIGHER STATE*** */
745
- /* fallthrough */
770
+ fallthrough;
746771 case KBASE_ATOM_EXIT_PROTECTED_IDLE_L2:
747772 if (kbdev->pm.backend.l2_state != KBASE_L2_OFF) {
748773 /*
....@@ -755,8 +780,15 @@
755780 KBASE_ATOM_EXIT_PROTECTED_RESET;
756781
757782 /* ***TRANSITION TO HIGHER STATE*** */
758
- /* fallthrough */
783
+ fallthrough;
759784 case KBASE_ATOM_EXIT_PROTECTED_RESET:
785
+ /* L2 cache has been turned off (which is needed prior to the reset of GPU
786
+ * to exit the protected mode), so the override flag can be safely cleared.
787
+ * Even if L2 cache is powered up again before the actual reset, it should
788
+ * not be an issue (there are no jobs running on the GPU).
789
+ */
790
+ kbase_pm_protected_override_disable(kbdev);
791
+
760792 /* Issue the reset to the GPU */
761793 err = kbase_gpu_protected_mode_reset(kbdev);
762794
....@@ -765,7 +797,6 @@
765797
766798 if (err) {
767799 kbdev->protected_mode_transition = false;
768
- kbase_pm_protected_override_disable(kbdev);
769800
770801 /* Failed to exit protected mode, fail atom */
771802 katom[idx]->event_code = BASE_JD_EVENT_JOB_INVALID;
....@@ -797,7 +828,7 @@
797828 KBASE_ATOM_EXIT_PROTECTED_RESET_WAIT;
798829
799830 /* ***TRANSITION TO HIGHER STATE*** */
800
- /* fallthrough */
831
+ fallthrough;
801832 case KBASE_ATOM_EXIT_PROTECTED_RESET_WAIT:
802833 /* A GPU reset is issued when exiting protected mode. Once the
803834 * reset is done all atoms' state will also be reset. For this
....@@ -813,7 +844,7 @@
813844
814845 void kbase_backend_slot_update(struct kbase_device *kbdev)
815846 {
816
- int js;
847
+ unsigned int js;
817848
818849 lockdep_assert_held(&kbdev->hwaccess_lock);
819850
....@@ -854,7 +885,7 @@
854885 KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_PREV;
855886
856887 /* ***TRANSITION TO HIGHER STATE*** */
857
- /* fallthrough */
888
+ fallthrough;
858889 case KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_PREV:
859890 if (kbase_gpu_check_secure_atoms(kbdev,
860891 !kbase_jd_katom_is_protected(
....@@ -874,7 +905,7 @@
874905 KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_TRANSITION;
875906
876907 /* ***TRANSITION TO HIGHER STATE*** */
877
- /* fallthrough */
908
+ fallthrough;
878909 case KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_TRANSITION:
879910
880911 /*
....@@ -909,7 +940,7 @@
909940 KBASE_ATOM_GPU_RB_WAITING_FOR_CORE_AVAILABLE;
910941
911942 /* ***TRANSITION TO HIGHER STATE*** */
912
- /* fallthrough */
943
+ fallthrough;
913944 case KBASE_ATOM_GPU_RB_WAITING_FOR_CORE_AVAILABLE:
914945 if (katom[idx]->will_fail_event_code) {
915946 kbase_gpu_mark_atom_for_return(kbdev,
....@@ -934,13 +965,6 @@
934965 cores_ready = kbase_pm_cores_requested(kbdev,
935966 true);
936967
937
- if (katom[idx]->event_code ==
938
- BASE_JD_EVENT_PM_EVENT) {
939
- katom[idx]->gpu_rb_state =
940
- KBASE_ATOM_GPU_RB_RETURN_TO_JS;
941
- break;
942
- }
943
-
944968 if (!cores_ready)
945969 break;
946970
....@@ -948,7 +972,7 @@
948972 KBASE_ATOM_GPU_RB_READY;
949973
950974 /* ***TRANSITION TO HIGHER STATE*** */
951
- /* fallthrough */
975
+ fallthrough;
952976 case KBASE_ATOM_GPU_RB_READY:
953977
954978 if (idx == 1) {
....@@ -977,36 +1001,34 @@
9771001 other_slots_busy(kbdev, js))
9781002 break;
9791003
980
-#ifdef CONFIG_MALI_GEM5_BUILD
981
- if (!kbasep_jm_is_js_free(kbdev, js,
982
- katom[idx]->kctx))
983
- break;
984
-#endif
9851004 /* Check if this job needs the cycle counter
9861005 * enabled before submission
9871006 */
9881007 if (katom[idx]->core_req & BASE_JD_REQ_PERMON)
989
- kbase_pm_request_gpu_cycle_counter_l2_is_on(
990
- kbdev);
1008
+ kbase_pm_request_gpu_cycle_counter_l2_is_on(kbdev);
9911009
992
- kbase_job_hw_submit(kbdev, katom[idx], js);
993
- katom[idx]->gpu_rb_state =
994
- KBASE_ATOM_GPU_RB_SUBMITTED;
1010
+ if (!kbase_job_hw_submit(kbdev, katom[idx], js)) {
1011
+ katom[idx]->gpu_rb_state = KBASE_ATOM_GPU_RB_SUBMITTED;
1012
+
1013
+ /* Inform power management at start/finish of
1014
+ * atom so it can update its GPU utilisation
1015
+ * metrics.
1016
+ */
1017
+ kbase_pm_metrics_update(kbdev,
1018
+ &katom[idx]->start_timestamp);
1019
+
1020
+ /* Inform platform at start/finish of atom */
1021
+ kbasep_platform_event_atom_submit(katom[idx]);
1022
+ } else {
1023
+ if (katom[idx]->core_req & BASE_JD_REQ_PERMON)
1024
+ kbase_pm_release_gpu_cycle_counter_nolock(kbdev);
1025
+
1026
+ break;
1027
+ }
9951028
9961029 /* ***TRANSITION TO HIGHER STATE*** */
997
- /* fallthrough */
1030
+ fallthrough;
9981031 case KBASE_ATOM_GPU_RB_SUBMITTED:
999
-
1000
- /* Inform power management at start/finish of
1001
- * atom so it can update its GPU utilisation
1002
- * metrics.
1003
- */
1004
- kbase_pm_metrics_update(kbdev,
1005
- &katom[idx]->start_timestamp);
1006
-
1007
- /* Inform platform at start/finish of atom */
1008
- kbasep_platform_event_atom_submit(katom[idx]);
1009
-
10101032 break;
10111033
10121034 case KBASE_ATOM_GPU_RB_RETURN_TO_JS:
....@@ -1037,11 +1059,56 @@
10371059 kbase_backend_slot_update(kbdev);
10381060 }
10391061
1040
-#define HAS_DEP(katom) (katom->pre_dep || katom->atom_flags & \
1041
- (KBASE_KATOM_FLAG_X_DEP_BLOCKED | KBASE_KATOM_FLAG_FAIL_BLOCKER))
1062
+/**
1063
+ * kbase_rb_atom_might_depend - determine if one atom in the slot ringbuffer
1064
+ * might depend on another from the same kctx
1065
+ * @katom_a: dependee atom
1066
+ * @katom_b: atom to query
1067
+ *
1068
+ * This can be used on atoms that belong to different slot ringbuffers
1069
+ *
1070
+ * Return: true if @katom_b might depend on @katom_a, false if it cannot depend.
1071
+ */
1072
+static inline bool
1073
+kbase_rb_atom_might_depend(const struct kbase_jd_atom *katom_a,
1074
+ const struct kbase_jd_atom *katom_b)
1075
+{
1076
+ if (katom_a->kctx != katom_b->kctx)
1077
+ return false;
1078
+ return (katom_b->pre_dep ||
1079
+ (katom_b->atom_flags & (KBASE_KATOM_FLAG_X_DEP_BLOCKED |
1080
+ KBASE_KATOM_FLAG_FAIL_BLOCKER)));
1081
+}
10421082
1043
-bool kbase_gpu_irq_evict(struct kbase_device *kbdev, int js,
1044
- u32 completion_code)
1083
+/**
1084
+ * kbase_gpu_irq_evict - evict a slot's JSn_HEAD_NEXT atom from the HW if it is
1085
+ * related to a failed JSn_HEAD atom
1086
+ * @kbdev: kbase device
1087
+ * @js: job slot to check
1088
+ * @completion_code: completion code of the failed atom
1089
+ *
1090
+ * Note: 'STOPPED' atoms are considered 'failed', as they are in the HW, but
1091
+ * unlike other failure codes we _can_ re-run them.
1092
+ *
1093
+ * This forms step 1 in a 2-step process of removing any related atoms from a
1094
+ * slot's JSn_HEAD_NEXT (ringbuffer index 1), should there have
1095
+ * been a 'failure' on an atom in JSn_HEAD (ringbuffer index 0).
1096
+ *
1097
+ * This step only removes the atoms from the HW, and marks them as
1098
+ * (potentially) ready to run again.
1099
+ *
1100
+ * Step 2 is on marking the JSn_HEAD atom as complete
1101
+ * (kbase_gpu_complete_hw()), to dequeue said atoms and return them to the JS
1102
+ * as appropriate, or re-submit them.
1103
+ *
1104
+ * Hence, this function must evict at a minimum the atoms related to the atom
1105
+ * in JSn_HEAD that kbase_gpu_complete_hw() will also dequeue. It is acceptable
1106
+ * if this function evicts more atoms than kbase_gpu_complete_hw() dequeues, as
1107
+ * the next kbase_backend_slot_update() will resubmit any remaining.
1108
+ *
1109
+ * Return: true if an atom was evicted, false otherwise.
1110
+ */
1111
+bool kbase_gpu_irq_evict(struct kbase_device *kbdev, unsigned int js, u32 completion_code)
10451112 {
10461113 struct kbase_jd_atom *katom;
10471114 struct kbase_jd_atom *next_katom;
....@@ -1049,16 +1116,18 @@
10491116 lockdep_assert_held(&kbdev->hwaccess_lock);
10501117
10511118 katom = kbase_gpu_inspect(kbdev, js, 0);
1119
+ if (!katom) {
1120
+ dev_err(kbdev->dev, "Can't get a katom from js(%u)\n", js);
1121
+ return false;
1122
+ }
10521123 next_katom = kbase_gpu_inspect(kbdev, js, 1);
10531124
1054
- if (next_katom && katom->kctx == next_katom->kctx &&
1055
- next_katom->gpu_rb_state == KBASE_ATOM_GPU_RB_SUBMITTED &&
1056
- (HAS_DEP(next_katom) || next_katom->sched_priority ==
1057
- katom->sched_priority) &&
1058
- (kbase_reg_read(kbdev, JOB_SLOT_REG(js, JS_HEAD_NEXT_LO))
1059
- != 0 ||
1060
- kbase_reg_read(kbdev, JOB_SLOT_REG(js, JS_HEAD_NEXT_HI))
1061
- != 0)) {
1125
+ if (next_katom &&
1126
+ next_katom->gpu_rb_state == KBASE_ATOM_GPU_RB_SUBMITTED &&
1127
+ (kbase_rb_atom_might_depend(katom, next_katom) ||
1128
+ kbase_js_atom_runs_before(kbdev, katom, next_katom, 0u)) &&
1129
+ (kbase_reg_read(kbdev, JOB_SLOT_REG(js, JS_HEAD_NEXT_LO)) != 0 ||
1130
+ kbase_reg_read(kbdev, JOB_SLOT_REG(js, JS_HEAD_NEXT_HI)) != 0)) {
10621131 kbase_reg_write(kbdev, JOB_SLOT_REG(js, JS_COMMAND_NEXT),
10631132 JS_COMMAND_NOP);
10641133 next_katom->gpu_rb_state = KBASE_ATOM_GPU_RB_READY;
....@@ -1077,19 +1146,56 @@
10771146 if (next_katom->core_req & BASE_JD_REQ_PERMON)
10781147 kbase_pm_release_gpu_cycle_counter_nolock(kbdev);
10791148
1149
+ /* On evicting the next_katom, the last submission kctx on the
1150
+ * given job slot then reverts back to the one that owns katom.
1151
+ * The aim is to enable the next submission that can determine
1152
+ * if the read only shader core L1 cache should be invalidated.
1153
+ */
1154
+ kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged =
1155
+ SLOT_RB_TAG_KCTX(katom->kctx);
1156
+
10801157 return true;
10811158 }
10821159
10831160 return false;
10841161 }
10851162
1086
-void kbase_gpu_complete_hw(struct kbase_device *kbdev, int js,
1087
- u32 completion_code,
1088
- u64 job_tail,
1089
- ktime_t *end_timestamp)
1163
+/**
1164
+ * kbase_gpu_complete_hw - complete the atom in a slot's JSn_HEAD
1165
+ * @kbdev: kbase device
1166
+ * @js: job slot to check
1167
+ * @completion_code: completion code of the completed atom
1168
+ * @job_tail: value read from JSn_TAIL, for STOPPED atoms
1169
+ * @end_timestamp: pointer to approximate ktime value when the katom completed
1170
+ *
1171
+ * Among other operations, this also executes step 2 of a 2-step process of
1172
+ * removing any related atoms from a slot's JSn_HEAD_NEXT (ringbuffer index 1),
1173
+ * should there have been a 'failure' on an atom in JSn_HEAD (ringbuffer index
1174
+ * 0). The first step is done in kbase_gpu_irq_evict().
1175
+ *
1176
+ * Note: 'STOPPED' atoms are considered 'failed', as they are in the HW, but
1177
+ * unlike other failure codes we _can_ re-run them.
1178
+ *
1179
+ * When the JSn_HEAD atom is considered to be 'failed', then this will dequeue
1180
+ * and return to the JS some (usually all) of the atoms evicted from the HW
1181
+ * during the kbase_gpu_irq_evict() for that JSn_HEAD atom. If it dequeues an
1182
+ * atom, that atom must not have been running or must already be evicted, as
1183
+ * otherwise we would be in the incorrect state of having an atom both running
1184
+ * on the HW and returned to the JS.
1185
+ */
1186
+
1187
+void kbase_gpu_complete_hw(struct kbase_device *kbdev, unsigned int js, u32 completion_code,
1188
+ u64 job_tail, ktime_t *end_timestamp)
10901189 {
10911190 struct kbase_jd_atom *katom = kbase_gpu_inspect(kbdev, js, 0);
1092
- struct kbase_context *kctx = katom->kctx;
1191
+ struct kbase_context *kctx = NULL;
1192
+
1193
+ if (unlikely(!katom)) {
1194
+ dev_err(kbdev->dev, "Can't get a katom from js(%d)\n", js);
1195
+ return;
1196
+ }
1197
+
1198
+ kctx = katom->kctx;
10931199
10941200 dev_dbg(kbdev->dev,
10951201 "Atom %pK completed on hw with code 0x%x and job_tail 0x%llx (s:%d)\n",
....@@ -1133,9 +1239,8 @@
11331239 * registers by kbase_gpu_soft_hard_stop_slot(), to ensure that
11341240 * the atoms on this slot are returned in the correct order.
11351241 */
1136
- if (next_katom && katom->kctx == next_katom->kctx &&
1137
- next_katom->sched_priority ==
1138
- katom->sched_priority) {
1242
+ if (next_katom &&
1243
+ kbase_js_atom_runs_before(kbdev, katom, next_katom, 0u)) {
11391244 WARN_ON(next_katom->gpu_rb_state ==
11401245 KBASE_ATOM_GPU_RB_SUBMITTED);
11411246 kbase_gpu_dequeue_atom(kbdev, js, end_timestamp);
....@@ -1143,13 +1248,15 @@
11431248 }
11441249 } else if (completion_code != BASE_JD_EVENT_DONE) {
11451250 struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
1146
- int i;
1251
+ unsigned int i;
11471252
1148
- if (!kbase_ctx_flag(katom->kctx, KCTX_DYING))
1253
+ if (!kbase_ctx_flag(katom->kctx, KCTX_DYING)) {
11491254 dev_warn(kbdev->dev, "error detected from slot %d, job status 0x%08x (%s)",
11501255 js, completion_code,
11511256 kbase_gpu_exception_name(
11521257 completion_code));
1258
+
1259
+ }
11531260
11541261 #if KBASE_KTRACE_DUMP_ON_JOB_SLOT_ERROR != 0
11551262 KBASE_KTRACE_DUMP(kbdev);
....@@ -1168,18 +1275,17 @@
11681275 struct kbase_jd_atom *katom_idx1 =
11691276 kbase_gpu_inspect(kbdev, i, 1);
11701277
1171
- if (katom_idx0 && katom_idx0->kctx == katom->kctx &&
1172
- HAS_DEP(katom_idx0) &&
1173
- katom_idx0->gpu_rb_state !=
1174
- KBASE_ATOM_GPU_RB_SUBMITTED) {
1278
+ if (katom_idx0 &&
1279
+ kbase_rb_atom_might_depend(katom, katom_idx0) &&
1280
+ katom_idx0->gpu_rb_state !=
1281
+ KBASE_ATOM_GPU_RB_SUBMITTED) {
11751282 /* Dequeue katom_idx0 from ringbuffer */
11761283 kbase_gpu_dequeue_atom(kbdev, i, end_timestamp);
11771284
1178
- if (katom_idx1 &&
1179
- katom_idx1->kctx == katom->kctx
1180
- && HAS_DEP(katom_idx1) &&
1181
- katom_idx0->gpu_rb_state !=
1182
- KBASE_ATOM_GPU_RB_SUBMITTED) {
1285
+ if (katom_idx1 && kbase_rb_atom_might_depend(
1286
+ katom, katom_idx1) &&
1287
+ katom_idx0->gpu_rb_state !=
1288
+ KBASE_ATOM_GPU_RB_SUBMITTED) {
11831289 /* Dequeue katom_idx1 from ringbuffer */
11841290 kbase_gpu_dequeue_atom(kbdev, i,
11851291 end_timestamp);
....@@ -1192,11 +1298,10 @@
11921298 katom_idx0->event_code = BASE_JD_EVENT_STOPPED;
11931299 kbase_jm_return_atom_to_js(kbdev, katom_idx0);
11941300
1195
- } else if (katom_idx1 &&
1196
- katom_idx1->kctx == katom->kctx &&
1197
- HAS_DEP(katom_idx1) &&
1198
- katom_idx1->gpu_rb_state !=
1199
- KBASE_ATOM_GPU_RB_SUBMITTED) {
1301
+ } else if (katom_idx1 && kbase_rb_atom_might_depend(
1302
+ katom, katom_idx1) &&
1303
+ katom_idx1->gpu_rb_state !=
1304
+ KBASE_ATOM_GPU_RB_SUBMITTED) {
12001305 /* Can not dequeue this atom yet - will be
12011306 * dequeued when atom at idx0 completes
12021307 */
....@@ -1248,17 +1353,12 @@
12481353 ktime_to_ns(*end_timestamp),
12491354 (u32)next_katom->kctx->id, 0,
12501355 next_katom->work_id);
1251
- kbdev->hwaccess.backend.slot_rb[js].last_context =
1252
- next_katom->kctx;
12531356 } else {
12541357 char js_string[16];
12551358
1256
- trace_gpu_sched_switch(kbasep_make_job_slot_string(js,
1257
- js_string,
1258
- sizeof(js_string)),
1259
- ktime_to_ns(ktime_get()), 0, 0,
1260
- 0);
1261
- kbdev->hwaccess.backend.slot_rb[js].last_context = 0;
1359
+ trace_gpu_sched_switch(kbasep_make_job_slot_string(js, js_string,
1360
+ sizeof(js_string)),
1361
+ ktime_to_ns(ktime_get_raw()), 0, 0, 0);
12621362 }
12631363 }
12641364 #endif
....@@ -1293,7 +1393,7 @@
12931393
12941394 void kbase_backend_reset(struct kbase_device *kbdev, ktime_t *end_timestamp)
12951395 {
1296
- int js;
1396
+ unsigned int js;
12971397
12981398 lockdep_assert_held(&kbdev->hwaccess_lock);
12991399
....@@ -1314,14 +1414,14 @@
13141414 if (katom->protected_state.exit ==
13151415 KBASE_ATOM_EXIT_PROTECTED_RESET_WAIT) {
13161416 /* protected mode sanity checks */
1317
- KBASE_DEBUG_ASSERT_MSG(
1318
- kbase_jd_katom_is_protected(katom) == kbase_gpu_in_protected_mode(kbdev),
1319
- "Protected mode of atom (%d) doesn't match protected mode of GPU (%d)",
1320
- kbase_jd_katom_is_protected(katom), kbase_gpu_in_protected_mode(kbdev));
1321
- KBASE_DEBUG_ASSERT_MSG(
1322
- (kbase_jd_katom_is_protected(katom) && js == 0) ||
1323
- !kbase_jd_katom_is_protected(katom),
1324
- "Protected atom on JS%d not supported", js);
1417
+ WARN(kbase_jd_katom_is_protected(katom) !=
1418
+ kbase_gpu_in_protected_mode(kbdev),
1419
+ "Protected mode of atom (%d) doesn't match protected mode of GPU (%d)",
1420
+ kbase_jd_katom_is_protected(katom),
1421
+ kbase_gpu_in_protected_mode(kbdev));
1422
+ WARN(!(kbase_jd_katom_is_protected(katom) && js == 0) &&
1423
+ kbase_jd_katom_is_protected(katom),
1424
+ "Protected atom on JS%u not supported", js);
13251425 }
13261426 if ((katom->gpu_rb_state < KBASE_ATOM_GPU_RB_SUBMITTED) &&
13271427 !kbase_ctx_flag(katom->kctx, KCTX_DYING))
....@@ -1352,6 +1452,9 @@
13521452 katom->event_code = BASE_JD_EVENT_JOB_CANCELLED;
13531453 kbase_jm_complete(kbdev, katom, end_timestamp);
13541454 }
1455
+
1456
+ /* Clear the slot's last katom submission kctx on reset */
1457
+ kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged = SLOT_RB_NULL_TAG_VAL;
13551458 }
13561459
13571460 /* Re-enable GPU hardware counters if we're resetting from protected
....@@ -1369,17 +1472,61 @@
13691472 kbase_pm_protected_override_disable(kbdev);
13701473 }
13711474
1372
-static inline void kbase_gpu_stop_atom(struct kbase_device *kbdev,
1373
- int js,
1374
- struct kbase_jd_atom *katom,
1375
- u32 action)
1475
+/**
1476
+ * should_stop_next_atom - given a soft/hard stop action, determine if the next
1477
+ * atom on a slot should be stopped
1478
+ * @kbdev: kbase devices
1479
+ * @head_katom: atom currently in the JSn_HEAD
1480
+ * @next_katom: atom currently in the JSn_HEAD_NEXT
1481
+ * @action: JS_COMMAND_<...> action for soft/hard-stop
1482
+ *
1483
+ * This is used in cases where @head_katom is the target of the soft/hard-stop.
1484
+ * It only makes sense to call this when @head_katom and @next_katom are from
1485
+ * the same slot.
1486
+ *
1487
+ * Return: true if @next_katom should also be stopped with the given action,
1488
+ * false otherwise
1489
+ */
1490
+static bool should_stop_next_atom(struct kbase_device *kbdev,
1491
+ const struct kbase_jd_atom *head_katom,
1492
+ const struct kbase_jd_atom *next_katom,
1493
+ u32 action)
13761494 {
1495
+ bool ret = false;
1496
+ u32 hw_action = action & JS_COMMAND_MASK;
1497
+
1498
+ switch (hw_action) {
1499
+ case JS_COMMAND_SOFT_STOP:
1500
+ ret = kbase_js_atom_runs_before(kbdev, head_katom, next_katom,
1501
+ 0u);
1502
+ break;
1503
+ case JS_COMMAND_HARD_STOP:
1504
+ /* Unlike soft-stop, a hard-stop targeting a particular atom
1505
+ * should not cause atoms from unrelated contexts to be
1506
+ * removed
1507
+ */
1508
+ ret = (head_katom->kctx == next_katom->kctx);
1509
+ break;
1510
+ default:
1511
+ /* Other stop actions are possible, but the driver should not
1512
+ * be generating them at this point in the call chain
1513
+ */
1514
+ WARN(1, "Unexpected stop action: 0x%.8x", hw_action);
1515
+ break;
1516
+ }
1517
+ return ret;
1518
+}
1519
+
1520
+static inline void kbase_gpu_stop_atom(struct kbase_device *kbdev, unsigned int js,
1521
+ struct kbase_jd_atom *katom, u32 action)
1522
+{
1523
+ struct kbase_context *kctx = katom->kctx;
13771524 u32 hw_action = action & JS_COMMAND_MASK;
13781525
13791526 kbase_job_check_enter_disjoint(kbdev, action, katom->core_req, katom);
13801527 kbasep_job_slot_soft_or_hard_stop_do_action(kbdev, js, hw_action,
13811528 katom->core_req, katom);
1382
- katom->kctx->blocked_js[js][katom->sched_priority] = true;
1529
+ kbase_jsctx_slot_prio_blocked_set(kctx, js, katom->sched_priority);
13831530 }
13841531
13851532 static inline void kbase_gpu_remove_atom(struct kbase_device *kbdev,
....@@ -1387,11 +1534,14 @@
13871534 u32 action,
13881535 bool disjoint)
13891536 {
1537
+ struct kbase_context *kctx = katom->kctx;
1538
+
13901539 lockdep_assert_held(&kbdev->hwaccess_lock);
13911540
13921541 katom->event_code = BASE_JD_EVENT_REMOVED_FROM_NEXT;
13931542 kbase_gpu_mark_atom_for_return(kbdev, katom);
1394
- katom->kctx->blocked_js[katom->slot_nr][katom->sched_priority] = true;
1543
+ kbase_jsctx_slot_prio_blocked_set(kctx, katom->slot_nr,
1544
+ katom->sched_priority);
13951545
13961546 if (disjoint)
13971547 kbase_job_check_enter_disjoint(kbdev, action, katom->core_req,
....@@ -1412,14 +1562,13 @@
14121562 return -1;
14131563 }
14141564
1415
-bool kbase_backend_soft_hard_stop_slot(struct kbase_device *kbdev,
1416
- struct kbase_context *kctx,
1417
- int js,
1418
- struct kbase_jd_atom *katom,
1419
- u32 action)
1565
+bool kbase_backend_soft_hard_stop_slot(struct kbase_device *kbdev, struct kbase_context *kctx,
1566
+ unsigned int js, struct kbase_jd_atom *katom, u32 action)
14201567 {
14211568 struct kbase_jd_atom *katom_idx0;
1569
+ struct kbase_context *kctx_idx0 = NULL;
14221570 struct kbase_jd_atom *katom_idx1;
1571
+ struct kbase_context *kctx_idx1 = NULL;
14231572
14241573 bool katom_idx0_valid, katom_idx1_valid;
14251574
....@@ -1433,31 +1582,32 @@
14331582 katom_idx0 = kbase_gpu_inspect(kbdev, js, 0);
14341583 katom_idx1 = kbase_gpu_inspect(kbdev, js, 1);
14351584
1436
- if (katom_idx0)
1585
+ if (katom_idx0) {
1586
+ kctx_idx0 = katom_idx0->kctx;
14371587 prio_idx0 = katom_idx0->sched_priority;
1438
- if (katom_idx1)
1588
+ }
1589
+ if (katom_idx1) {
1590
+ kctx_idx1 = katom_idx1->kctx;
14391591 prio_idx1 = katom_idx1->sched_priority;
1592
+ }
14401593
14411594 if (katom) {
14421595 katom_idx0_valid = (katom_idx0 == katom);
1443
- /* If idx0 is to be removed and idx1 is on the same context,
1444
- * then idx1 must also be removed otherwise the atoms might be
1445
- * returned out of order
1446
- */
14471596 if (katom_idx1)
1448
- katom_idx1_valid = (katom_idx1 == katom) ||
1449
- (katom_idx0_valid &&
1450
- (katom_idx0->kctx ==
1451
- katom_idx1->kctx));
1597
+ katom_idx1_valid = (katom_idx1 == katom);
14521598 else
14531599 katom_idx1_valid = false;
14541600 } else {
1455
- katom_idx0_valid = (katom_idx0 &&
1456
- (!kctx || katom_idx0->kctx == kctx));
1457
- katom_idx1_valid = (katom_idx1 &&
1458
- (!kctx || katom_idx1->kctx == kctx) &&
1459
- prio_idx0 == prio_idx1);
1601
+ katom_idx0_valid = (katom_idx0 && (!kctx || kctx_idx0 == kctx));
1602
+ katom_idx1_valid = (katom_idx1 && (!kctx || kctx_idx1 == kctx));
14601603 }
1604
+ /* If there's an atom in JSn_HEAD_NEXT that we haven't already decided
1605
+ * to stop, but we're stopping the JSn_HEAD atom, see if they are
1606
+ * related/ordered in some way that would require the same stop action
1607
+ */
1608
+ if (!katom_idx1_valid && katom_idx0_valid && katom_idx1)
1609
+ katom_idx1_valid = should_stop_next_atom(kbdev, katom_idx0,
1610
+ katom_idx1, action);
14611611
14621612 if (katom_idx0_valid)
14631613 stop_x_dep_idx0 = should_stop_x_dep_slot(katom_idx0);
....@@ -1473,14 +1623,15 @@
14731623 katom_idx1->event_code =
14741624 BASE_JD_EVENT_REMOVED_FROM_NEXT;
14751625 kbase_jm_return_atom_to_js(kbdev, katom_idx1);
1476
- katom_idx1->kctx->blocked_js[js][prio_idx1] =
1477
- true;
1626
+ kbase_jsctx_slot_prio_blocked_set(kctx_idx1, js,
1627
+ prio_idx1);
14781628 }
14791629
14801630 katom_idx0->event_code =
14811631 BASE_JD_EVENT_REMOVED_FROM_NEXT;
14821632 kbase_jm_return_atom_to_js(kbdev, katom_idx0);
1483
- katom_idx0->kctx->blocked_js[js][prio_idx0] = true;
1633
+ kbase_jsctx_slot_prio_blocked_set(kctx_idx0, js,
1634
+ prio_idx0);
14841635 } else {
14851636 /* katom_idx0 is on GPU */
14861637 if (katom_idx1_valid && katom_idx1->gpu_rb_state ==
....@@ -1521,6 +1672,11 @@
15211672 kbase_gpu_remove_atom(kbdev,
15221673 katom_idx1,
15231674 action, true);
1675
+ /* Revert the last_context. */
1676
+ kbdev->hwaccess.backend.slot_rb[js]
1677
+ .last_kctx_tagged =
1678
+ SLOT_RB_TAG_KCTX(katom_idx0->kctx);
1679
+
15241680 stop_x_dep_idx1 =
15251681 should_stop_x_dep_slot(katom_idx1);
15261682
....@@ -1596,6 +1752,10 @@
15961752 kbase_gpu_remove_atom(kbdev, katom_idx1,
15971753 action,
15981754 false);
1755
+ /* Revert the last_context, or mark as purged */
1756
+ kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged =
1757
+ kctx_idx0 ? SLOT_RB_TAG_KCTX(katom_idx0->kctx) :
1758
+ SLOT_RB_TAG_PURGED;
15991759 } else {
16001760 /* idx0 has already completed - stop
16011761 * idx1
....@@ -1625,7 +1785,8 @@
16251785 struct kbase_jd_atom *katom)
16261786 {
16271787 if (katom->need_cache_flush_cores_retained) {
1628
- kbase_gpu_start_cache_clean(kbdev);
1788
+ kbase_gpu_start_cache_clean(kbdev,
1789
+ GPU_COMMAND_CACHE_CLN_INV_FULL);
16291790 kbase_gpu_wait_cache_clean(kbdev);
16301791
16311792 katom->need_cache_flush_cores_retained = false;
....@@ -1646,22 +1807,20 @@
16461807 base_jd_core_req core_req)
16471808 {
16481809 if (!kbdev->pm.active_count) {
1649
- mutex_lock(&kbdev->js_data.runpool_mutex);
1650
- mutex_lock(&kbdev->pm.lock);
1810
+ kbase_pm_lock(kbdev);
16511811 kbase_pm_update_active(kbdev);
1652
- mutex_unlock(&kbdev->pm.lock);
1653
- mutex_unlock(&kbdev->js_data.runpool_mutex);
1812
+ kbase_pm_unlock(kbdev);
16541813 }
16551814 }
16561815
16571816 void kbase_gpu_dump_slots(struct kbase_device *kbdev)
16581817 {
16591818 unsigned long flags;
1660
- int js;
1819
+ unsigned int js;
16611820
16621821 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
16631822
1664
- dev_info(kbdev->dev, "kbase_gpu_dump_slots:\n");
1823
+ dev_info(kbdev->dev, "%s:\n", __func__);
16651824
16661825 for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
16671826 int idx;
....@@ -1672,14 +1831,43 @@
16721831 idx);
16731832
16741833 if (katom)
1675
- dev_info(kbdev->dev,
1676
- " js%d idx%d : katom=%pK gpu_rb_state=%d\n",
1677
- js, idx, katom, katom->gpu_rb_state);
1834
+ dev_info(kbdev->dev, " js%u idx%d : katom=%pK gpu_rb_state=%d\n",
1835
+ js, idx, katom, katom->gpu_rb_state);
16781836 else
1679
- dev_info(kbdev->dev, " js%d idx%d : empty\n",
1680
- js, idx);
1837
+ dev_info(kbdev->dev, " js%u idx%d : empty\n", js, idx);
16811838 }
16821839 }
16831840
16841841 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
16851842 }
1843
+
1844
+void kbase_backend_slot_kctx_purge_locked(struct kbase_device *kbdev, struct kbase_context *kctx)
1845
+{
1846
+ unsigned int js;
1847
+ bool tracked = false;
1848
+
1849
+ lockdep_assert_held(&kbdev->hwaccess_lock);
1850
+
1851
+ for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
1852
+ u64 tagged_kctx = kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged;
1853
+
1854
+ if (tagged_kctx == SLOT_RB_TAG_KCTX(kctx)) {
1855
+ /* Marking the slot kctx tracking field is purged */
1856
+ kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged = SLOT_RB_TAG_PURGED;
1857
+ tracked = true;
1858
+ }
1859
+ }
1860
+
1861
+ if (tracked) {
1862
+ /* The context had run some jobs before the purge, other slots
1863
+ * in SLOT_RB_NULL_TAG_VAL condition needs to be marked as
1864
+ * purged as well.
1865
+ */
1866
+ for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
1867
+ if (kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged ==
1868
+ SLOT_RB_NULL_TAG_VAL)
1869
+ kbdev->hwaccess.backend.slot_rb[js].last_kctx_tagged =
1870
+ SLOT_RB_TAG_PURGED;
1871
+ }
1872
+ }
1873
+}