hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/gpu/arm/bifrost/mali_kbase_js.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2011-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2011-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
....@@ -34,6 +34,7 @@
3434
3535 #include "mali_kbase_jm.h"
3636 #include "mali_kbase_hwaccess_jm.h"
37
+#include <mali_kbase_hwaccess_time.h>
3738 #include <linux/priority_control_manager.h>
3839
3940 /*
....@@ -77,8 +78,7 @@
7778 struct kbase_device *kbdev, struct kbase_context *kctx,
7879 struct kbasep_js_atom_retained_state *katom_retained_state);
7980
80
-static int kbase_js_get_slot(struct kbase_device *kbdev,
81
- struct kbase_jd_atom *katom);
81
+static unsigned int kbase_js_get_slot(struct kbase_device *kbdev, struct kbase_jd_atom *katom);
8282
8383 static void kbase_js_foreach_ctx_job(struct kbase_context *kctx,
8484 kbasep_js_ctx_job_cb *callback);
....@@ -151,8 +151,7 @@
151151 *
152152 * Return: true if there are no atoms to pull, false otherwise.
153153 */
154
-static inline bool
155
-jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, int js, int prio)
154
+static inline bool jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, unsigned int js, int prio)
156155 {
157156 bool none_to_pull;
158157 struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
....@@ -161,9 +160,8 @@
161160
162161 none_to_pull = RB_EMPTY_ROOT(&rb->runnable_tree);
163162
164
- dev_dbg(kctx->kbdev->dev,
165
- "Slot %d (prio %d) is %spullable in kctx %pK\n",
166
- js, prio, none_to_pull ? "not " : "", kctx);
163
+ dev_dbg(kctx->kbdev->dev, "Slot %u (prio %d) is %spullable in kctx %pK\n", js, prio,
164
+ none_to_pull ? "not " : "", kctx);
167165
168166 return none_to_pull;
169167 }
....@@ -179,8 +177,7 @@
179177 * Return: true if the ring buffers for all priorities have no pullable atoms,
180178 * false otherwise.
181179 */
182
-static inline bool
183
-jsctx_rb_none_to_pull(struct kbase_context *kctx, int js)
180
+static inline bool jsctx_rb_none_to_pull(struct kbase_context *kctx, unsigned int js)
184181 {
185182 int prio;
186183
....@@ -212,8 +209,8 @@
212209 *
213210 * The HW access lock must always be held when calling this function.
214211 */
215
-static void jsctx_queue_foreach_prio(struct kbase_context *kctx, int js,
216
- int prio, kbasep_js_ctx_job_cb *callback)
212
+static void jsctx_queue_foreach_prio(struct kbase_context *kctx, unsigned int js, int prio,
213
+ kbasep_js_ctx_job_cb *callback)
217214 {
218215 struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
219216
....@@ -272,7 +269,7 @@
272269 * jsctx_queue_foreach_prio() to iterate over the queue and invoke @callback
273270 * for each entry, and remove the entry from the queue.
274271 */
275
-static inline void jsctx_queue_foreach(struct kbase_context *kctx, int js,
272
+static inline void jsctx_queue_foreach(struct kbase_context *kctx, unsigned int js,
276273 kbasep_js_ctx_job_cb *callback)
277274 {
278275 int prio;
....@@ -293,15 +290,14 @@
293290 *
294291 * Return: Pointer to next atom in buffer, or NULL if there is no atom.
295292 */
296
-static inline struct kbase_jd_atom *
297
-jsctx_rb_peek_prio(struct kbase_context *kctx, int js, int prio)
293
+static inline struct kbase_jd_atom *jsctx_rb_peek_prio(struct kbase_context *kctx, unsigned int js,
294
+ int prio)
298295 {
299296 struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
300297 struct rb_node *node;
301298
302299 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
303
- dev_dbg(kctx->kbdev->dev,
304
- "Peeking runnable tree of kctx %pK for prio %d (s:%d)\n",
300
+ dev_dbg(kctx->kbdev->dev, "Peeking runnable tree of kctx %pK for prio %d (s:%u)\n",
305301 (void *)kctx, prio, js);
306302
307303 node = rb_first(&rb->runnable_tree);
....@@ -326,8 +322,7 @@
326322 *
327323 * Return: Pointer to next atom in buffer, or NULL if there is no atom.
328324 */
329
-static inline struct kbase_jd_atom *
330
-jsctx_rb_peek(struct kbase_context *kctx, int js)
325
+static inline struct kbase_jd_atom *jsctx_rb_peek(struct kbase_context *kctx, unsigned int js)
331326 {
332327 int prio;
333328
....@@ -358,7 +353,7 @@
358353 jsctx_rb_pull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
359354 {
360355 int prio = katom->sched_priority;
361
- int js = katom->slot_nr;
356
+ unsigned int js = katom->slot_nr;
362357 struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
363358
364359 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
....@@ -372,28 +367,26 @@
372367 rb_erase(&katom->runnable_tree_node, &rb->runnable_tree);
373368 }
374369
375
-#define LESS_THAN_WRAP(a, b) ((s32)(a - b) < 0)
376
-
377370 static void
378371 jsctx_tree_add(struct kbase_context *kctx, struct kbase_jd_atom *katom)
379372 {
380373 struct kbase_device *kbdev = kctx->kbdev;
381374 int prio = katom->sched_priority;
382
- int js = katom->slot_nr;
375
+ unsigned int js = katom->slot_nr;
383376 struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
384377 struct rb_node **new = &(queue->runnable_tree.rb_node), *parent = NULL;
385378
386379 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
387380
388
- dev_dbg(kbdev->dev, "Adding atom %pK to runnable tree of kctx %pK (s:%d)\n",
389
- (void *)katom, (void *)kctx, js);
381
+ dev_dbg(kbdev->dev, "Adding atom %pK to runnable tree of kctx %pK (s:%u)\n", (void *)katom,
382
+ (void *)kctx, js);
390383
391384 while (*new) {
392385 struct kbase_jd_atom *entry = container_of(*new,
393386 struct kbase_jd_atom, runnable_tree_node);
394387
395388 parent = *new;
396
- if (LESS_THAN_WRAP(katom->age, entry->age))
389
+ if (kbase_jd_atom_is_younger(katom, entry))
397390 new = &((*new)->rb_left);
398391 else
399392 new = &((*new)->rb_right);
....@@ -421,18 +414,78 @@
421414 {
422415 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
423416
417
+ KBASE_KTRACE_ADD_JM(kctx->kbdev, JS_UNPULL_JOB, kctx, katom, katom->jc,
418
+ 0u);
419
+
424420 jsctx_tree_add(kctx, katom);
425421 }
426422
427
-static bool kbase_js_ctx_pullable(struct kbase_context *kctx,
428
- int js,
429
- bool is_scheduled);
423
+static bool kbase_js_ctx_pullable(struct kbase_context *kctx, unsigned int js, bool is_scheduled);
430424 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
431
- struct kbase_context *kctx,
432
- int js);
425
+ struct kbase_context *kctx, unsigned int js);
433426 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
434
- struct kbase_context *kctx,
435
- int js);
427
+ struct kbase_context *kctx, unsigned int js);
428
+
429
+typedef bool(katom_ordering_func)(const struct kbase_jd_atom *,
430
+ const struct kbase_jd_atom *);
431
+
432
+bool kbase_js_atom_runs_before(struct kbase_device *kbdev,
433
+ const struct kbase_jd_atom *katom_a,
434
+ const struct kbase_jd_atom *katom_b,
435
+ const kbase_atom_ordering_flag_t order_flags)
436
+{
437
+ struct kbase_context *kctx_a = katom_a->kctx;
438
+ struct kbase_context *kctx_b = katom_b->kctx;
439
+ katom_ordering_func *samectxatomprio_ordering_func =
440
+ kbase_jd_atom_is_younger;
441
+
442
+ lockdep_assert_held(&kbdev->hwaccess_lock);
443
+
444
+ if (order_flags & KBASE_ATOM_ORDERING_FLAG_SEQNR)
445
+ samectxatomprio_ordering_func = kbase_jd_atom_is_earlier;
446
+
447
+ /* It only makes sense to make this test for atoms on the same slot */
448
+ WARN_ON(katom_a->slot_nr != katom_b->slot_nr);
449
+
450
+ if (kbdev->js_ctx_scheduling_mode ==
451
+ KBASE_JS_PROCESS_LOCAL_PRIORITY_MODE) {
452
+ /* In local priority mode, querying either way around for "a
453
+ * should run before b" and "b should run before a" should
454
+ * always be false when they're from different contexts
455
+ */
456
+ if (kctx_a != kctx_b)
457
+ return false;
458
+ } else {
459
+ /* In system priority mode, ordering is done first strictly by
460
+ * context priority, even when katom_b might be lower priority
461
+ * than katom_a. This is due to scheduling of contexts in order
462
+ * of highest priority first, regardless of whether the atoms
463
+ * for a particular slot from such contexts have the highest
464
+ * priority or not.
465
+ */
466
+ if (kctx_a != kctx_b) {
467
+ if (kctx_a->priority < kctx_b->priority)
468
+ return true;
469
+ if (kctx_a->priority > kctx_b->priority)
470
+ return false;
471
+ }
472
+ }
473
+
474
+ /* For same contexts/contexts with the same context priority (in system
475
+ * priority mode), ordering is next done by atom priority
476
+ */
477
+ if (katom_a->sched_priority < katom_b->sched_priority)
478
+ return true;
479
+ if (katom_a->sched_priority > katom_b->sched_priority)
480
+ return false;
481
+ /* For atoms of same priority on the same kctx, they are
482
+ * ordered by seq_nr/age (dependent on caller)
483
+ */
484
+ if (kctx_a == kctx_b && samectxatomprio_ordering_func(katom_a, katom_b))
485
+ return true;
486
+
487
+ return false;
488
+}
436489
437490 /*
438491 * Functions private to KBase ('Protected' functions)
....@@ -475,9 +528,11 @@
475528 jsdd->hard_stop_ticks_dumping = DEFAULT_JS_HARD_STOP_TICKS_DUMPING;
476529 jsdd->gpu_reset_ticks_ss = DEFAULT_JS_RESET_TICKS_SS;
477530 jsdd->gpu_reset_ticks_cl = DEFAULT_JS_RESET_TICKS_CL;
531
+
478532 jsdd->gpu_reset_ticks_dumping = DEFAULT_JS_RESET_TICKS_DUMPING;
479533 jsdd->ctx_timeslice_ns = DEFAULT_JS_CTX_TIMESLICE_NS;
480534 atomic_set(&jsdd->soft_job_timeout_ms, DEFAULT_JS_SOFT_JOB_TIMEOUT);
535
+ jsdd->js_free_wait_time_ms = kbase_get_timeout_ms(kbdev, JM_DEFAULT_JS_FREE_TIMEOUT);
481536
482537 dev_dbg(kbdev->dev, "JS Config Attribs: ");
483538 dev_dbg(kbdev->dev, "\tscheduling_period_ns:%u",
....@@ -502,6 +557,7 @@
502557 jsdd->ctx_timeslice_ns);
503558 dev_dbg(kbdev->dev, "\tsoft_job_timeout:%i",
504559 atomic_read(&jsdd->soft_job_timeout_ms));
560
+ dev_dbg(kbdev->dev, "\tjs_free_wait_time_ms:%u", jsdd->js_free_wait_time_ms);
505561
506562 if (!(jsdd->soft_stop_ticks < jsdd->hard_stop_ticks_ss &&
507563 jsdd->hard_stop_ticks_ss < jsdd->gpu_reset_ticks_ss &&
....@@ -558,6 +614,7 @@
558614 {
559615 struct kbasep_js_device_data *js_devdata;
560616 s8 zero_ctx_attr_ref_count[KBASEP_JS_CTX_ATTR_COUNT] = { 0, };
617
+ CSTD_UNUSED(js_devdata);
561618
562619 KBASE_DEBUG_ASSERT(kbdev != NULL);
563620
....@@ -575,14 +632,13 @@
575632
576633 int kbasep_js_kctx_init(struct kbase_context *const kctx)
577634 {
578
- struct kbase_device *kbdev;
579635 struct kbasep_js_kctx_info *js_kctx_info;
580636 int i, j;
637
+ CSTD_UNUSED(js_kctx_info);
581638
582639 KBASE_DEBUG_ASSERT(kctx != NULL);
583640
584
- kbdev = kctx->kbdev;
585
- KBASE_DEBUG_ASSERT(kbdev != NULL);
641
+ kbase_ctx_sched_init_ctx(kctx);
586642
587643 for (i = 0; i < BASE_JM_MAX_NR_SLOTS; ++i)
588644 INIT_LIST_HEAD(&kctx->jctx.sched_info.ctx.ctx_list_entry[i]);
....@@ -622,9 +678,10 @@
622678 {
623679 struct kbase_device *kbdev;
624680 struct kbasep_js_kctx_info *js_kctx_info;
625
- int js;
681
+ unsigned int js;
626682 bool update_ctx_count = false;
627683 unsigned long flags;
684
+ CSTD_UNUSED(js_kctx_info);
628685
629686 KBASE_DEBUG_ASSERT(kctx != NULL);
630687
....@@ -660,6 +717,149 @@
660717 kbase_backend_ctx_count_changed(kbdev);
661718 mutex_unlock(&kbdev->js_data.runpool_mutex);
662719 }
720
+
721
+ kbase_ctx_sched_remove_ctx(kctx);
722
+}
723
+
724
+/*
725
+ * Priority blocking management functions
726
+ */
727
+
728
+/* Should not normally use directly - use kbase_jsctx_slot_atom_pulled_dec() instead */
729
+static void kbase_jsctx_slot_prio_blocked_clear(struct kbase_context *kctx, unsigned int js,
730
+ int sched_prio)
731
+{
732
+ struct kbase_jsctx_slot_tracking *slot_tracking =
733
+ &kctx->slot_tracking[js];
734
+
735
+ lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
736
+
737
+ slot_tracking->blocked &= ~(((kbase_js_prio_bitmap_t)1) << sched_prio);
738
+ KBASE_KTRACE_ADD_JM_SLOT_INFO(kctx->kbdev, JS_SLOT_PRIO_UNBLOCKED, kctx,
739
+ NULL, 0, js, (unsigned int)sched_prio);
740
+}
741
+
742
+static int kbase_jsctx_slot_atoms_pulled(struct kbase_context *kctx, unsigned int js)
743
+{
744
+ return atomic_read(&kctx->slot_tracking[js].atoms_pulled);
745
+}
746
+
747
+/*
748
+ * A priority level on a slot is blocked when:
749
+ * - that priority level is blocked
750
+ * - or, any higher priority level is blocked
751
+ */
752
+static bool kbase_jsctx_slot_prio_is_blocked(struct kbase_context *kctx, unsigned int js,
753
+ int sched_prio)
754
+{
755
+ struct kbase_jsctx_slot_tracking *slot_tracking =
756
+ &kctx->slot_tracking[js];
757
+ kbase_js_prio_bitmap_t prio_bit, higher_prios_mask;
758
+
759
+ lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
760
+
761
+ /* done in two separate shifts to prevent future undefined behavior
762
+ * should the number of priority levels == (bit width of the type)
763
+ */
764
+ prio_bit = (((kbase_js_prio_bitmap_t)1) << sched_prio);
765
+ /* all bits of sched_prio or higher, with sched_prio = 0 being the
766
+ * highest priority
767
+ */
768
+ higher_prios_mask = (prio_bit << 1) - 1u;
769
+ return (slot_tracking->blocked & higher_prios_mask) != 0u;
770
+}
771
+
772
+/**
773
+ * kbase_jsctx_slot_atom_pulled_inc - Increase counts of atoms that have being
774
+ * pulled for a slot from a ctx, based on
775
+ * this atom
776
+ * @kctx: kbase context
777
+ * @katom: atom pulled
778
+ *
779
+ * Manages counts of atoms pulled (including per-priority-level counts), for
780
+ * later determining when a ctx can become unblocked on a slot.
781
+ *
782
+ * Once a slot has been blocked at @katom's priority level, it should not be
783
+ * pulled from, hence this function should not be called in that case.
784
+ *
785
+ * The return value is to aid tracking of when @kctx becomes runnable.
786
+ *
787
+ * Return: new total count of atoms pulled from all slots on @kctx
788
+ */
789
+static int kbase_jsctx_slot_atom_pulled_inc(struct kbase_context *kctx,
790
+ const struct kbase_jd_atom *katom)
791
+{
792
+ unsigned int js = katom->slot_nr;
793
+ int sched_prio = katom->sched_priority;
794
+ struct kbase_jsctx_slot_tracking *slot_tracking =
795
+ &kctx->slot_tracking[js];
796
+ int nr_atoms_pulled;
797
+
798
+ lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
799
+
800
+ WARN(kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio),
801
+ "Should not have pulled atoms for slot %u from a context that is blocked at priority %d or higher",
802
+ js, sched_prio);
803
+
804
+ nr_atoms_pulled = atomic_inc_return(&kctx->atoms_pulled_all_slots);
805
+ atomic_inc(&slot_tracking->atoms_pulled);
806
+ slot_tracking->atoms_pulled_pri[sched_prio]++;
807
+
808
+ return nr_atoms_pulled;
809
+}
810
+
811
+/**
812
+ * kbase_jsctx_slot_atom_pulled_dec- Decrease counts of atoms that have being
813
+ * pulled for a slot from a ctx, and
814
+ * re-evaluate whether a context is blocked
815
+ * on this slot
816
+ * @kctx: kbase context
817
+ * @katom: atom that has just been removed from a job slot
818
+ *
819
+ * @kctx can become unblocked on a slot for a priority level when it no longer
820
+ * has any pulled atoms at that priority level on that slot, and all higher
821
+ * (numerically lower) priority levels are also unblocked @kctx on that
822
+ * slot. The latter condition is to retain priority ordering within @kctx.
823
+ *
824
+ * Return: true if the slot was previously blocked but has now become unblocked
825
+ * at @katom's priority level, false otherwise.
826
+ */
827
+static bool kbase_jsctx_slot_atom_pulled_dec(struct kbase_context *kctx,
828
+ const struct kbase_jd_atom *katom)
829
+{
830
+ unsigned int js = katom->slot_nr;
831
+ int sched_prio = katom->sched_priority;
832
+ int atoms_pulled_pri;
833
+ struct kbase_jsctx_slot_tracking *slot_tracking =
834
+ &kctx->slot_tracking[js];
835
+ bool slot_prio_became_unblocked = false;
836
+
837
+ lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
838
+
839
+ atomic_dec(&kctx->atoms_pulled_all_slots);
840
+ atomic_dec(&slot_tracking->atoms_pulled);
841
+
842
+ atoms_pulled_pri = --(slot_tracking->atoms_pulled_pri[sched_prio]);
843
+
844
+ /* We can safely clear this priority level's blocked status even if
845
+ * higher priority levels are still blocked: a subsequent query to
846
+ * kbase_jsctx_slot_prio_is_blocked() will still return true
847
+ */
848
+ if (!atoms_pulled_pri &&
849
+ kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio)) {
850
+ kbase_jsctx_slot_prio_blocked_clear(kctx, js, sched_prio);
851
+
852
+ if (!kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio))
853
+ slot_prio_became_unblocked = true;
854
+ }
855
+
856
+ if (slot_prio_became_unblocked)
857
+ KBASE_KTRACE_ADD_JM_SLOT_INFO(kctx->kbdev,
858
+ JS_SLOT_PRIO_AND_HIGHER_UNBLOCKED,
859
+ kctx, katom, katom->jc, js,
860
+ (unsigned int)sched_prio);
861
+
862
+ return slot_prio_became_unblocked;
663863 }
664864
665865 /**
....@@ -676,14 +876,12 @@
676876 * Return: true if caller should call kbase_backend_ctx_count_changed()
677877 */
678878 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
679
- struct kbase_context *kctx,
680
- int js)
879
+ struct kbase_context *kctx, unsigned int js)
681880 {
682881 bool ret = false;
683882
684883 lockdep_assert_held(&kbdev->hwaccess_lock);
685
- dev_dbg(kbdev->dev, "Add pullable tail kctx %pK (s:%d)\n",
686
- (void *)kctx, js);
884
+ dev_dbg(kbdev->dev, "Add pullable tail kctx %pK (s:%u)\n", (void *)kctx, js);
687885
688886 if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
689887 list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
....@@ -694,7 +892,7 @@
694892 if (!kctx->slots_pullable) {
695893 kbdev->js_data.nr_contexts_pullable++;
696894 ret = true;
697
- if (!atomic_read(&kctx->atoms_pulled)) {
895
+ if (!kbase_jsctx_atoms_pulled(kctx)) {
698896 WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
699897 kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
700898 atomic_inc(&kbdev->js_data.nr_contexts_runnable);
....@@ -718,14 +916,13 @@
718916 *
719917 * Return: true if caller should call kbase_backend_ctx_count_changed()
720918 */
721
-static bool kbase_js_ctx_list_add_pullable_head_nolock(
722
- struct kbase_device *kbdev, struct kbase_context *kctx, int js)
919
+static bool kbase_js_ctx_list_add_pullable_head_nolock(struct kbase_device *kbdev,
920
+ struct kbase_context *kctx, unsigned int js)
723921 {
724922 bool ret = false;
725923
726924 lockdep_assert_held(&kbdev->hwaccess_lock);
727
- dev_dbg(kbdev->dev, "Add pullable head kctx %pK (s:%d)\n",
728
- (void *)kctx, js);
925
+ dev_dbg(kbdev->dev, "Add pullable head kctx %pK (s:%u)\n", (void *)kctx, js);
729926
730927 if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
731928 list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
....@@ -736,7 +933,7 @@
736933 if (!kctx->slots_pullable) {
737934 kbdev->js_data.nr_contexts_pullable++;
738935 ret = true;
739
- if (!atomic_read(&kctx->atoms_pulled)) {
936
+ if (!kbase_jsctx_atoms_pulled(kctx)) {
740937 WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
741938 kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
742939 atomic_inc(&kbdev->js_data.nr_contexts_runnable);
....@@ -763,8 +960,7 @@
763960 * Return: true if caller should call kbase_backend_ctx_count_changed()
764961 */
765962 static bool kbase_js_ctx_list_add_pullable_head(struct kbase_device *kbdev,
766
- struct kbase_context *kctx,
767
- int js)
963
+ struct kbase_context *kctx, unsigned int js)
768964 {
769965 bool ret;
770966 unsigned long flags;
....@@ -794,14 +990,12 @@
794990 * Return: true if caller should call kbase_backend_ctx_count_changed()
795991 */
796992 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
797
- struct kbase_context *kctx,
798
- int js)
993
+ struct kbase_context *kctx, unsigned int js)
799994 {
800995 bool ret = false;
801996
802997 lockdep_assert_held(&kbdev->hwaccess_lock);
803
- dev_dbg(kbdev->dev, "Add unpullable tail kctx %pK (s:%d)\n",
804
- (void *)kctx, js);
998
+ dev_dbg(kbdev->dev, "Add unpullable tail kctx %pK (s:%u)\n", (void *)kctx, js);
805999
8061000 list_move_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
8071001 &kbdev->js_data.ctx_list_unpullable[js][kctx->priority]);
....@@ -809,7 +1003,7 @@
8091003 if (kctx->slots_pullable == (1 << js)) {
8101004 kbdev->js_data.nr_contexts_pullable--;
8111005 ret = true;
812
- if (!atomic_read(&kctx->atoms_pulled)) {
1006
+ if (!kbase_jsctx_atoms_pulled(kctx)) {
8131007 WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
8141008 kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
8151009 atomic_dec(&kbdev->js_data.nr_contexts_runnable);
....@@ -836,9 +1030,8 @@
8361030 *
8371031 * Return: true if caller should call kbase_backend_ctx_count_changed()
8381032 */
839
-static bool kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev,
840
- struct kbase_context *kctx,
841
- int js)
1033
+static bool kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev, struct kbase_context *kctx,
1034
+ unsigned int js)
8421035 {
8431036 bool ret = false;
8441037
....@@ -851,7 +1044,7 @@
8511044 if (kctx->slots_pullable == (1 << js)) {
8521045 kbdev->js_data.nr_contexts_pullable--;
8531046 ret = true;
854
- if (!atomic_read(&kctx->atoms_pulled)) {
1047
+ if (!kbase_jsctx_atoms_pulled(kctx)) {
8551048 WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
8561049 kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
8571050 atomic_dec(&kbdev->js_data.nr_contexts_runnable);
....@@ -874,9 +1067,8 @@
8741067 * Return: Context to use for specified slot.
8751068 * NULL if no contexts present for specified slot
8761069 */
877
-static struct kbase_context *kbase_js_ctx_list_pop_head_nolock(
878
- struct kbase_device *kbdev,
879
- int js)
1070
+static struct kbase_context *kbase_js_ctx_list_pop_head_nolock(struct kbase_device *kbdev,
1071
+ unsigned int js)
8801072 {
8811073 struct kbase_context *kctx;
8821074 int i;
....@@ -892,9 +1084,8 @@
8921084 jctx.sched_info.ctx.ctx_list_entry[js]);
8931085
8941086 list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
895
- dev_dbg(kbdev->dev,
896
- "Popped %pK from the pullable queue (s:%d)\n",
897
- (void *)kctx, js);
1087
+ dev_dbg(kbdev->dev, "Popped %pK from the pullable queue (s:%u)\n", (void *)kctx,
1088
+ js);
8981089 return kctx;
8991090 }
9001091 return NULL;
....@@ -909,8 +1100,7 @@
9091100 * Return: Context to use for specified slot.
9101101 * NULL if no contexts present for specified slot
9111102 */
912
-static struct kbase_context *kbase_js_ctx_list_pop_head(
913
- struct kbase_device *kbdev, int js)
1103
+static struct kbase_context *kbase_js_ctx_list_pop_head(struct kbase_device *kbdev, unsigned int js)
9141104 {
9151105 struct kbase_context *kctx;
9161106 unsigned long flags;
....@@ -934,8 +1124,7 @@
9341124 * Return: true if context can be pulled from on specified slot
9351125 * false otherwise
9361126 */
937
-static bool kbase_js_ctx_pullable(struct kbase_context *kctx, int js,
938
- bool is_scheduled)
1127
+static bool kbase_js_ctx_pullable(struct kbase_context *kctx, unsigned int js, bool is_scheduled)
9391128 {
9401129 struct kbasep_js_device_data *js_devdata;
9411130 struct kbase_jd_atom *katom;
....@@ -954,13 +1143,15 @@
9541143 }
9551144 katom = jsctx_rb_peek(kctx, js);
9561145 if (!katom) {
957
- dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%d)\n",
958
- (void *)kctx, js);
1146
+ dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%u)\n", (void *)kctx, js);
9591147 return false; /* No pullable atoms */
9601148 }
961
- if (kctx->blocked_js[js][katom->sched_priority]) {
1149
+ if (kbase_jsctx_slot_prio_is_blocked(kctx, js, katom->sched_priority)) {
1150
+ KBASE_KTRACE_ADD_JM_SLOT_INFO(
1151
+ kctx->kbdev, JS_SLOT_PRIO_IS_BLOCKED, kctx, katom,
1152
+ katom->jc, js, (unsigned int)katom->sched_priority);
9621153 dev_dbg(kbdev->dev,
963
- "JS: kctx %pK is blocked from submitting atoms at priority %d (s:%d)\n",
1154
+ "JS: kctx %pK is blocked from submitting atoms at priority %d and lower (s:%u)\n",
9641155 (void *)kctx, katom->sched_priority, js);
9651156 return false;
9661157 }
....@@ -981,14 +1172,14 @@
9811172 if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
9821173 kbase_backend_nr_atoms_on_slot(kctx->kbdev, js)) {
9831174 dev_dbg(kbdev->dev,
984
- "JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%d)\n",
1175
+ "JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%u)\n",
9851176 (void *)katom, js);
9861177 return false;
9871178 }
9881179 }
9891180
990
- dev_dbg(kbdev->dev, "JS: Atom %pK is pullable in kctx %pK (s:%d)\n",
991
- (void *)katom, (void *)kctx, js);
1181
+ dev_dbg(kbdev->dev, "JS: Atom %pK is pullable in kctx %pK (s:%u)\n", (void *)katom,
1182
+ (void *)kctx, js);
9921183
9931184 return true;
9941185 }
....@@ -999,7 +1190,7 @@
9991190 struct kbase_device *kbdev = kctx->kbdev;
10001191 bool ret = true;
10011192 bool has_dep = false, has_x_dep = false;
1002
- int js = kbase_js_get_slot(kbdev, katom);
1193
+ unsigned int js = kbase_js_get_slot(kbdev, katom);
10031194 int prio = katom->sched_priority;
10041195 int i;
10051196
....@@ -1007,7 +1198,7 @@
10071198 struct kbase_jd_atom *dep_atom = katom->dep[i].atom;
10081199
10091200 if (dep_atom) {
1010
- int dep_js = kbase_js_get_slot(kbdev, dep_atom);
1201
+ unsigned int dep_js = kbase_js_get_slot(kbdev, dep_atom);
10111202 int dep_prio = dep_atom->sched_priority;
10121203
10131204 dev_dbg(kbdev->dev,
....@@ -1162,7 +1353,7 @@
11621353 void kbase_js_set_ctx_priority(struct kbase_context *kctx, int new_priority)
11631354 {
11641355 struct kbase_device *kbdev = kctx->kbdev;
1165
- int js;
1356
+ unsigned int js;
11661357
11671358 lockdep_assert_held(&kbdev->hwaccess_lock);
11681359
....@@ -1593,6 +1784,7 @@
15931784 bool runpool_ctx_attr_change = false;
15941785 int kctx_as_nr;
15951786 int new_ref_count;
1787
+ CSTD_UNUSED(kctx_as_nr);
15961788
15971789 KBASE_DEBUG_ASSERT(kbdev != NULL);
15981790 KBASE_DEBUG_ASSERT(kctx != NULL);
....@@ -1867,9 +2059,8 @@
18672059 kbase_backend_timeouts_changed(kbdev);
18682060 }
18692061
1870
-static bool kbasep_js_schedule_ctx(struct kbase_device *kbdev,
1871
- struct kbase_context *kctx,
1872
- int js)
2062
+static bool kbasep_js_schedule_ctx(struct kbase_device *kbdev, struct kbase_context *kctx,
2063
+ unsigned int js)
18732064 {
18742065 struct kbasep_js_device_data *js_devdata;
18752066 struct kbasep_js_kctx_info *js_kctx_info;
....@@ -1877,7 +2068,7 @@
18772068 bool kctx_suspended = false;
18782069 int as_nr;
18792070
1880
- dev_dbg(kbdev->dev, "Scheduling kctx %pK (s:%d)\n", kctx, js);
2071
+ dev_dbg(kbdev->dev, "Scheduling kctx %pK (s:%u)\n", kctx, js);
18812072
18822073 js_devdata = &kbdev->js_data;
18832074 js_kctx_info = &kctx->jctx.sched_info;
....@@ -1904,8 +2095,8 @@
19042095 WARN_ON(as_nr == KBASEP_AS_NR_INVALID);
19052096 }
19062097 }
1907
- if (as_nr == KBASEP_AS_NR_INVALID)
1908
- return false; /* No address spaces currently available */
2098
+ if ((as_nr < 0) || (as_nr >= BASE_MAX_NR_AS))
2099
+ return false; /* No address space currently available */
19092100
19102101 /*
19112102 * Atomic transaction on the Context and Run Pool begins
....@@ -1976,6 +2167,7 @@
19762167 #endif
19772168 /* Cause it to leave at some later point */
19782169 bool retained;
2170
+ CSTD_UNUSED(retained);
19792171
19802172 retained = kbase_ctx_sched_inc_refcount_nolock(kctx);
19812173 KBASE_DEBUG_ASSERT(retained);
....@@ -2011,9 +2203,8 @@
20112203 return true;
20122204 }
20132205
2014
-static bool kbase_js_use_ctx(struct kbase_device *kbdev,
2015
- struct kbase_context *kctx,
2016
- int js)
2206
+static bool kbase_js_use_ctx(struct kbase_device *kbdev, struct kbase_context *kctx,
2207
+ unsigned int js)
20172208 {
20182209 unsigned long flags;
20192210
....@@ -2021,9 +2212,7 @@
20212212
20222213 if (kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
20232214 kbase_backend_use_ctx_sched(kbdev, kctx, js)) {
2024
-
2025
- dev_dbg(kbdev->dev,
2026
- "kctx %pK already has ASID - mark as active (s:%d)\n",
2215
+ dev_dbg(kbdev->dev, "kctx %pK already has ASID - mark as active (s:%u)\n",
20272216 (void *)kctx, js);
20282217
20292218 if (kbdev->hwaccess.active_kctx[js] != kctx) {
....@@ -2290,8 +2479,7 @@
22902479 return true;
22912480 }
22922481
2293
-static int kbase_js_get_slot(struct kbase_device *kbdev,
2294
- struct kbase_jd_atom *katom)
2482
+static unsigned int kbase_js_get_slot(struct kbase_device *kbdev, struct kbase_jd_atom *katom)
22952483 {
22962484 if (katom->core_req & BASE_JD_REQ_JOB_SLOT)
22972485 return katom->jobslot;
....@@ -2321,21 +2509,19 @@
23212509 /* If slot will transition from unpullable to pullable then add to
23222510 * pullable list
23232511 */
2324
- if (jsctx_rb_none_to_pull(kctx, katom->slot_nr)) {
2512
+ if (jsctx_rb_none_to_pull(kctx, katom->slot_nr))
23252513 enqueue_required = true;
2326
- } else {
2514
+ else
23272515 enqueue_required = false;
2328
- }
23292516
23302517 if ((katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) ||
23312518 (katom->pre_dep && (katom->pre_dep->atom_flags &
23322519 KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST))) {
23332520 int prio = katom->sched_priority;
2334
- int js = katom->slot_nr;
2521
+ unsigned int js = katom->slot_nr;
23352522 struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
23362523
2337
- dev_dbg(kctx->kbdev->dev, "Add atom %pK to X_DEP list (s:%d)\n",
2338
- (void *)katom, js);
2524
+ dev_dbg(kctx->kbdev->dev, "Add atom %pK to X_DEP list (s:%u)\n", (void *)katom, js);
23392525
23402526 list_add_tail(&katom->queue, &queue->x_dep_head);
23412527 katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
....@@ -2426,8 +2612,8 @@
24262612 *
24272613 * Context: Caller must hold the HW access lock
24282614 */
2429
-static void kbase_js_evict_deps(struct kbase_context *kctx,
2430
- struct kbase_jd_atom *katom, int js, int prio)
2615
+static void kbase_js_evict_deps(struct kbase_context *kctx, struct kbase_jd_atom *katom,
2616
+ unsigned int js, int prio)
24312617 {
24322618 struct kbase_jd_atom *x_dep = katom->x_post_dep;
24332619 struct kbase_jd_atom *next_katom = katom->post_dep;
....@@ -2451,15 +2637,15 @@
24512637 (void *)x_dep);
24522638
24532639 /* Fail if it had a data dependency. */
2454
- if (x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) {
2640
+ if (x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER)
24552641 x_dep->will_fail_event_code = katom->event_code;
2456
- }
2642
+
24572643 if (x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST)
24582644 kbase_js_move_to_tree(x_dep);
24592645 }
24602646 }
24612647
2462
-struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, int js)
2648
+struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, unsigned int js)
24632649 {
24642650 struct kbase_jd_atom *katom;
24652651 struct kbasep_js_device_data *js_devdata;
....@@ -2469,8 +2655,7 @@
24692655 KBASE_DEBUG_ASSERT(kctx);
24702656
24712657 kbdev = kctx->kbdev;
2472
- dev_dbg(kbdev->dev, "JS: pulling an atom from kctx %pK (s:%d)\n",
2473
- (void *)kctx, js);
2658
+ dev_dbg(kbdev->dev, "JS: pulling an atom from kctx %pK (s:%u)\n", (void *)kctx, js);
24742659
24752660 js_devdata = &kbdev->js_data;
24762661 lockdep_assert_held(&kbdev->hwaccess_lock);
....@@ -2489,13 +2674,12 @@
24892674
24902675 katom = jsctx_rb_peek(kctx, js);
24912676 if (!katom) {
2492
- dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%d)\n",
2493
- (void *)kctx, js);
2677
+ dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%u)\n", (void *)kctx, js);
24942678 return NULL;
24952679 }
2496
- if (kctx->blocked_js[js][katom->sched_priority]) {
2680
+ if (kbase_jsctx_slot_prio_is_blocked(kctx, js, katom->sched_priority)) {
24972681 dev_dbg(kbdev->dev,
2498
- "JS: kctx %pK is blocked from submitting atoms at priority %d (s:%d)\n",
2682
+ "JS: kctx %pK is blocked from submitting atoms at priority %d and lower (s:%u)\n",
24992683 (void *)kctx, katom->sched_priority, js);
25002684 return NULL;
25012685 }
....@@ -2509,7 +2693,7 @@
25092693 * not allow multiple runs of fail-dep atoms from the same context to be
25102694 * present on the same slot
25112695 */
2512
- if (katom->pre_dep && atomic_read(&kctx->atoms_pulled_slot[js])) {
2696
+ if (katom->pre_dep && kbase_jsctx_slot_atoms_pulled(kctx, js)) {
25132697 struct kbase_jd_atom *prev_atom =
25142698 kbase_backend_inspect_tail(kbdev, js);
25152699
....@@ -2529,32 +2713,30 @@
25292713 if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
25302714 kbase_backend_nr_atoms_on_slot(kbdev, js)) {
25312715 dev_dbg(kbdev->dev,
2532
- "JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%d)\n",
2716
+ "JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%u)\n",
25332717 (void *)katom, js);
25342718 return NULL;
25352719 }
25362720 }
25372721
2722
+ KBASE_KTRACE_ADD_JM_SLOT_INFO(kbdev, JS_PULL_JOB, kctx, katom,
2723
+ katom->jc, js, katom->sched_priority);
25382724 kbase_ctx_flag_set(kctx, KCTX_PULLED);
25392725 kbase_ctx_flag_set(kctx, (KCTX_PULLED_SINCE_ACTIVE_JS0 << js));
25402726
2541
- pulled = atomic_inc_return(&kctx->atoms_pulled);
2727
+ pulled = kbase_jsctx_slot_atom_pulled_inc(kctx, katom);
25422728 if (pulled == 1 && !kctx->slots_pullable) {
25432729 WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
25442730 kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
25452731 atomic_inc(&kbdev->js_data.nr_contexts_runnable);
25462732 }
2547
- atomic_inc(&kctx->atoms_pulled_slot[katom->slot_nr]);
2548
- kctx->atoms_pulled_slot_pri[katom->slot_nr][katom->sched_priority]++;
25492733 jsctx_rb_pull(kctx, katom);
25502734
25512735 kbase_ctx_sched_retain_ctx_refcount(kctx);
25522736
2553
- katom->atom_flags |= KBASE_KATOM_FLAG_HOLDING_CTX_REF;
2554
-
25552737 katom->ticks = 0;
25562738
2557
- dev_dbg(kbdev->dev, "JS: successfully pulled atom %pK from kctx %pK (s:%d)\n",
2739
+ dev_dbg(kbdev->dev, "JS: successfully pulled atom %pK from kctx %pK (s:%u)\n",
25582740 (void *)katom, (void *)kctx, js);
25592741
25602742 return katom;
....@@ -2773,14 +2955,17 @@
27732955 struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
27742956 struct kbasep_js_atom_retained_state retained_state;
27752957 int js = katom->slot_nr;
2776
- int prio = katom->sched_priority;
2958
+ bool slot_became_unblocked;
27772959 bool timer_sync = false;
27782960 bool context_idle = false;
27792961 unsigned long flags;
27802962 base_jd_core_req core_req = katom->core_req;
2963
+ u64 cache_jc = katom->jc;
27812964
27822965 dev_dbg(kbdev->dev, "%s for atom %pK with event code 0x%x\n",
27832966 __func__, (void *)katom, katom->event_code);
2967
+
2968
+ KBASE_KTRACE_ADD_JM(kbdev, JS_RETURN_WORKER, kctx, katom, katom->jc, 0);
27842969
27852970 if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
27862971 KBASE_TLSTREAM_TL_EVENT_ATOM_SOFTSTOP_EX(kbdev, katom);
....@@ -2792,37 +2977,27 @@
27922977 mutex_lock(&js_devdata->queue_mutex);
27932978 mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
27942979
2795
- atomic_dec(&kctx->atoms_pulled);
2796
- atomic_dec(&kctx->atoms_pulled_slot[js]);
2797
-
27982980 if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
27992981 atomic_dec(&katom->blocked);
28002982
28012983 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
28022984
2803
- kctx->atoms_pulled_slot_pri[js][katom->sched_priority]--;
2985
+ slot_became_unblocked = kbase_jsctx_slot_atom_pulled_dec(kctx, katom);
28042986
2805
- if (!atomic_read(&kctx->atoms_pulled_slot[js]) &&
2806
- jsctx_rb_none_to_pull(kctx, js))
2987
+ if (!kbase_jsctx_slot_atoms_pulled(kctx, js) &&
2988
+ jsctx_rb_none_to_pull(kctx, js))
28072989 timer_sync |= kbase_js_ctx_list_remove_nolock(kbdev, kctx, js);
28082990
2809
- /* If this slot has been blocked due to soft-stopped atoms, and all
2810
- * atoms have now been processed, then unblock the slot
2991
+ /* If the context is now unblocked on this slot after soft-stopped
2992
+ * atoms, then only mark it as pullable on this slot if it is not
2993
+ * idle
28112994 */
2812
- if (!kctx->atoms_pulled_slot_pri[js][prio] &&
2813
- kctx->blocked_js[js][prio]) {
2814
- kctx->blocked_js[js][prio] = false;
2995
+ if (slot_became_unblocked && kbase_jsctx_atoms_pulled(kctx) &&
2996
+ kbase_js_ctx_pullable(kctx, js, true))
2997
+ timer_sync |=
2998
+ kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx, js);
28152999
2816
- /* Only mark the slot as pullable if the context is not idle -
2817
- * that case is handled below
2818
- */
2819
- if (atomic_read(&kctx->atoms_pulled) &&
2820
- kbase_js_ctx_pullable(kctx, js, true))
2821
- timer_sync |= kbase_js_ctx_list_add_pullable_nolock(
2822
- kbdev, kctx, js);
2823
- }
2824
-
2825
- if (!atomic_read(&kctx->atoms_pulled)) {
3000
+ if (!kbase_jsctx_atoms_pulled(kctx)) {
28263001 dev_dbg(kbdev->dev,
28273002 "No atoms currently pulled from context %pK\n",
28283003 (void *)kctx);
....@@ -2890,7 +3065,6 @@
28903065 mutex_unlock(&kctx->jctx.lock);
28913066 }
28923067
2893
- katom->atom_flags &= ~KBASE_KATOM_FLAG_HOLDING_CTX_REF;
28943068 dev_dbg(kbdev->dev, "JS: retained state %s finished",
28953069 kbasep_js_has_atom_finished(&retained_state) ?
28963070 "has" : "hasn't");
....@@ -2903,6 +3077,9 @@
29033077 kbase_js_sched_all(kbdev);
29043078
29053079 kbase_backend_complete_wq_post_sched(kbdev, core_req);
3080
+
3081
+ KBASE_KTRACE_ADD_JM(kbdev, JS_RETURN_WORKER_END, kctx, NULL, cache_jc,
3082
+ 0);
29063083
29073084 dev_dbg(kbdev->dev, "Leaving %s for atom %pK\n",
29083085 __func__, (void *)katom);
....@@ -3113,15 +3290,16 @@
31133290 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
31143291
31153292 if (katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE) {
3293
+ bool slot_became_unblocked;
3294
+
31163295 dev_dbg(kbdev->dev, "Atom %pK is in runnable_tree\n",
31173296 (void *)katom);
31183297
3119
- context_idle = !atomic_dec_return(&kctx->atoms_pulled);
3120
- atomic_dec(&kctx->atoms_pulled_slot[atom_slot]);
3121
- kctx->atoms_pulled_slot_pri[atom_slot][prio]--;
3298
+ slot_became_unblocked =
3299
+ kbase_jsctx_slot_atom_pulled_dec(kctx, katom);
3300
+ context_idle = !kbase_jsctx_atoms_pulled(kctx);
31223301
3123
- if (!atomic_read(&kctx->atoms_pulled) &&
3124
- !kctx->slots_pullable) {
3302
+ if (!kbase_jsctx_atoms_pulled(kctx) && !kctx->slots_pullable) {
31253303 WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
31263304 kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
31273305 atomic_dec(&kbdev->js_data.nr_contexts_runnable);
....@@ -3129,15 +3307,14 @@
31293307 }
31303308
31313309 /* If this slot has been blocked due to soft-stopped atoms, and
3132
- * all atoms have now been processed, then unblock the slot
3310
+ * all atoms have now been processed at this priority level and
3311
+ * higher, then unblock the slot
31333312 */
3134
- if (!kctx->atoms_pulled_slot_pri[atom_slot][prio]
3135
- && kctx->blocked_js[atom_slot][prio]) {
3313
+ if (slot_became_unblocked) {
31363314 dev_dbg(kbdev->dev,
3137
- "kctx %pK is no longer blocked from submitting on slot %d at priority %d\n",
3315
+ "kctx %pK is no longer blocked from submitting on slot %d at priority %d or higher\n",
31383316 (void *)kctx, atom_slot, prio);
31393317
3140
- kctx->blocked_js[atom_slot][prio] = false;
31413318 if (kbase_js_ctx_pullable(kctx, atom_slot, true))
31423319 timer_sync |=
31433320 kbase_js_ctx_list_add_pullable_nolock(
....@@ -3146,8 +3323,8 @@
31463323 }
31473324 WARN_ON(!(katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE));
31483325
3149
- if (!atomic_read(&kctx->atoms_pulled_slot[atom_slot]) &&
3150
- jsctx_rb_none_to_pull(kctx, atom_slot)) {
3326
+ if (!kbase_jsctx_slot_atoms_pulled(kctx, atom_slot) &&
3327
+ jsctx_rb_none_to_pull(kctx, atom_slot)) {
31513328 if (!list_empty(
31523329 &kctx->jctx.sched_info.ctx.ctx_list_entry[atom_slot]))
31533330 timer_sync |= kbase_js_ctx_list_remove_nolock(
....@@ -3160,9 +3337,9 @@
31603337 * re-enable submission so that context can be scheduled again.
31613338 */
31623339 if (!kbasep_js_is_submit_allowed(js_devdata, kctx) &&
3163
- !atomic_read(&kctx->atoms_pulled) &&
3164
- !kbase_ctx_flag(kctx, KCTX_DYING)) {
3165
- int js;
3340
+ !kbase_jsctx_atoms_pulled(kctx) &&
3341
+ !kbase_ctx_flag(kctx, KCTX_DYING)) {
3342
+ unsigned int js;
31663343
31673344 kbasep_js_set_submit_allowed(js_devdata, kctx);
31683345
....@@ -3174,7 +3351,7 @@
31743351 }
31753352 } else if (katom->x_post_dep &&
31763353 kbasep_js_is_submit_allowed(js_devdata, kctx)) {
3177
- int js;
3354
+ unsigned int js;
31783355
31793356 for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
31803357 if (kbase_js_ctx_pullable(kctx, js, true))
....@@ -3285,6 +3462,11 @@
32853462
32863463 katom->status = KBASE_JD_ATOM_STATE_HW_COMPLETED;
32873464 dev_dbg(kbdev->dev, "Atom %pK status to HW completed\n", (void *)katom);
3465
+ if (kbase_is_quick_reset_enabled(kbdev)) {
3466
+ kbdev->num_of_atoms_hw_completed++;
3467
+ if (kbdev->num_of_atoms_hw_completed >= 20)
3468
+ kbase_disable_quick_reset(kbdev);
3469
+ }
32883470
32893471 if (katom->event_code != BASE_JD_EVENT_DONE) {
32903472 kbase_js_evict_deps(kctx, katom, katom->slot_nr,
....@@ -3297,7 +3479,9 @@
32973479 trace_sysgraph_gpu(SGR_COMPLETE, kctx->id,
32983480 kbase_jd_atom_id(katom->kctx, katom), katom->slot_nr);
32993481
3482
+ KBASE_TLSTREAM_TL_JD_DONE_START(kbdev, katom);
33003483 kbase_jd_done(katom, katom->slot_nr, end_timestamp, 0);
3484
+ KBASE_TLSTREAM_TL_JD_DONE_END(kbdev, katom);
33013485
33023486 /* Unblock cross dependency if present */
33033487 if (x_dep && (katom->event_code == BASE_JD_EVENT_DONE ||
....@@ -3397,13 +3581,15 @@
33973581 return false;
33983582 }
33993583
3400
-void kbase_js_sched(struct kbase_device *kbdev, int js_mask)
3584
+void kbase_js_sched(struct kbase_device *kbdev, unsigned int js_mask)
34013585 {
34023586 struct kbasep_js_device_data *js_devdata;
34033587 struct kbase_context *last_active[BASE_JM_MAX_NR_SLOTS];
34043588 bool timer_sync = false;
34053589 bool ctx_waiting[BASE_JM_MAX_NR_SLOTS];
3406
- int js;
3590
+ unsigned int js;
3591
+
3592
+ KBASE_TLSTREAM_TL_JS_SCHED_START(kbdev, 0);
34073593
34083594 dev_dbg(kbdev->dev, "%s kbdev %pK mask 0x%x\n",
34093595 __func__, (void *)kbdev, (unsigned int)js_mask);
....@@ -3430,24 +3616,20 @@
34303616
34313617 if (!kctx) {
34323618 js_mask &= ~(1 << js);
3433
- dev_dbg(kbdev->dev,
3434
- "No kctx on pullable list (s:%d)\n",
3435
- js);
3619
+ dev_dbg(kbdev->dev, "No kctx on pullable list (s:%u)\n", js);
34363620 break;
34373621 }
34383622
34393623 if (!kbase_ctx_flag(kctx, KCTX_ACTIVE)) {
34403624 context_idle = true;
34413625
3442
- dev_dbg(kbdev->dev,
3443
- "kctx %pK is not active (s:%d)\n",
3444
- (void *)kctx, js);
3626
+ dev_dbg(kbdev->dev, "kctx %pK is not active (s:%u)\n", (void *)kctx,
3627
+ js);
34453628
34463629 if (kbase_pm_context_active_handle_suspend(
34473630 kbdev,
34483631 KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
3449
- dev_dbg(kbdev->dev,
3450
- "Suspend pending (s:%d)\n", js);
3632
+ dev_dbg(kbdev->dev, "Suspend pending (s:%u)\n", js);
34513633 /* Suspend pending - return context to
34523634 * queue and stop scheduling
34533635 */
....@@ -3460,6 +3642,8 @@
34603642 &kctx->jctx.sched_info.ctx.jsctx_mutex);
34613643 mutex_unlock(&js_devdata->queue_mutex);
34623644 up(&js_devdata->schedule_sem);
3645
+ KBASE_TLSTREAM_TL_JS_SCHED_END(kbdev,
3646
+ 0);
34633647 return;
34643648 }
34653649 kbase_ctx_flag_set(kctx, KCTX_ACTIVE);
....@@ -3503,16 +3687,13 @@
35033687 kbase_ctx_flag_clear(kctx, KCTX_PULLED);
35043688
35053689 if (!kbase_jm_kick(kbdev, 1 << js)) {
3506
- dev_dbg(kbdev->dev,
3507
- "No more jobs can be submitted (s:%d)\n",
3508
- js);
3690
+ dev_dbg(kbdev->dev, "No more jobs can be submitted (s:%u)\n", js);
35093691 js_mask &= ~(1 << js);
35103692 }
35113693 if (!kbase_ctx_flag(kctx, KCTX_PULLED)) {
35123694 bool pullable;
35133695
3514
- dev_dbg(kbdev->dev,
3515
- "No atoms pulled from kctx %pK (s:%d)\n",
3696
+ dev_dbg(kbdev->dev, "No atoms pulled from kctx %pK (s:%u)\n",
35163697 (void *)kctx, js);
35173698
35183699 pullable = kbase_js_ctx_pullable(kctx, js,
....@@ -3596,14 +3777,15 @@
35963777 for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
35973778 if (kbdev->hwaccess.active_kctx[js] == last_active[js] &&
35983779 ctx_waiting[js]) {
3599
- dev_dbg(kbdev->dev, "Marking kctx %pK as inactive (s:%d)\n",
3600
- (void *)last_active[js], js);
3780
+ dev_dbg(kbdev->dev, "Marking kctx %pK as inactive (s:%u)\n",
3781
+ (void *)last_active[js], js);
36013782 kbdev->hwaccess.active_kctx[js] = NULL;
36023783 }
36033784 }
36043785
36053786 mutex_unlock(&js_devdata->queue_mutex);
36063787 up(&js_devdata->schedule_sem);
3788
+ KBASE_TLSTREAM_TL_JS_SCHED_END(kbdev, 0);
36073789 }
36083790
36093791 void kbase_js_zap_context(struct kbase_context *kctx)
....@@ -3667,7 +3849,7 @@
36673849 */
36683850 if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED)) {
36693851 unsigned long flags;
3670
- int js;
3852
+ unsigned int js;
36713853
36723854 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
36733855 for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
....@@ -3707,6 +3889,7 @@
37073889 } else {
37083890 unsigned long flags;
37093891 bool was_retained;
3892
+ CSTD_UNUSED(was_retained);
37103893
37113894 /* Case c: didn't evict, but it is scheduled - it's in the Run
37123895 * Pool
....@@ -3719,7 +3902,7 @@
37193902
37203903 kbasep_js_clear_submit_allowed(js_devdata, kctx);
37213904
3722
- /* Retain and (later) release the context whilst it is is now
3905
+ /* Retain and (later) release the context whilst it is now
37233906 * disallowed from submitting jobs - ensures that someone
37243907 * somewhere will be removing the context later on
37253908 */
....@@ -3790,7 +3973,7 @@
37903973 {
37913974 struct kbase_device *kbdev;
37923975 unsigned long flags;
3793
- u32 js;
3976
+ unsigned int js;
37943977
37953978 kbdev = kctx->kbdev;
37963979
....@@ -3810,13 +3993,15 @@
38103993 {
38113994 struct priority_control_manager_device *pcm_device = kbdev->pcm_dev;
38123995 int req_priority, out_priority;
3813
- base_jd_prio out_jd_priority = priority;
38143996
3815
- if (pcm_device) {
3816
- req_priority = kbasep_js_atom_prio_to_sched_prio(priority);
3817
- out_priority = pcm_device->ops.pcm_scheduler_priority_check(pcm_device, current, req_priority);
3818
- out_jd_priority = kbasep_js_sched_prio_to_atom_prio(out_priority);
3819
- }
3820
- return out_jd_priority;
3997
+ req_priority = kbasep_js_atom_prio_to_sched_prio(priority);
3998
+ out_priority = req_priority;
3999
+ /* Does not use pcm defined priority check if PCM not defined or if
4000
+ * kbasep_js_atom_prio_to_sched_prio returns an error
4001
+ * (KBASE_JS_ATOM_SCHED_PRIO_INVALID).
4002
+ */
4003
+ if (pcm_device && (req_priority != KBASE_JS_ATOM_SCHED_PRIO_INVALID))
4004
+ out_priority = pcm_device->ops.pcm_scheduler_priority_check(pcm_device, current,
4005
+ req_priority);
4006
+ return kbasep_js_sched_prio_to_atom_prio(kbdev, out_priority);
38214007 }
3822
-