1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3  *
4  * (C) COPYRIGHT 2011-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 /*
23  * Job Scheduler Implementation
24  */
25 #include <mali_kbase.h>
26 #include <mali_kbase_js.h>
27 #include <tl/mali_kbase_tracepoints.h>
28 #include <mali_linux_trace.h>
29 #include <mali_kbase_hw.h>
30 #include <mali_kbase_ctx_sched.h>
31 
32 #include <mali_kbase_defs.h>
33 #include <mali_kbase_config_defaults.h>
34 
35 #include "mali_kbase_jm.h"
36 #include "mali_kbase_hwaccess_jm.h"
37 #include <linux/priority_control_manager.h>
38 
39 /*
40  * Private types
41  */
42 
43 /* Bitpattern indicating the result of releasing a context */
44 enum {
45 	/* The context was descheduled - caller should try scheduling in a new
46 	 * one to keep the runpool full
47 	 */
48 	KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED = (1u << 0),
49 	/* Ctx attributes were changed - caller should try scheduling all
50 	 * contexts
51 	 */
52 	KBASEP_JS_RELEASE_RESULT_SCHED_ALL = (1u << 1)
53 };
54 
55 typedef u32 kbasep_js_release_result;
56 
57 const int kbasep_js_atom_priority_to_relative[BASE_JD_NR_PRIO_LEVELS] = {
58 	KBASE_JS_ATOM_SCHED_PRIO_MED,      /* BASE_JD_PRIO_MEDIUM */
59 	KBASE_JS_ATOM_SCHED_PRIO_HIGH,     /* BASE_JD_PRIO_HIGH */
60 	KBASE_JS_ATOM_SCHED_PRIO_LOW,      /* BASE_JD_PRIO_LOW */
61 	KBASE_JS_ATOM_SCHED_PRIO_REALTIME  /* BASE_JD_PRIO_REALTIME */
62 };
63 
64 const base_jd_prio
65 kbasep_js_relative_priority_to_atom[KBASE_JS_ATOM_SCHED_PRIO_COUNT] = {
66 	BASE_JD_PRIO_REALTIME,   /* KBASE_JS_ATOM_SCHED_PRIO_REALTIME */
67 	BASE_JD_PRIO_HIGH,       /* KBASE_JS_ATOM_SCHED_PRIO_HIGH */
68 	BASE_JD_PRIO_MEDIUM,     /* KBASE_JS_ATOM_SCHED_PRIO_MED */
69 	BASE_JD_PRIO_LOW         /* KBASE_JS_ATOM_SCHED_PRIO_LOW */
70 };
71 
72 
73 /*
74  * Private function prototypes
75  */
76 static kbasep_js_release_result kbasep_js_runpool_release_ctx_internal(
77 		struct kbase_device *kbdev, struct kbase_context *kctx,
78 		struct kbasep_js_atom_retained_state *katom_retained_state);
79 
80 static int kbase_js_get_slot(struct kbase_device *kbdev,
81 				struct kbase_jd_atom *katom);
82 
83 static void kbase_js_foreach_ctx_job(struct kbase_context *kctx,
84 				     kbasep_js_ctx_job_cb *callback);
85 
86 /* Helper for ktrace */
87 #if KBASE_KTRACE_ENABLE
kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)88 static int kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)
89 {
90 	return atomic_read(&kctx->refcount);
91 }
92 #else /* KBASE_KTRACE_ENABLE  */
kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)93 static int kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)
94 {
95 	CSTD_UNUSED(kctx);
96 	return 0;
97 }
98 #endif /* KBASE_KTRACE_ENABLE  */
99 
100 /*
101  * Private functions
102  */
103 
104 /**
105  * core_reqs_from_jsn_features - Convert JSn_FEATURES to core requirements
106  * @features: JSn_FEATURE register value
107  *
108  * Given a JSn_FEATURE register value returns the core requirements that match
109  *
110  * Return: Core requirement bit mask
111  */
core_reqs_from_jsn_features(u16 features)112 static base_jd_core_req core_reqs_from_jsn_features(u16 features)
113 {
114 	base_jd_core_req core_req = 0u;
115 
116 	if ((features & JS_FEATURE_SET_VALUE_JOB) != 0)
117 		core_req |= BASE_JD_REQ_V;
118 
119 	if ((features & JS_FEATURE_CACHE_FLUSH_JOB) != 0)
120 		core_req |= BASE_JD_REQ_CF;
121 
122 	if ((features & JS_FEATURE_COMPUTE_JOB) != 0)
123 		core_req |= BASE_JD_REQ_CS;
124 
125 	if ((features & JS_FEATURE_TILER_JOB) != 0)
126 		core_req |= BASE_JD_REQ_T;
127 
128 	if ((features & JS_FEATURE_FRAGMENT_JOB) != 0)
129 		core_req |= BASE_JD_REQ_FS;
130 
131 	return core_req;
132 }
133 
kbase_js_sync_timers(struct kbase_device *kbdev)134 static void kbase_js_sync_timers(struct kbase_device *kbdev)
135 {
136 	mutex_lock(&kbdev->js_data.runpool_mutex);
137 	kbase_backend_ctx_count_changed(kbdev);
138 	mutex_unlock(&kbdev->js_data.runpool_mutex);
139 }
140 
141 /**
142  * jsctx_rb_none_to_pull_prio(): - Check if there are no pullable atoms
143  * @kctx: Pointer to kbase context with ring buffer.
144  * @js:   Job slot id to check.
145  * @prio: Priority to check.
146  *
147  * Return true if there are no atoms to pull. There may be running atoms in the
148  * ring buffer even if there are no atoms to pull. It is also possible for the
149  * ring buffer to be full (with running atoms) when this functions returns
150  * true.
151  *
152  * Return: true if there are no atoms to pull, false otherwise.
153  */
154 static inline bool
jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, int js, int prio)155 jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, int js, int prio)
156 {
157 	bool none_to_pull;
158 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
159 
160 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
161 
162 	none_to_pull = RB_EMPTY_ROOT(&rb->runnable_tree);
163 
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);
167 
168 	return none_to_pull;
169 }
170 
171 /**
172  * jsctx_rb_none_to_pull(): - Check if all priority ring buffers have no
173  * pullable atoms
174  * @kctx: Pointer to kbase context with ring buffer.
175  * @js:   Job slot id to check.
176  *
177  * Caller must hold hwaccess_lock
178  *
179  * Return: true if the ring buffers for all priorities have no pullable atoms,
180  *	   false otherwise.
181  */
182 static inline bool
jsctx_rb_none_to_pull(struct kbase_context *kctx, int js)183 jsctx_rb_none_to_pull(struct kbase_context *kctx, int js)
184 {
185 	int prio;
186 
187 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
188 
189 	for (prio = KBASE_JS_ATOM_SCHED_PRIO_FIRST;
190 		prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
191 		if (!jsctx_rb_none_to_pull_prio(kctx, js, prio))
192 			return false;
193 	}
194 
195 	return true;
196 }
197 
198 /**
199  * jsctx_queue_foreach_prio(): - Execute callback for each entry in the queue.
200  * @kctx:     Pointer to kbase context with the queue.
201  * @js:       Job slot id to iterate.
202  * @prio:     Priority id to iterate.
203  * @callback: Function pointer to callback.
204  *
205  * Iterate over a queue and invoke @callback for each entry in the queue, and
206  * remove the entry from the queue.
207  *
208  * If entries are added to the queue while this is running those entries may, or
209  * may not be covered. To ensure that all entries in the buffer have been
210  * enumerated when this function returns jsctx->lock must be held when calling
211  * this function.
212  *
213  * The HW access lock must always be held when calling this function.
214  */
jsctx_queue_foreach_prio(struct kbase_context *kctx, int js, int prio, kbasep_js_ctx_job_cb *callback)215 static void jsctx_queue_foreach_prio(struct kbase_context *kctx, int js,
216 				     int prio, kbasep_js_ctx_job_cb *callback)
217 {
218 	struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
219 
220 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
221 
222 	while (!RB_EMPTY_ROOT(&queue->runnable_tree)) {
223 		struct rb_node *node = rb_first(&queue->runnable_tree);
224 		struct kbase_jd_atom *entry = rb_entry(node,
225 				struct kbase_jd_atom, runnable_tree_node);
226 
227 		rb_erase(node, &queue->runnable_tree);
228 		callback(kctx->kbdev, entry);
229 
230 		/* Runnable end-of-renderpass atoms can also be in the linked
231 		 * list of atoms blocked on cross-slot dependencies. Remove them
232 		 * to avoid calling the callback twice.
233 		 */
234 		if (entry->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST) {
235 			WARN_ON(!(entry->core_req &
236 				BASE_JD_REQ_END_RENDERPASS));
237 			dev_dbg(kctx->kbdev->dev,
238 				"Del runnable atom %pK from X_DEP list\n",
239 				(void *)entry);
240 
241 			list_del(&entry->queue);
242 			entry->atom_flags &=
243 					~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
244 		}
245 	}
246 
247 	while (!list_empty(&queue->x_dep_head)) {
248 		struct kbase_jd_atom *entry = list_entry(queue->x_dep_head.next,
249 				struct kbase_jd_atom, queue);
250 
251 		WARN_ON(!(entry->atom_flags &
252 			KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST));
253 		dev_dbg(kctx->kbdev->dev,
254 			"Del blocked atom %pK from X_DEP list\n",
255 			(void *)entry);
256 
257 		list_del(queue->x_dep_head.next);
258 		entry->atom_flags &=
259 				~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
260 
261 		callback(kctx->kbdev, entry);
262 	}
263 }
264 
265 /**
266  * jsctx_queue_foreach(): - Execute callback for each entry in every queue
267  * @kctx:     Pointer to kbase context with queue.
268  * @js:       Job slot id to iterate.
269  * @callback: Function pointer to callback.
270  *
271  * Iterate over all the different priorities, and for each call
272  * jsctx_queue_foreach_prio() to iterate over the queue and invoke @callback
273  * for each entry, and remove the entry from the queue.
274  */
jsctx_queue_foreach(struct kbase_context *kctx, int js, kbasep_js_ctx_job_cb *callback)275 static inline void jsctx_queue_foreach(struct kbase_context *kctx, int js,
276 				       kbasep_js_ctx_job_cb *callback)
277 {
278 	int prio;
279 
280 	for (prio = KBASE_JS_ATOM_SCHED_PRIO_FIRST;
281 		prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++)
282 		jsctx_queue_foreach_prio(kctx, js, prio, callback);
283 }
284 
285 /**
286  * jsctx_rb_peek_prio(): - Check buffer and get next atom
287  * @kctx: Pointer to kbase context with ring buffer.
288  * @js:   Job slot id to check.
289  * @prio: Priority id to check.
290  *
291  * Check the ring buffer for the specified @js and @prio and return a pointer to
292  * the next atom, unless the ring buffer is empty.
293  *
294  * Return: Pointer to next atom in buffer, or NULL if there is no atom.
295  */
296 static inline struct kbase_jd_atom *
jsctx_rb_peek_prio(struct kbase_context *kctx, int js, int prio)297 jsctx_rb_peek_prio(struct kbase_context *kctx, int js, int prio)
298 {
299 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
300 	struct rb_node *node;
301 
302 	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",
305 		(void *)kctx, prio, js);
306 
307 	node = rb_first(&rb->runnable_tree);
308 	if (!node) {
309 		dev_dbg(kctx->kbdev->dev, "Tree is empty\n");
310 		return NULL;
311 	}
312 
313 	return rb_entry(node, struct kbase_jd_atom, runnable_tree_node);
314 }
315 
316 /**
317  * jsctx_rb_peek(): - Check all priority buffers and get next atom
318  * @kctx: Pointer to kbase context with ring buffer.
319  * @js:   Job slot id to check.
320  *
321  * Check the ring buffers for all priorities, starting from
322  * KBASE_JS_ATOM_SCHED_PRIO_REALTIME, for the specified @js and @prio and return a
323  * pointer to the next atom, unless all the priority's ring buffers are empty.
324  *
325  * Caller must hold the hwaccess_lock.
326  *
327  * Return: Pointer to next atom in buffer, or NULL if there is no atom.
328  */
329 static inline struct kbase_jd_atom *
jsctx_rb_peek(struct kbase_context *kctx, int js)330 jsctx_rb_peek(struct kbase_context *kctx, int js)
331 {
332 	int prio;
333 
334 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
335 
336 	for (prio = KBASE_JS_ATOM_SCHED_PRIO_FIRST;
337 		prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
338 		struct kbase_jd_atom *katom;
339 
340 		katom = jsctx_rb_peek_prio(kctx, js, prio);
341 		if (katom)
342 			return katom;
343 	}
344 
345 	return NULL;
346 }
347 
348 /**
349  * jsctx_rb_pull(): - Mark atom in list as running
350  * @kctx:  Pointer to kbase context with ring buffer.
351  * @katom: Pointer to katom to pull.
352  *
353  * Mark an atom previously obtained from jsctx_rb_peek() as running.
354  *
355  * @katom must currently be at the head of the ring buffer.
356  */
357 static inline void
jsctx_rb_pull(struct kbase_context *kctx, struct kbase_jd_atom *katom)358 jsctx_rb_pull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
359 {
360 	int prio = katom->sched_priority;
361 	int js = katom->slot_nr;
362 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
363 
364 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
365 
366 	dev_dbg(kctx->kbdev->dev, "Erasing atom %pK from runnable tree of kctx %pK\n",
367 		(void *)katom, (void *)kctx);
368 
369 	/* Atoms must be pulled in the correct order. */
370 	WARN_ON(katom != jsctx_rb_peek_prio(kctx, js, prio));
371 
372 	rb_erase(&katom->runnable_tree_node, &rb->runnable_tree);
373 }
374 
375 static void
jsctx_tree_add(struct kbase_context *kctx, struct kbase_jd_atom *katom)376 jsctx_tree_add(struct kbase_context *kctx, struct kbase_jd_atom *katom)
377 {
378 	struct kbase_device *kbdev = kctx->kbdev;
379 	int prio = katom->sched_priority;
380 	int js = katom->slot_nr;
381 	struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
382 	struct rb_node **new = &(queue->runnable_tree.rb_node), *parent = NULL;
383 
384 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
385 
386 	dev_dbg(kbdev->dev, "Adding atom %pK to runnable tree of kctx %pK (s:%d)\n",
387 		(void *)katom, (void *)kctx, js);
388 
389 	while (*new) {
390 		struct kbase_jd_atom *entry = container_of(*new,
391 				struct kbase_jd_atom, runnable_tree_node);
392 
393 		parent = *new;
394 		if (kbase_jd_atom_is_younger(katom, entry))
395 			new = &((*new)->rb_left);
396 		else
397 			new = &((*new)->rb_right);
398 	}
399 
400 	/* Add new node and rebalance tree. */
401 	rb_link_node(&katom->runnable_tree_node, parent, new);
402 	rb_insert_color(&katom->runnable_tree_node, &queue->runnable_tree);
403 
404 	KBASE_TLSTREAM_TL_ATTRIB_ATOM_STATE(kbdev, katom, TL_ATOM_STATE_READY);
405 }
406 
407 /**
408  * jsctx_rb_unpull(): - Undo marking of atom in list as running
409  * @kctx:  Pointer to kbase context with ring buffer.
410  * @katom: Pointer to katom to unpull.
411  *
412  * Undo jsctx_rb_pull() and put @katom back in the queue.
413  *
414  * jsctx_rb_unpull() must be called on atoms in the same order the atoms were
415  * pulled.
416  */
417 static inline void
jsctx_rb_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)418 jsctx_rb_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
419 {
420 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
421 
422 	KBASE_KTRACE_ADD_JM(kctx->kbdev, JS_UNPULL_JOB, kctx, katom, katom->jc,
423 			    0u);
424 
425 	jsctx_tree_add(kctx, katom);
426 }
427 
428 static bool kbase_js_ctx_pullable(struct kbase_context *kctx,
429 					int js,
430 					bool is_scheduled);
431 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
432 						struct kbase_context *kctx,
433 						int js);
434 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
435 						struct kbase_context *kctx,
436 						int js);
437 
438 typedef bool(katom_ordering_func)(const struct kbase_jd_atom *,
439 				  const struct kbase_jd_atom *);
440 
kbase_js_atom_runs_before(struct kbase_device *kbdev, const struct kbase_jd_atom *katom_a, const struct kbase_jd_atom *katom_b, const kbase_atom_ordering_flag_t order_flags)441 bool kbase_js_atom_runs_before(struct kbase_device *kbdev,
442 			       const struct kbase_jd_atom *katom_a,
443 			       const struct kbase_jd_atom *katom_b,
444 			       const kbase_atom_ordering_flag_t order_flags)
445 {
446 	struct kbase_context *kctx_a = katom_a->kctx;
447 	struct kbase_context *kctx_b = katom_b->kctx;
448 	katom_ordering_func *samectxatomprio_ordering_func =
449 		kbase_jd_atom_is_younger;
450 
451 	lockdep_assert_held(&kbdev->hwaccess_lock);
452 
453 	if (order_flags & KBASE_ATOM_ORDERING_FLAG_SEQNR)
454 		samectxatomprio_ordering_func = kbase_jd_atom_is_earlier;
455 
456 	/* It only makes sense to make this test for atoms on the same slot */
457 	WARN_ON(katom_a->slot_nr != katom_b->slot_nr);
458 
459 	if (kbdev->js_ctx_scheduling_mode ==
460 	    KBASE_JS_PROCESS_LOCAL_PRIORITY_MODE) {
461 		/* In local priority mode, querying either way around for "a
462 		 * should run before b" and "b should run before a" should
463 		 * always be false when they're from different contexts
464 		 */
465 		if (kctx_a != kctx_b)
466 			return false;
467 	} else {
468 		/* In system priority mode, ordering is done first strictly by
469 		 * context priority, even when katom_b might be lower priority
470 		 * than katom_a. This is due to scheduling of contexts in order
471 		 * of highest priority first, regardless of whether the atoms
472 		 * for a particular slot from such contexts have the highest
473 		 * priority or not.
474 		 */
475 		if (kctx_a != kctx_b) {
476 			if (kctx_a->priority < kctx_b->priority)
477 				return true;
478 			if (kctx_a->priority > kctx_b->priority)
479 				return false;
480 		}
481 	}
482 
483 	/* For same contexts/contexts with the same context priority (in system
484 	 * priority mode), ordering is next done by atom priority
485 	 */
486 	if (katom_a->sched_priority < katom_b->sched_priority)
487 		return true;
488 	if (katom_a->sched_priority > katom_b->sched_priority)
489 		return false;
490 	/* For atoms of same priority on the same kctx, they are
491 	 * ordered by seq_nr/age (dependent on caller)
492 	 */
493 	if (kctx_a == kctx_b && samectxatomprio_ordering_func(katom_a, katom_b))
494 		return true;
495 
496 	return false;
497 }
498 
499 /*
500  * Functions private to KBase ('Protected' functions)
501  */
kbasep_js_devdata_init(struct kbase_device * const kbdev)502 int kbasep_js_devdata_init(struct kbase_device * const kbdev)
503 {
504 	struct kbasep_js_device_data *jsdd;
505 	int i, j;
506 
507 	KBASE_DEBUG_ASSERT(kbdev != NULL);
508 
509 	jsdd = &kbdev->js_data;
510 
511 #ifdef CONFIG_MALI_BIFROST_DEBUG
512 	/* Soft-stop will be disabled on a single context by default unless
513 	 * softstop_always is set
514 	 */
515 	jsdd->softstop_always = false;
516 #endif				/* CONFIG_MALI_BIFROST_DEBUG */
517 	jsdd->nr_all_contexts_running = 0;
518 	jsdd->nr_user_contexts_running = 0;
519 	jsdd->nr_contexts_pullable = 0;
520 	atomic_set(&jsdd->nr_contexts_runnable, 0);
521 	/* No ctx allowed to submit */
522 	jsdd->runpool_irq.submit_allowed = 0u;
523 	memset(jsdd->runpool_irq.ctx_attr_ref_count, 0,
524 			sizeof(jsdd->runpool_irq.ctx_attr_ref_count));
525 	memset(jsdd->runpool_irq.slot_affinities, 0,
526 			sizeof(jsdd->runpool_irq.slot_affinities));
527 	memset(jsdd->runpool_irq.slot_affinity_refcount, 0,
528 			sizeof(jsdd->runpool_irq.slot_affinity_refcount));
529 	INIT_LIST_HEAD(&jsdd->suspended_soft_jobs_list);
530 
531 	/* Config attributes */
532 	jsdd->scheduling_period_ns = DEFAULT_JS_SCHEDULING_PERIOD_NS;
533 	jsdd->soft_stop_ticks = DEFAULT_JS_SOFT_STOP_TICKS;
534 	jsdd->soft_stop_ticks_cl = DEFAULT_JS_SOFT_STOP_TICKS_CL;
535 	jsdd->hard_stop_ticks_ss = DEFAULT_JS_HARD_STOP_TICKS_SS;
536 	jsdd->hard_stop_ticks_cl = DEFAULT_JS_HARD_STOP_TICKS_CL;
537 	jsdd->hard_stop_ticks_dumping = DEFAULT_JS_HARD_STOP_TICKS_DUMPING;
538 	jsdd->gpu_reset_ticks_ss = DEFAULT_JS_RESET_TICKS_SS;
539 	jsdd->gpu_reset_ticks_cl = DEFAULT_JS_RESET_TICKS_CL;
540 
541 	jsdd->gpu_reset_ticks_dumping = DEFAULT_JS_RESET_TICKS_DUMPING;
542 	jsdd->ctx_timeslice_ns = DEFAULT_JS_CTX_TIMESLICE_NS;
543 	atomic_set(&jsdd->soft_job_timeout_ms, DEFAULT_JS_SOFT_JOB_TIMEOUT);
544 
545 	dev_dbg(kbdev->dev, "JS Config Attribs: ");
546 	dev_dbg(kbdev->dev, "\tscheduling_period_ns:%u",
547 			jsdd->scheduling_period_ns);
548 	dev_dbg(kbdev->dev, "\tsoft_stop_ticks:%u",
549 			jsdd->soft_stop_ticks);
550 	dev_dbg(kbdev->dev, "\tsoft_stop_ticks_cl:%u",
551 			jsdd->soft_stop_ticks_cl);
552 	dev_dbg(kbdev->dev, "\thard_stop_ticks_ss:%u",
553 			jsdd->hard_stop_ticks_ss);
554 	dev_dbg(kbdev->dev, "\thard_stop_ticks_cl:%u",
555 			jsdd->hard_stop_ticks_cl);
556 	dev_dbg(kbdev->dev, "\thard_stop_ticks_dumping:%u",
557 			jsdd->hard_stop_ticks_dumping);
558 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_ss:%u",
559 			jsdd->gpu_reset_ticks_ss);
560 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_cl:%u",
561 			jsdd->gpu_reset_ticks_cl);
562 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_dumping:%u",
563 			jsdd->gpu_reset_ticks_dumping);
564 	dev_dbg(kbdev->dev, "\tctx_timeslice_ns:%u",
565 			jsdd->ctx_timeslice_ns);
566 	dev_dbg(kbdev->dev, "\tsoft_job_timeout:%i",
567 		atomic_read(&jsdd->soft_job_timeout_ms));
568 
569 	if (!(jsdd->soft_stop_ticks < jsdd->hard_stop_ticks_ss &&
570 			jsdd->hard_stop_ticks_ss < jsdd->gpu_reset_ticks_ss &&
571 			jsdd->soft_stop_ticks < jsdd->hard_stop_ticks_dumping &&
572 			jsdd->hard_stop_ticks_dumping <
573 			jsdd->gpu_reset_ticks_dumping)) {
574 		dev_err(kbdev->dev, "Job scheduler timeouts invalid; soft/hard/reset tick counts should be in increasing order\n");
575 		return -EINVAL;
576 	}
577 
578 #if KBASE_DISABLE_SCHEDULING_SOFT_STOPS
579 	dev_dbg(kbdev->dev, "Job Scheduling Soft-stops disabled, ignoring value for soft_stop_ticks==%u at %uns per tick. Other soft-stops may still occur.",
580 			jsdd->soft_stop_ticks,
581 			jsdd->scheduling_period_ns);
582 #endif
583 #if KBASE_DISABLE_SCHEDULING_HARD_STOPS
584 	dev_dbg(kbdev->dev, "Job Scheduling Hard-stops disabled, ignoring values for hard_stop_ticks_ss==%d and hard_stop_ticks_dumping==%u at %uns per tick. Other hard-stops may still occur.",
585 			jsdd->hard_stop_ticks_ss,
586 			jsdd->hard_stop_ticks_dumping,
587 			jsdd->scheduling_period_ns);
588 #endif
589 #if KBASE_DISABLE_SCHEDULING_SOFT_STOPS && KBASE_DISABLE_SCHEDULING_HARD_STOPS
590 	dev_dbg(kbdev->dev, "Note: The JS tick timer (if coded) will still be run, but do nothing.");
591 #endif
592 
593 	for (i = 0; i < kbdev->gpu_props.num_job_slots; ++i)
594 		jsdd->js_reqs[i] = core_reqs_from_jsn_features(
595 			kbdev->gpu_props.props.raw_props.js_features[i]);
596 
597 	/* On error, we could continue on: providing none of the below resources
598 	 * rely on the ones above
599 	 */
600 
601 	mutex_init(&jsdd->runpool_mutex);
602 	mutex_init(&jsdd->queue_mutex);
603 	sema_init(&jsdd->schedule_sem, 1);
604 
605 	for (i = 0; i < kbdev->gpu_props.num_job_slots; ++i) {
606 		for (j = KBASE_JS_ATOM_SCHED_PRIO_FIRST; j < KBASE_JS_ATOM_SCHED_PRIO_COUNT; ++j) {
607 			INIT_LIST_HEAD(&jsdd->ctx_list_pullable[i][j]);
608 			INIT_LIST_HEAD(&jsdd->ctx_list_unpullable[i][j]);
609 		}
610 	}
611 
612 	return 0;
613 }
614 
kbasep_js_devdata_halt(struct kbase_device *kbdev)615 void kbasep_js_devdata_halt(struct kbase_device *kbdev)
616 {
617 	CSTD_UNUSED(kbdev);
618 }
619 
kbasep_js_devdata_term(struct kbase_device *kbdev)620 void kbasep_js_devdata_term(struct kbase_device *kbdev)
621 {
622 	struct kbasep_js_device_data *js_devdata;
623 	s8 zero_ctx_attr_ref_count[KBASEP_JS_CTX_ATTR_COUNT] = { 0, };
624 
625 	KBASE_DEBUG_ASSERT(kbdev != NULL);
626 
627 	js_devdata = &kbdev->js_data;
628 
629 	/* The caller must de-register all contexts before calling this
630 	 */
631 	KBASE_DEBUG_ASSERT(js_devdata->nr_all_contexts_running == 0);
632 	KBASE_DEBUG_ASSERT(memcmp(
633 				  js_devdata->runpool_irq.ctx_attr_ref_count,
634 				  zero_ctx_attr_ref_count,
635 				  sizeof(zero_ctx_attr_ref_count)) == 0);
636 	CSTD_UNUSED(zero_ctx_attr_ref_count);
637 }
638 
kbasep_js_kctx_init(struct kbase_context *const kctx)639 int kbasep_js_kctx_init(struct kbase_context *const kctx)
640 {
641 	struct kbase_device *kbdev;
642 	struct kbasep_js_kctx_info *js_kctx_info;
643 	int i, j;
644 
645 	KBASE_DEBUG_ASSERT(kctx != NULL);
646 
647 	kbdev = kctx->kbdev;
648 	KBASE_DEBUG_ASSERT(kbdev != NULL);
649 
650 	for (i = 0; i < BASE_JM_MAX_NR_SLOTS; ++i)
651 		INIT_LIST_HEAD(&kctx->jctx.sched_info.ctx.ctx_list_entry[i]);
652 
653 	js_kctx_info = &kctx->jctx.sched_info;
654 
655 	kctx->slots_pullable = 0;
656 	js_kctx_info->ctx.nr_jobs = 0;
657 	kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
658 	kbase_ctx_flag_clear(kctx, KCTX_DYING);
659 	memset(js_kctx_info->ctx.ctx_attr_ref_count, 0,
660 			sizeof(js_kctx_info->ctx.ctx_attr_ref_count));
661 
662 	/* Initially, the context is disabled from submission until the create
663 	 * flags are set
664 	 */
665 	kbase_ctx_flag_set(kctx, KCTX_SUBMIT_DISABLED);
666 
667 	/* On error, we could continue on: providing none of the below resources
668 	 * rely on the ones above
669 	 */
670 	mutex_init(&js_kctx_info->ctx.jsctx_mutex);
671 
672 	init_waitqueue_head(&js_kctx_info->ctx.is_scheduled_wait);
673 
674 	for (i = KBASE_JS_ATOM_SCHED_PRIO_FIRST; i < KBASE_JS_ATOM_SCHED_PRIO_COUNT; i++) {
675 		for (j = 0; j < BASE_JM_MAX_NR_SLOTS; j++) {
676 			INIT_LIST_HEAD(&kctx->jsctx_queue[i][j].x_dep_head);
677 			kctx->jsctx_queue[i][j].runnable_tree = RB_ROOT;
678 		}
679 	}
680 
681 	return 0;
682 }
683 
kbasep_js_kctx_term(struct kbase_context *kctx)684 void kbasep_js_kctx_term(struct kbase_context *kctx)
685 {
686 	struct kbase_device *kbdev;
687 	struct kbasep_js_kctx_info *js_kctx_info;
688 	int js;
689 	bool update_ctx_count = false;
690 	unsigned long flags;
691 
692 	KBASE_DEBUG_ASSERT(kctx != NULL);
693 
694 	kbdev = kctx->kbdev;
695 	KBASE_DEBUG_ASSERT(kbdev != NULL);
696 
697 	js_kctx_info = &kctx->jctx.sched_info;
698 
699 	/* The caller must de-register all jobs before calling this */
700 	KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
701 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs == 0);
702 
703 	mutex_lock(&kbdev->js_data.queue_mutex);
704 	mutex_lock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
705 
706 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
707 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++)
708 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
709 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
710 
711 	if (kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF)) {
712 		WARN_ON(atomic_read(&kbdev->js_data.nr_contexts_runnable) <= 0);
713 		atomic_dec(&kbdev->js_data.nr_contexts_runnable);
714 		update_ctx_count = true;
715 		kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
716 	}
717 
718 	mutex_unlock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
719 	mutex_unlock(&kbdev->js_data.queue_mutex);
720 
721 	if (update_ctx_count) {
722 		mutex_lock(&kbdev->js_data.runpool_mutex);
723 		kbase_backend_ctx_count_changed(kbdev);
724 		mutex_unlock(&kbdev->js_data.runpool_mutex);
725 	}
726 }
727 
728 /*
729  * Priority blocking management functions
730  */
731 
732 /* Should not normally use directly - use kbase_jsctx_slot_atom_pulled_dec() instead */
kbase_jsctx_slot_prio_blocked_clear(struct kbase_context *kctx, int js, int sched_prio)733 static void kbase_jsctx_slot_prio_blocked_clear(struct kbase_context *kctx,
734 						int js, int sched_prio)
735 {
736 	struct kbase_jsctx_slot_tracking *slot_tracking =
737 		&kctx->slot_tracking[js];
738 
739 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
740 
741 	slot_tracking->blocked &= ~(((kbase_js_prio_bitmap_t)1) << sched_prio);
742 	KBASE_KTRACE_ADD_JM_SLOT_INFO(kctx->kbdev, JS_SLOT_PRIO_UNBLOCKED, kctx,
743 				      NULL, 0, js, (unsigned int)sched_prio);
744 }
745 
kbase_jsctx_slot_atoms_pulled(struct kbase_context *kctx, int js)746 static int kbase_jsctx_slot_atoms_pulled(struct kbase_context *kctx, int js)
747 {
748 	return atomic_read(&kctx->slot_tracking[js].atoms_pulled);
749 }
750 
751 /*
752  * A priority level on a slot is blocked when:
753  * - that priority level is blocked
754  * - or, any higher priority level is blocked
755  */
kbase_jsctx_slot_prio_is_blocked(struct kbase_context *kctx, int js, int sched_prio)756 static bool kbase_jsctx_slot_prio_is_blocked(struct kbase_context *kctx, int js,
757 					     int sched_prio)
758 {
759 	struct kbase_jsctx_slot_tracking *slot_tracking =
760 		&kctx->slot_tracking[js];
761 	kbase_js_prio_bitmap_t prio_bit, higher_prios_mask;
762 
763 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
764 
765 	/* done in two separate shifts to prevent future undefined behavior
766 	 * should the number of priority levels == (bit width of the type)
767 	 */
768 	prio_bit = (((kbase_js_prio_bitmap_t)1) << sched_prio);
769 	/* all bits of sched_prio or higher, with sched_prio = 0 being the
770 	 * highest priority
771 	 */
772 	higher_prios_mask = (prio_bit << 1) - 1u;
773 	return (slot_tracking->blocked & higher_prios_mask) != 0u;
774 }
775 
776 /**
777  * kbase_jsctx_slot_atom_pulled_inc - Increase counts of atoms that have being
778  *                                    pulled for a slot from a ctx, based on
779  *                                    this atom
780  * @kctx: kbase context
781  * @katom: atom pulled
782  *
783  * Manages counts of atoms pulled (including per-priority-level counts), for
784  * later determining when a ctx can become unblocked on a slot.
785  *
786  * Once a slot has been blocked at @katom's priority level, it should not be
787  * pulled from, hence this function should not be called in that case.
788  *
789  * The return value is to aid tracking of when @kctx becomes runnable.
790  *
791  * Return: new total count of atoms pulled from all slots on @kctx
792  */
kbase_jsctx_slot_atom_pulled_inc(struct kbase_context *kctx, const struct kbase_jd_atom *katom)793 static int kbase_jsctx_slot_atom_pulled_inc(struct kbase_context *kctx,
794 					    const struct kbase_jd_atom *katom)
795 {
796 	int js = katom->slot_nr;
797 	int sched_prio = katom->sched_priority;
798 	struct kbase_jsctx_slot_tracking *slot_tracking =
799 		&kctx->slot_tracking[js];
800 	int nr_atoms_pulled;
801 
802 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
803 
804 	WARN(kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio),
805 	     "Should not have pulled atoms for slot %d from a context that is blocked at priority %d or higher",
806 	     js, sched_prio);
807 
808 	nr_atoms_pulled = atomic_inc_return(&kctx->atoms_pulled_all_slots);
809 	atomic_inc(&slot_tracking->atoms_pulled);
810 	slot_tracking->atoms_pulled_pri[sched_prio]++;
811 
812 	return nr_atoms_pulled;
813 }
814 
815 /**
816  * kbase_jsctx_slot_atom_pulled_dec- Decrease counts of atoms that have being
817  *                                   pulled for a slot from a ctx, and
818  *                                   re-evaluate whether a context is blocked
819  *                                   on this slot
820  * @kctx: kbase context
821  * @katom: atom that has just been removed from a job slot
822  *
823  * @kctx can become unblocked on a slot for a priority level when it no longer
824  * has any pulled atoms at that priority level on that slot, and all higher
825  * (numerically lower) priority levels are also unblocked @kctx on that
826  * slot. The latter condition is to retain priority ordering within @kctx.
827  *
828  * Return: true if the slot was previously blocked but has now become unblocked
829  * at @katom's priority level, false otherwise.
830  */
kbase_jsctx_slot_atom_pulled_dec(struct kbase_context *kctx, const struct kbase_jd_atom *katom)831 static bool kbase_jsctx_slot_atom_pulled_dec(struct kbase_context *kctx,
832 					     const struct kbase_jd_atom *katom)
833 {
834 	int js = katom->slot_nr;
835 	int sched_prio = katom->sched_priority;
836 	int atoms_pulled_pri;
837 	struct kbase_jsctx_slot_tracking *slot_tracking =
838 		&kctx->slot_tracking[js];
839 	bool slot_prio_became_unblocked = false;
840 
841 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
842 
843 	atomic_dec(&kctx->atoms_pulled_all_slots);
844 	atomic_dec(&slot_tracking->atoms_pulled);
845 
846 	atoms_pulled_pri = --(slot_tracking->atoms_pulled_pri[sched_prio]);
847 
848 	/* We can safely clear this priority level's blocked status even if
849 	 * higher priority levels are still blocked: a subsequent query to
850 	 * kbase_jsctx_slot_prio_is_blocked() will still return true
851 	 */
852 	if (!atoms_pulled_pri &&
853 	    kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio)) {
854 		kbase_jsctx_slot_prio_blocked_clear(kctx, js, sched_prio);
855 
856 		if (!kbase_jsctx_slot_prio_is_blocked(kctx, js, sched_prio))
857 			slot_prio_became_unblocked = true;
858 	}
859 
860 	if (slot_prio_became_unblocked)
861 		KBASE_KTRACE_ADD_JM_SLOT_INFO(kctx->kbdev,
862 					      JS_SLOT_PRIO_AND_HIGHER_UNBLOCKED,
863 					      kctx, katom, katom->jc, js,
864 					      (unsigned int)sched_prio);
865 
866 	return slot_prio_became_unblocked;
867 }
868 
869 /**
870  * kbase_js_ctx_list_add_pullable_nolock - Variant of
871  *                                         kbase_jd_ctx_list_add_pullable()
872  *                                         where the caller must hold
873  *                                         hwaccess_lock
874  * @kbdev:  Device pointer
875  * @kctx:   Context to add to queue
876  * @js:     Job slot to use
877  *
878  * Caller must hold hwaccess_lock
879  *
880  * Return: true if caller should call kbase_backend_ctx_count_changed()
881  */
kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)882 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
883 						struct kbase_context *kctx,
884 						int js)
885 {
886 	bool ret = false;
887 
888 	lockdep_assert_held(&kbdev->hwaccess_lock);
889 	dev_dbg(kbdev->dev, "Add pullable tail kctx %pK (s:%d)\n",
890 		(void *)kctx, js);
891 
892 	if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
893 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
894 
895 	list_add_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
896 			&kbdev->js_data.ctx_list_pullable[js][kctx->priority]);
897 
898 	if (!kctx->slots_pullable) {
899 		kbdev->js_data.nr_contexts_pullable++;
900 		ret = true;
901 		if (!kbase_jsctx_atoms_pulled(kctx)) {
902 			WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
903 			kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
904 			atomic_inc(&kbdev->js_data.nr_contexts_runnable);
905 		}
906 	}
907 	kctx->slots_pullable |= (1 << js);
908 
909 	return ret;
910 }
911 
912 /**
913  * kbase_js_ctx_list_add_pullable_head_nolock - Variant of
914  *                                              kbase_js_ctx_list_add_pullable_head()
915  *                                              where the caller must hold
916  *                                              hwaccess_lock
917  * @kbdev:  Device pointer
918  * @kctx:   Context to add to queue
919  * @js:     Job slot to use
920  *
921  * Caller must hold hwaccess_lock
922  *
923  * Return:  true if caller should call kbase_backend_ctx_count_changed()
924  */
kbase_js_ctx_list_add_pullable_head_nolock( struct kbase_device *kbdev, struct kbase_context *kctx, int js)925 static bool kbase_js_ctx_list_add_pullable_head_nolock(
926 		struct kbase_device *kbdev, struct kbase_context *kctx, int js)
927 {
928 	bool ret = false;
929 
930 	lockdep_assert_held(&kbdev->hwaccess_lock);
931 	dev_dbg(kbdev->dev, "Add pullable head kctx %pK (s:%d)\n",
932 		(void *)kctx, js);
933 
934 	if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
935 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
936 
937 	list_add(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
938 			&kbdev->js_data.ctx_list_pullable[js][kctx->priority]);
939 
940 	if (!kctx->slots_pullable) {
941 		kbdev->js_data.nr_contexts_pullable++;
942 		ret = true;
943 		if (!kbase_jsctx_atoms_pulled(kctx)) {
944 			WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
945 			kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
946 			atomic_inc(&kbdev->js_data.nr_contexts_runnable);
947 		}
948 	}
949 	kctx->slots_pullable |= (1 << js);
950 
951 	return ret;
952 }
953 
954 /**
955  * kbase_js_ctx_list_add_pullable_head - Add context to the head of the
956  *                                       per-slot pullable context queue
957  * @kbdev:  Device pointer
958  * @kctx:   Context to add to queue
959  * @js:     Job slot to use
960  *
961  * If the context is on either the pullable or unpullable queues, then it is
962  * removed before being added to the head.
963  *
964  * This function should be used when a context has been scheduled, but no jobs
965  * can currently be pulled from it.
966  *
967  * Return:  true if caller should call kbase_backend_ctx_count_changed()
968  */
kbase_js_ctx_list_add_pullable_head(struct kbase_device *kbdev, struct kbase_context *kctx, int js)969 static bool kbase_js_ctx_list_add_pullable_head(struct kbase_device *kbdev,
970 						struct kbase_context *kctx,
971 						int js)
972 {
973 	bool ret;
974 	unsigned long flags;
975 
976 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
977 	ret = kbase_js_ctx_list_add_pullable_head_nolock(kbdev, kctx, js);
978 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
979 
980 	return ret;
981 }
982 
983 /**
984  * kbase_js_ctx_list_add_unpullable_nolock - Add context to the tail of the
985  *                                           per-slot unpullable context queue
986  * @kbdev:  Device pointer
987  * @kctx:   Context to add to queue
988  * @js:     Job slot to use
989  *
990  * The context must already be on the per-slot pullable queue. It will be
991  * removed from the pullable queue before being added to the unpullable queue.
992  *
993  * This function should be used when a context has been pulled from, and there
994  * are no jobs remaining on the specified slot.
995  *
996  * Caller must hold hwaccess_lock
997  *
998  * Return:  true if caller should call kbase_backend_ctx_count_changed()
999  */
kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)1000 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
1001 						struct kbase_context *kctx,
1002 						int js)
1003 {
1004 	bool ret = false;
1005 
1006 	lockdep_assert_held(&kbdev->hwaccess_lock);
1007 	dev_dbg(kbdev->dev, "Add unpullable tail kctx %pK (s:%d)\n",
1008 		(void *)kctx, js);
1009 
1010 	list_move_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
1011 		&kbdev->js_data.ctx_list_unpullable[js][kctx->priority]);
1012 
1013 	if (kctx->slots_pullable == (1 << js)) {
1014 		kbdev->js_data.nr_contexts_pullable--;
1015 		ret = true;
1016 		if (!kbase_jsctx_atoms_pulled(kctx)) {
1017 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
1018 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
1019 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
1020 		}
1021 	}
1022 	kctx->slots_pullable &= ~(1 << js);
1023 
1024 	return ret;
1025 }
1026 
1027 /**
1028  * kbase_js_ctx_list_remove_nolock - Remove context from the per-slot pullable
1029  *                                   or unpullable context queues
1030  * @kbdev:  Device pointer
1031  * @kctx:   Context to remove from queue
1032  * @js:     Job slot to use
1033  *
1034  * The context must already be on one of the queues.
1035  *
1036  * This function should be used when a context has no jobs on the GPU, and no
1037  * jobs remaining for the specified slot.
1038  *
1039  * Caller must hold hwaccess_lock
1040  *
1041  * Return:  true if caller should call kbase_backend_ctx_count_changed()
1042  */
kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)1043 static bool kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev,
1044 					struct kbase_context *kctx,
1045 					int js)
1046 {
1047 	bool ret = false;
1048 
1049 	lockdep_assert_held(&kbdev->hwaccess_lock);
1050 
1051 	WARN_ON(list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]));
1052 
1053 	list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
1054 
1055 	if (kctx->slots_pullable == (1 << js)) {
1056 		kbdev->js_data.nr_contexts_pullable--;
1057 		ret = true;
1058 		if (!kbase_jsctx_atoms_pulled(kctx)) {
1059 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
1060 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
1061 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
1062 		}
1063 	}
1064 	kctx->slots_pullable &= ~(1 << js);
1065 
1066 	return ret;
1067 }
1068 
1069 /**
1070  * kbase_js_ctx_list_pop_head_nolock - Variant of kbase_js_ctx_list_pop_head()
1071  *                                     where the caller must hold
1072  *                                     hwaccess_lock
1073  * @kbdev:  Device pointer
1074  * @js:     Job slot to use
1075  *
1076  * Caller must hold hwaccess_lock
1077  *
1078  * Return:  Context to use for specified slot.
1079  *          NULL if no contexts present for specified slot
1080  */
kbase_js_ctx_list_pop_head_nolock( struct kbase_device *kbdev, int js)1081 static struct kbase_context *kbase_js_ctx_list_pop_head_nolock(
1082 						struct kbase_device *kbdev,
1083 						int js)
1084 {
1085 	struct kbase_context *kctx;
1086 	int i;
1087 
1088 	lockdep_assert_held(&kbdev->hwaccess_lock);
1089 
1090 	for (i = KBASE_JS_ATOM_SCHED_PRIO_FIRST; i < KBASE_JS_ATOM_SCHED_PRIO_COUNT; i++) {
1091 		if (list_empty(&kbdev->js_data.ctx_list_pullable[js][i]))
1092 			continue;
1093 
1094 		kctx = list_entry(kbdev->js_data.ctx_list_pullable[js][i].next,
1095 				struct kbase_context,
1096 				jctx.sched_info.ctx.ctx_list_entry[js]);
1097 
1098 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
1099 		dev_dbg(kbdev->dev,
1100 			"Popped %pK from the pullable queue (s:%d)\n",
1101 			(void *)kctx, js);
1102 		return kctx;
1103 	}
1104 	return NULL;
1105 }
1106 
1107 /**
1108  * kbase_js_ctx_list_pop_head - Pop the head context off the per-slot pullable
1109  *                              queue.
1110  * @kbdev:  Device pointer
1111  * @js:     Job slot to use
1112  *
1113  * Return:  Context to use for specified slot.
1114  *          NULL if no contexts present for specified slot
1115  */
kbase_js_ctx_list_pop_head( struct kbase_device *kbdev, int js)1116 static struct kbase_context *kbase_js_ctx_list_pop_head(
1117 		struct kbase_device *kbdev, int js)
1118 {
1119 	struct kbase_context *kctx;
1120 	unsigned long flags;
1121 
1122 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1123 	kctx = kbase_js_ctx_list_pop_head_nolock(kbdev, js);
1124 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1125 
1126 	return kctx;
1127 }
1128 
1129 /**
1130  * kbase_js_ctx_pullable - Return if a context can be pulled from on the
1131  *                         specified slot
1132  * @kctx:          Context pointer
1133  * @js:            Job slot to use
1134  * @is_scheduled:  true if the context is currently scheduled
1135  *
1136  * Caller must hold hwaccess_lock
1137  *
1138  * Return:         true if context can be pulled from on specified slot
1139  *                 false otherwise
1140  */
kbase_js_ctx_pullable(struct kbase_context *kctx, int js, bool is_scheduled)1141 static bool kbase_js_ctx_pullable(struct kbase_context *kctx, int js,
1142 					bool is_scheduled)
1143 {
1144 	struct kbasep_js_device_data *js_devdata;
1145 	struct kbase_jd_atom *katom;
1146 	struct kbase_device *kbdev = kctx->kbdev;
1147 
1148 	lockdep_assert_held(&kbdev->hwaccess_lock);
1149 
1150 	js_devdata = &kbdev->js_data;
1151 
1152 	if (is_scheduled) {
1153 		if (!kbasep_js_is_submit_allowed(js_devdata, kctx)) {
1154 			dev_dbg(kbdev->dev, "JS: No submit allowed for kctx %pK\n",
1155 				(void *)kctx);
1156 			return false;
1157 		}
1158 	}
1159 	katom = jsctx_rb_peek(kctx, js);
1160 	if (!katom) {
1161 		dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%d)\n",
1162 			(void *)kctx, js);
1163 		return false; /* No pullable atoms */
1164 	}
1165 	if (kbase_jsctx_slot_prio_is_blocked(kctx, js, katom->sched_priority)) {
1166 		KBASE_KTRACE_ADD_JM_SLOT_INFO(
1167 			kctx->kbdev, JS_SLOT_PRIO_IS_BLOCKED, kctx, katom,
1168 			katom->jc, js, (unsigned int)katom->sched_priority);
1169 		dev_dbg(kbdev->dev,
1170 			"JS: kctx %pK is blocked from submitting atoms at priority %d and lower (s:%d)\n",
1171 			(void *)kctx, katom->sched_priority, js);
1172 		return false;
1173 	}
1174 	if (atomic_read(&katom->blocked)) {
1175 		dev_dbg(kbdev->dev, "JS: Atom %pK is blocked in js_ctx_pullable\n",
1176 			(void *)katom);
1177 		return false; /* next atom blocked */
1178 	}
1179 	if (kbase_js_atom_blocked_on_x_dep(katom)) {
1180 		if (katom->x_pre_dep->gpu_rb_state ==
1181 				KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
1182 				katom->x_pre_dep->will_fail_event_code) {
1183 			dev_dbg(kbdev->dev,
1184 				"JS: X pre-dep %pK is not present in slot FIFO or will fail\n",
1185 				(void *)katom->x_pre_dep);
1186 			return false;
1187 		}
1188 		if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
1189 			kbase_backend_nr_atoms_on_slot(kctx->kbdev, js)) {
1190 			dev_dbg(kbdev->dev,
1191 				"JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%d)\n",
1192 				(void *)katom, js);
1193 			return false;
1194 		}
1195 	}
1196 
1197 	dev_dbg(kbdev->dev, "JS: Atom %pK is pullable in kctx %pK (s:%d)\n",
1198 		(void *)katom, (void *)kctx, js);
1199 
1200 	return true;
1201 }
1202 
kbase_js_dep_validate(struct kbase_context *kctx, struct kbase_jd_atom *katom)1203 static bool kbase_js_dep_validate(struct kbase_context *kctx,
1204 				struct kbase_jd_atom *katom)
1205 {
1206 	struct kbase_device *kbdev = kctx->kbdev;
1207 	bool ret = true;
1208 	bool has_dep = false, has_x_dep = false;
1209 	int js = kbase_js_get_slot(kbdev, katom);
1210 	int prio = katom->sched_priority;
1211 	int i;
1212 
1213 	for (i = 0; i < 2; i++) {
1214 		struct kbase_jd_atom *dep_atom = katom->dep[i].atom;
1215 
1216 		if (dep_atom) {
1217 			int dep_js = kbase_js_get_slot(kbdev, dep_atom);
1218 			int dep_prio = dep_atom->sched_priority;
1219 
1220 			dev_dbg(kbdev->dev,
1221 				"Checking dep %d of atom %pK (s:%d) on %pK (s:%d)\n",
1222 				i, (void *)katom, js, (void *)dep_atom, dep_js);
1223 
1224 			/* Dependent atom must already have been submitted */
1225 			if (!(dep_atom->atom_flags &
1226 					KBASE_KATOM_FLAG_JSCTX_IN_TREE)) {
1227 				dev_dbg(kbdev->dev,
1228 					"Blocker not submitted yet\n");
1229 				ret = false;
1230 				break;
1231 			}
1232 
1233 			/* Dependencies with different priorities can't
1234 			 * be represented in the ringbuffer
1235 			 */
1236 			if (prio != dep_prio) {
1237 				dev_dbg(kbdev->dev,
1238 					"Different atom priorities\n");
1239 				ret = false;
1240 				break;
1241 			}
1242 
1243 			if (js == dep_js) {
1244 				/* Only one same-slot dependency can be
1245 				 * represented in the ringbuffer
1246 				 */
1247 				if (has_dep) {
1248 					dev_dbg(kbdev->dev,
1249 						"Too many same-slot deps\n");
1250 					ret = false;
1251 					break;
1252 				}
1253 				/* Each dependee atom can only have one
1254 				 * same-slot dependency
1255 				 */
1256 				if (dep_atom->post_dep) {
1257 					dev_dbg(kbdev->dev,
1258 						"Too many same-slot successors\n");
1259 					ret = false;
1260 					break;
1261 				}
1262 				has_dep = true;
1263 			} else {
1264 				/* Only one cross-slot dependency can be
1265 				 * represented in the ringbuffer
1266 				 */
1267 				if (has_x_dep) {
1268 					dev_dbg(kbdev->dev,
1269 						"Too many cross-slot deps\n");
1270 					ret = false;
1271 					break;
1272 				}
1273 				/* Each dependee atom can only have one
1274 				 * cross-slot dependency
1275 				 */
1276 				if (dep_atom->x_post_dep) {
1277 					dev_dbg(kbdev->dev,
1278 						"Too many cross-slot successors\n");
1279 					ret = false;
1280 					break;
1281 				}
1282 				/* The dependee atom can not already be in the
1283 				 * HW access ringbuffer
1284 				 */
1285 				if (dep_atom->gpu_rb_state !=
1286 					KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB) {
1287 					dev_dbg(kbdev->dev,
1288 						"Blocker already in ringbuffer (state:%d)\n",
1289 						dep_atom->gpu_rb_state);
1290 					ret = false;
1291 					break;
1292 				}
1293 				/* The dependee atom can not already have
1294 				 * completed
1295 				 */
1296 				if (dep_atom->status !=
1297 						KBASE_JD_ATOM_STATE_IN_JS) {
1298 					dev_dbg(kbdev->dev,
1299 						"Blocker already completed (status:%d)\n",
1300 						dep_atom->status);
1301 					ret = false;
1302 					break;
1303 				}
1304 
1305 				has_x_dep = true;
1306 			}
1307 
1308 			/* Dependency can be represented in ringbuffers */
1309 		}
1310 	}
1311 
1312 	/* If dependencies can be represented by ringbuffer then clear them from
1313 	 * atom structure
1314 	 */
1315 	if (ret) {
1316 		for (i = 0; i < 2; i++) {
1317 			struct kbase_jd_atom *dep_atom = katom->dep[i].atom;
1318 
1319 			if (dep_atom) {
1320 				int dep_js = kbase_js_get_slot(kbdev, dep_atom);
1321 
1322 				dev_dbg(kbdev->dev,
1323 					"Clearing dep %d of atom %pK (s:%d) on %pK (s:%d)\n",
1324 					i, (void *)katom, js, (void *)dep_atom,
1325 					dep_js);
1326 
1327 				if ((js != dep_js) &&
1328 					(dep_atom->status !=
1329 						KBASE_JD_ATOM_STATE_COMPLETED)
1330 					&& (dep_atom->status !=
1331 					KBASE_JD_ATOM_STATE_HW_COMPLETED)
1332 					&& (dep_atom->status !=
1333 						KBASE_JD_ATOM_STATE_UNUSED)) {
1334 
1335 					katom->atom_flags |=
1336 						KBASE_KATOM_FLAG_X_DEP_BLOCKED;
1337 
1338 					dev_dbg(kbdev->dev, "Set X_DEP flag on atom %pK\n",
1339 						(void *)katom);
1340 
1341 					katom->x_pre_dep = dep_atom;
1342 					dep_atom->x_post_dep = katom;
1343 					if (kbase_jd_katom_dep_type(
1344 							&katom->dep[i]) ==
1345 							BASE_JD_DEP_TYPE_DATA)
1346 						katom->atom_flags |=
1347 						KBASE_KATOM_FLAG_FAIL_BLOCKER;
1348 				}
1349 				if ((kbase_jd_katom_dep_type(&katom->dep[i])
1350 						== BASE_JD_DEP_TYPE_DATA) &&
1351 						(js == dep_js)) {
1352 					katom->pre_dep = dep_atom;
1353 					dep_atom->post_dep = katom;
1354 				}
1355 
1356 				list_del(&katom->dep_item[i]);
1357 				kbase_jd_katom_dep_clear(&katom->dep[i]);
1358 			}
1359 		}
1360 	} else {
1361 		dev_dbg(kbdev->dev,
1362 			"Deps of atom %pK (s:%d) could not be represented\n",
1363 			(void *)katom, js);
1364 	}
1365 
1366 	return ret;
1367 }
1368 
kbase_js_set_ctx_priority(struct kbase_context *kctx, int new_priority)1369 void kbase_js_set_ctx_priority(struct kbase_context *kctx, int new_priority)
1370 {
1371 	struct kbase_device *kbdev = kctx->kbdev;
1372 	int js;
1373 
1374 	lockdep_assert_held(&kbdev->hwaccess_lock);
1375 
1376 	/* Move kctx to the pullable/upullable list as per the new priority */
1377 	if (new_priority != kctx->priority) {
1378 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
1379 			if (kctx->slots_pullable & (1 << js))
1380 				list_move_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
1381 					&kbdev->js_data.ctx_list_pullable[js][new_priority]);
1382 			else
1383 				list_move_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
1384 					&kbdev->js_data.ctx_list_unpullable[js][new_priority]);
1385 		}
1386 
1387 		kctx->priority = new_priority;
1388 	}
1389 }
1390 
kbase_js_update_ctx_priority(struct kbase_context *kctx)1391 void kbase_js_update_ctx_priority(struct kbase_context *kctx)
1392 {
1393 	struct kbase_device *kbdev = kctx->kbdev;
1394 	int new_priority = KBASE_JS_ATOM_SCHED_PRIO_LOW;
1395 	int prio;
1396 
1397 	lockdep_assert_held(&kbdev->hwaccess_lock);
1398 
1399 	if (kbdev->js_ctx_scheduling_mode == KBASE_JS_SYSTEM_PRIORITY_MODE) {
1400 		/* Determine the new priority for context, as per the priority
1401 		 * of currently in-use atoms.
1402 		 */
1403 		for (prio = KBASE_JS_ATOM_SCHED_PRIO_FIRST;
1404 			prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
1405 			if (kctx->atoms_count[prio]) {
1406 				new_priority = prio;
1407 				break;
1408 			}
1409 		}
1410 	}
1411 
1412 	kbase_js_set_ctx_priority(kctx, new_priority);
1413 }
1414 KBASE_EXPORT_TEST_API(kbase_js_update_ctx_priority);
1415 
1416 /**
1417  * js_add_start_rp() - Add an atom that starts a renderpass to the job scheduler
1418  * @start_katom: Pointer to the atom to be added.
1419  * Return: 0 if successful or a negative value on failure.
1420  */
js_add_start_rp(struct kbase_jd_atom *const start_katom)1421 static int js_add_start_rp(struct kbase_jd_atom *const start_katom)
1422 {
1423 	struct kbase_context *const kctx = start_katom->kctx;
1424 	struct kbase_jd_renderpass *rp;
1425 	struct kbase_device *const kbdev = kctx->kbdev;
1426 	unsigned long flags;
1427 
1428 	lockdep_assert_held(&kctx->jctx.lock);
1429 
1430 	if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
1431 		return -EINVAL;
1432 
1433 	if (start_katom->core_req & BASE_JD_REQ_END_RENDERPASS)
1434 		return -EINVAL;
1435 
1436 	compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
1437 			ARRAY_SIZE(kctx->jctx.renderpasses),
1438 			"Should check invalid access to renderpasses");
1439 
1440 	rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
1441 
1442 	if (rp->state != KBASE_JD_RP_COMPLETE)
1443 		return -EINVAL;
1444 
1445 	dev_dbg(kctx->kbdev->dev, "JS add start atom %pK of RP %d\n",
1446 		(void *)start_katom, start_katom->renderpass_id);
1447 
1448 	/* The following members are read when updating the job slot
1449 	 * ringbuffer/fifo therefore they require additional locking.
1450 	 */
1451 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1452 
1453 	rp->state = KBASE_JD_RP_START;
1454 	rp->start_katom = start_katom;
1455 	rp->end_katom = NULL;
1456 	INIT_LIST_HEAD(&rp->oom_reg_list);
1457 
1458 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1459 
1460 	return 0;
1461 }
1462 
1463 /**
1464  * js_add_end_rp() - Add an atom that ends a renderpass to the job scheduler
1465  * @end_katom: Pointer to the atom to be added.
1466  * Return: 0 if successful or a negative value on failure.
1467  */
js_add_end_rp(struct kbase_jd_atom *const end_katom)1468 static int js_add_end_rp(struct kbase_jd_atom *const end_katom)
1469 {
1470 	struct kbase_context *const kctx = end_katom->kctx;
1471 	struct kbase_jd_renderpass *rp;
1472 	struct kbase_device *const kbdev = kctx->kbdev;
1473 
1474 	lockdep_assert_held(&kctx->jctx.lock);
1475 
1476 	if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
1477 		return -EINVAL;
1478 
1479 	if (end_katom->core_req & BASE_JD_REQ_START_RENDERPASS)
1480 		return -EINVAL;
1481 
1482 	compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
1483 			ARRAY_SIZE(kctx->jctx.renderpasses),
1484 			"Should check invalid access to renderpasses");
1485 
1486 	rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
1487 
1488 	dev_dbg(kbdev->dev, "JS add end atom %pK in state %d of RP %d\n",
1489 		(void *)end_katom, (int)rp->state, end_katom->renderpass_id);
1490 
1491 	if (rp->state == KBASE_JD_RP_COMPLETE)
1492 		return -EINVAL;
1493 
1494 	if (rp->end_katom == NULL) {
1495 		/* We can't be in a retry state until the fragment job chain
1496 		 * has completed.
1497 		 */
1498 		unsigned long flags;
1499 
1500 		WARN_ON(rp->state == KBASE_JD_RP_RETRY);
1501 		WARN_ON(rp->state == KBASE_JD_RP_RETRY_PEND_OOM);
1502 		WARN_ON(rp->state == KBASE_JD_RP_RETRY_OOM);
1503 
1504 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1505 		rp->end_katom = end_katom;
1506 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1507 	} else
1508 		WARN_ON(rp->end_katom != end_katom);
1509 
1510 	return 0;
1511 }
1512 
kbasep_js_add_job(struct kbase_context *kctx, struct kbase_jd_atom *atom)1513 bool kbasep_js_add_job(struct kbase_context *kctx,
1514 		struct kbase_jd_atom *atom)
1515 {
1516 	unsigned long flags;
1517 	struct kbasep_js_kctx_info *js_kctx_info;
1518 	struct kbase_device *kbdev;
1519 	struct kbasep_js_device_data *js_devdata;
1520 	int err = 0;
1521 
1522 	bool enqueue_required = false;
1523 	bool timer_sync = false;
1524 
1525 	KBASE_DEBUG_ASSERT(kctx != NULL);
1526 	KBASE_DEBUG_ASSERT(atom != NULL);
1527 	lockdep_assert_held(&kctx->jctx.lock);
1528 
1529 	kbdev = kctx->kbdev;
1530 	js_devdata = &kbdev->js_data;
1531 	js_kctx_info = &kctx->jctx.sched_info;
1532 
1533 	mutex_lock(&js_devdata->queue_mutex);
1534 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1535 
1536 	if (atom->core_req & BASE_JD_REQ_START_RENDERPASS)
1537 		err = js_add_start_rp(atom);
1538 	else if (atom->core_req & BASE_JD_REQ_END_RENDERPASS)
1539 		err = js_add_end_rp(atom);
1540 
1541 	if (err < 0) {
1542 		atom->event_code = BASE_JD_EVENT_JOB_INVALID;
1543 		atom->status = KBASE_JD_ATOM_STATE_COMPLETED;
1544 		goto out_unlock;
1545 	}
1546 
1547 	/*
1548 	 * Begin Runpool transaction
1549 	 */
1550 	mutex_lock(&js_devdata->runpool_mutex);
1551 
1552 	/* Refcount ctx.nr_jobs */
1553 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs < U32_MAX);
1554 	++(js_kctx_info->ctx.nr_jobs);
1555 	dev_dbg(kbdev->dev, "Add atom %pK to kctx %pK; now %d in ctx\n",
1556 		(void *)atom, (void *)kctx, js_kctx_info->ctx.nr_jobs);
1557 
1558 	/* Lock for state available during IRQ */
1559 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1560 
1561 	if (++kctx->atoms_count[atom->sched_priority] == 1)
1562 		kbase_js_update_ctx_priority(kctx);
1563 
1564 	if (!kbase_js_dep_validate(kctx, atom)) {
1565 		/* Dependencies could not be represented */
1566 		--(js_kctx_info->ctx.nr_jobs);
1567 		dev_dbg(kbdev->dev,
1568 			"Remove atom %pK from kctx %pK; now %d in ctx\n",
1569 			(void *)atom, (void *)kctx, js_kctx_info->ctx.nr_jobs);
1570 
1571 		/* Setting atom status back to queued as it still has unresolved
1572 		 * dependencies
1573 		 */
1574 		atom->status = KBASE_JD_ATOM_STATE_QUEUED;
1575 		dev_dbg(kbdev->dev, "Atom %pK status to queued\n", (void *)atom);
1576 
1577 		/* Undo the count, as the atom will get added again later but
1578 		 * leave the context priority adjusted or boosted, in case if
1579 		 * this was the first higher priority atom received for this
1580 		 * context.
1581 		 * This will prevent the scenario of priority inversion, where
1582 		 * another context having medium priority atoms keeps getting
1583 		 * scheduled over this context, which is having both lower and
1584 		 * higher priority atoms, but higher priority atoms are blocked
1585 		 * due to dependency on lower priority atoms. With priority
1586 		 * boost the high priority atom will get to run at earliest.
1587 		 */
1588 		kctx->atoms_count[atom->sched_priority]--;
1589 
1590 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1591 		mutex_unlock(&js_devdata->runpool_mutex);
1592 
1593 		goto out_unlock;
1594 	}
1595 
1596 	enqueue_required = kbase_js_dep_resolved_submit(kctx, atom);
1597 
1598 	KBASE_KTRACE_ADD_JM_REFCOUNT(kbdev, JS_ADD_JOB, kctx, atom, atom->jc,
1599 				kbase_ktrace_get_ctx_refcnt(kctx));
1600 
1601 	/* Context Attribute Refcounting */
1602 	kbasep_js_ctx_attr_ctx_retain_atom(kbdev, kctx, atom);
1603 
1604 	if (enqueue_required) {
1605 		if (kbase_js_ctx_pullable(kctx, atom->slot_nr, false))
1606 			timer_sync = kbase_js_ctx_list_add_pullable_nolock(
1607 					kbdev, kctx, atom->slot_nr);
1608 		else
1609 			timer_sync = kbase_js_ctx_list_add_unpullable_nolock(
1610 					kbdev, kctx, atom->slot_nr);
1611 	}
1612 	/* If this context is active and the atom is the first on its slot,
1613 	 * kick the job manager to attempt to fast-start the atom
1614 	 */
1615 	if (enqueue_required && kctx ==
1616 			kbdev->hwaccess.active_kctx[atom->slot_nr])
1617 		kbase_jm_try_kick(kbdev, 1 << atom->slot_nr);
1618 
1619 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1620 	if (timer_sync)
1621 		kbase_backend_ctx_count_changed(kbdev);
1622 	mutex_unlock(&js_devdata->runpool_mutex);
1623 	/* End runpool transaction */
1624 
1625 	if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED)) {
1626 		if (kbase_ctx_flag(kctx, KCTX_DYING)) {
1627 			/* A job got added while/after kbase_job_zap_context()
1628 			 * was called on a non-scheduled context. Kill that job
1629 			 * by killing the context.
1630 			 */
1631 			kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx,
1632 					false);
1633 		} else if (js_kctx_info->ctx.nr_jobs == 1) {
1634 			/* Handle Refcount going from 0 to 1: schedule the
1635 			 * context on the Queue
1636 			 */
1637 			KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1638 			dev_dbg(kbdev->dev, "JS: Enqueue Context %pK", kctx);
1639 
1640 			/* Queue was updated - caller must try to schedule the
1641 			 * head context
1642 			 */
1643 			WARN_ON(!enqueue_required);
1644 		}
1645 	}
1646 out_unlock:
1647 	dev_dbg(kbdev->dev, "Enqueue of kctx %pK is %srequired\n",
1648 		kctx, enqueue_required ? "" : "not ");
1649 
1650 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1651 
1652 	mutex_unlock(&js_devdata->queue_mutex);
1653 
1654 	return enqueue_required;
1655 }
1656 
kbasep_js_remove_job(struct kbase_device *kbdev, struct kbase_context *kctx, struct kbase_jd_atom *atom)1657 void kbasep_js_remove_job(struct kbase_device *kbdev,
1658 		struct kbase_context *kctx, struct kbase_jd_atom *atom)
1659 {
1660 	struct kbasep_js_kctx_info *js_kctx_info;
1661 	unsigned long flags;
1662 
1663 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1664 	KBASE_DEBUG_ASSERT(kctx != NULL);
1665 	KBASE_DEBUG_ASSERT(atom != NULL);
1666 
1667 	js_kctx_info = &kctx->jctx.sched_info;
1668 
1669 	KBASE_KTRACE_ADD_JM_REFCOUNT(kbdev, JS_REMOVE_JOB, kctx, atom, atom->jc,
1670 			kbase_ktrace_get_ctx_refcnt(kctx));
1671 
1672 	/* De-refcount ctx.nr_jobs */
1673 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs > 0);
1674 	--(js_kctx_info->ctx.nr_jobs);
1675 	dev_dbg(kbdev->dev,
1676 		"Remove atom %pK from kctx %pK; now %d in ctx\n",
1677 		(void *)atom, (void *)kctx, js_kctx_info->ctx.nr_jobs);
1678 
1679 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1680 	if (--kctx->atoms_count[atom->sched_priority] == 0)
1681 		kbase_js_update_ctx_priority(kctx);
1682 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1683 }
1684 
kbasep_js_remove_cancelled_job(struct kbase_device *kbdev, struct kbase_context *kctx, struct kbase_jd_atom *katom)1685 bool kbasep_js_remove_cancelled_job(struct kbase_device *kbdev,
1686 		struct kbase_context *kctx, struct kbase_jd_atom *katom)
1687 {
1688 	unsigned long flags;
1689 	struct kbasep_js_atom_retained_state katom_retained_state;
1690 	bool attr_state_changed;
1691 
1692 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1693 	KBASE_DEBUG_ASSERT(kctx != NULL);
1694 	KBASE_DEBUG_ASSERT(katom != NULL);
1695 
1696 	kbasep_js_atom_retained_state_copy(&katom_retained_state, katom);
1697 	kbasep_js_remove_job(kbdev, kctx, katom);
1698 
1699 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1700 
1701 	/* The atom has 'finished' (will not be re-run), so no need to call
1702 	 * kbasep_js_has_atom_finished().
1703 	 *
1704 	 * This is because it returns false for soft-stopped atoms, but we
1705 	 * want to override that, because we're cancelling an atom regardless of
1706 	 * whether it was soft-stopped or not
1707 	 */
1708 	attr_state_changed = kbasep_js_ctx_attr_ctx_release_atom(kbdev, kctx,
1709 			&katom_retained_state);
1710 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1711 
1712 	return attr_state_changed;
1713 }
1714 
1715 /**
1716  * kbasep_js_run_jobs_after_ctx_and_atom_release - Try running more jobs after
1717  *                           releasing a context and/or atom
1718  * @kbdev:                   The kbase_device to operate on
1719  * @kctx:                    The kbase_context to operate on
1720  * @katom_retained_state:    Retained state from the atom
1721  * @runpool_ctx_attr_change: True if the runpool context attributes have changed
1722  *
1723  * This collates a set of actions that must happen whilst hwaccess_lock is held.
1724  *
1725  * This includes running more jobs when:
1726  * - The previously released kctx caused a ctx attribute change,
1727  * - The released atom caused a ctx attribute change,
1728  * - Slots were previously blocked due to affinity restrictions,
1729  * - Submission during IRQ handling failed.
1730  *
1731  * Return: %KBASEP_JS_RELEASE_RESULT_SCHED_ALL if context attributes were
1732  *         changed. The caller should try scheduling all contexts
1733  */
kbasep_js_run_jobs_after_ctx_and_atom_release( struct kbase_device *kbdev, struct kbase_context *kctx, struct kbasep_js_atom_retained_state *katom_retained_state, bool runpool_ctx_attr_change)1734 static kbasep_js_release_result kbasep_js_run_jobs_after_ctx_and_atom_release(
1735 		struct kbase_device *kbdev,
1736 		struct kbase_context *kctx,
1737 		struct kbasep_js_atom_retained_state *katom_retained_state,
1738 		bool runpool_ctx_attr_change)
1739 {
1740 	struct kbasep_js_device_data *js_devdata;
1741 	kbasep_js_release_result result = 0;
1742 
1743 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1744 	KBASE_DEBUG_ASSERT(kctx != NULL);
1745 	KBASE_DEBUG_ASSERT(katom_retained_state != NULL);
1746 	js_devdata = &kbdev->js_data;
1747 
1748 	lockdep_assert_held(&kctx->jctx.sched_info.ctx.jsctx_mutex);
1749 	lockdep_assert_held(&js_devdata->runpool_mutex);
1750 	lockdep_assert_held(&kbdev->hwaccess_lock);
1751 
1752 	if (js_devdata->nr_user_contexts_running != 0 && runpool_ctx_attr_change) {
1753 		/* A change in runpool ctx attributes might mean we can
1754 		 * run more jobs than before
1755 		 */
1756 		result = KBASEP_JS_RELEASE_RESULT_SCHED_ALL;
1757 
1758 		KBASE_KTRACE_ADD_JM_SLOT(kbdev, JD_DONE_TRY_RUN_NEXT_JOB,
1759 					kctx, NULL, 0u, 0);
1760 	}
1761 	return result;
1762 }
1763 
1764 /**
1765  * kbasep_js_runpool_release_ctx_internal - Internal function to release the reference
1766  *                                          on a ctx and an atom's "retained state", only
1767  *                                          taking the runpool and as transaction mutexes
1768  * @kbdev:                   The kbase_device to operate on
1769  * @kctx:                    The kbase_context to operate on
1770  * @katom_retained_state:    Retained state from the atom
1771  *
1772  * This also starts more jobs running in the case of an ctx-attribute state change
1773  *
1774  * This does none of the followup actions for scheduling:
1775  * - It does not schedule in a new context
1776  * - It does not requeue or handle dying contexts
1777  *
1778  * For those tasks, just call kbasep_js_runpool_release_ctx() instead
1779  *
1780  * Has following requirements
1781  * - Context is scheduled in, and kctx->as_nr matches kctx_as_nr
1782  * - Context has a non-zero refcount
1783  * - Caller holds js_kctx_info->ctx.jsctx_mutex
1784  * - Caller holds js_devdata->runpool_mutex
1785  *
1786  * Return: A bitpattern, containing KBASEP_JS_RELEASE_RESULT_* flags, indicating
1787  *         the result of releasing a context that whether the caller should try
1788  *         scheduling a new context or should try scheduling all contexts.
1789  */
kbasep_js_runpool_release_ctx_internal( struct kbase_device *kbdev, struct kbase_context *kctx, struct kbasep_js_atom_retained_state *katom_retained_state)1790 static kbasep_js_release_result kbasep_js_runpool_release_ctx_internal(
1791 		struct kbase_device *kbdev,
1792 		struct kbase_context *kctx,
1793 		struct kbasep_js_atom_retained_state *katom_retained_state)
1794 {
1795 	unsigned long flags;
1796 	struct kbasep_js_device_data *js_devdata;
1797 	struct kbasep_js_kctx_info *js_kctx_info;
1798 
1799 	kbasep_js_release_result release_result = 0u;
1800 	bool runpool_ctx_attr_change = false;
1801 	int kctx_as_nr;
1802 	int new_ref_count;
1803 
1804 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1805 	KBASE_DEBUG_ASSERT(kctx != NULL);
1806 	js_kctx_info = &kctx->jctx.sched_info;
1807 	js_devdata = &kbdev->js_data;
1808 
1809 	/* Ensure context really is scheduled in */
1810 	KBASE_DEBUG_ASSERT(kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1811 
1812 	kctx_as_nr = kctx->as_nr;
1813 	KBASE_DEBUG_ASSERT(kctx_as_nr != KBASEP_AS_NR_INVALID);
1814 	KBASE_DEBUG_ASSERT(atomic_read(&kctx->refcount) > 0);
1815 
1816 	/*
1817 	 * Transaction begins on AS and runpool_irq
1818 	 *
1819 	 * Assert about out calling contract
1820 	 */
1821 	mutex_lock(&kbdev->pm.lock);
1822 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1823 
1824 	KBASE_DEBUG_ASSERT(kctx_as_nr == kctx->as_nr);
1825 	KBASE_DEBUG_ASSERT(atomic_read(&kctx->refcount) > 0);
1826 
1827 	/* Update refcount */
1828 	kbase_ctx_sched_release_ctx(kctx);
1829 	new_ref_count = atomic_read(&kctx->refcount);
1830 
1831 	/* Release the atom if it finished (i.e. wasn't soft-stopped) */
1832 	if (kbasep_js_has_atom_finished(katom_retained_state))
1833 		runpool_ctx_attr_change |= kbasep_js_ctx_attr_ctx_release_atom(
1834 				kbdev, kctx, katom_retained_state);
1835 
1836 	if (new_ref_count == 2 && kbase_ctx_flag(kctx, KCTX_PRIVILEGED) &&
1837 #ifdef CONFIG_MALI_ARBITER_SUPPORT
1838 			!kbase_pm_is_gpu_lost(kbdev) &&
1839 #endif
1840 			!kbase_pm_is_suspending(kbdev)) {
1841 		/* Context is kept scheduled into an address space even when
1842 		 * there are no jobs, in this case we have to handle the
1843 		 * situation where all jobs have been evicted from the GPU and
1844 		 * submission is disabled.
1845 		 *
1846 		 * At this point we re-enable submission to allow further jobs
1847 		 * to be executed
1848 		 */
1849 		kbasep_js_set_submit_allowed(js_devdata, kctx);
1850 	}
1851 
1852 	/* Make a set of checks to see if the context should be scheduled out.
1853 	 * Note that there'll always be at least 1 reference to the context
1854 	 * which was previously acquired by kbasep_js_schedule_ctx().
1855 	 */
1856 	if (new_ref_count == 1 &&
1857 		(!kbasep_js_is_submit_allowed(js_devdata, kctx) ||
1858 #ifdef CONFIG_MALI_ARBITER_SUPPORT
1859 			kbase_pm_is_gpu_lost(kbdev) ||
1860 #endif
1861 			kbase_pm_is_suspending(kbdev))) {
1862 		int num_slots = kbdev->gpu_props.num_job_slots;
1863 		int slot;
1864 
1865 		/* Last reference, and we've been told to remove this context
1866 		 * from the Run Pool
1867 		 */
1868 		dev_dbg(kbdev->dev, "JS: RunPool Remove Context %pK because refcount=%d, jobs=%d, allowed=%d",
1869 				kctx, new_ref_count, js_kctx_info->ctx.nr_jobs,
1870 				kbasep_js_is_submit_allowed(js_devdata, kctx));
1871 
1872 		KBASE_TLSTREAM_TL_NRET_AS_CTX(kbdev, &kbdev->as[kctx->as_nr], kctx);
1873 
1874 		kbase_backend_release_ctx_irq(kbdev, kctx);
1875 
1876 		for (slot = 0; slot < num_slots; slot++) {
1877 			if (kbdev->hwaccess.active_kctx[slot] == kctx) {
1878 				dev_dbg(kbdev->dev, "Marking kctx %pK as inactive (s:%d)\n",
1879 					(void *)kctx, slot);
1880 				kbdev->hwaccess.active_kctx[slot] = NULL;
1881 			}
1882 		}
1883 
1884 		/* Ctx Attribute handling
1885 		 *
1886 		 * Releasing atoms attributes must either happen before this, or
1887 		 * after the KCTX_SHEDULED flag is changed, otherwise we
1888 		 * double-decount the attributes
1889 		 */
1890 		runpool_ctx_attr_change |=
1891 			kbasep_js_ctx_attr_runpool_release_ctx(kbdev, kctx);
1892 
1893 		/* Releasing the context and katom retained state can allow
1894 		 * more jobs to run
1895 		 */
1896 		release_result |=
1897 			kbasep_js_run_jobs_after_ctx_and_atom_release(kbdev,
1898 						kctx, katom_retained_state,
1899 						runpool_ctx_attr_change);
1900 
1901 		/*
1902 		 * Transaction ends on AS and runpool_irq:
1903 		 *
1904 		 * By this point, the AS-related data is now clear and ready
1905 		 * for re-use.
1906 		 *
1907 		 * Since releases only occur once for each previous successful
1908 		 * retain, and no more retains are allowed on this context, no
1909 		 * other thread will be operating in this
1910 		 * code whilst we are
1911 		 */
1912 
1913 		/* Recalculate pullable status for all slots */
1914 		for (slot = 0; slot < num_slots; slot++) {
1915 			if (kbase_js_ctx_pullable(kctx, slot, false))
1916 				kbase_js_ctx_list_add_pullable_nolock(kbdev,
1917 						kctx, slot);
1918 		}
1919 
1920 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1921 
1922 		kbase_backend_release_ctx_noirq(kbdev, kctx);
1923 
1924 		mutex_unlock(&kbdev->pm.lock);
1925 
1926 		/* Note: Don't reuse kctx_as_nr now */
1927 
1928 		/* Synchronize with any timers */
1929 		kbase_backend_ctx_count_changed(kbdev);
1930 
1931 		/* update book-keeping info */
1932 		kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
1933 		/* Signal any waiter that the context is not scheduled, so is
1934 		 * safe for termination - once the jsctx_mutex is also dropped,
1935 		 * and jobs have finished.
1936 		 */
1937 		wake_up(&js_kctx_info->ctx.is_scheduled_wait);
1938 
1939 		/* Queue an action to occur after we've dropped the lock */
1940 		release_result |= KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED |
1941 			KBASEP_JS_RELEASE_RESULT_SCHED_ALL;
1942 	} else {
1943 		kbasep_js_run_jobs_after_ctx_and_atom_release(kbdev, kctx,
1944 				katom_retained_state, runpool_ctx_attr_change);
1945 
1946 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1947 		mutex_unlock(&kbdev->pm.lock);
1948 	}
1949 
1950 	return release_result;
1951 }
1952 
kbasep_js_runpool_release_ctx_nolock(struct kbase_device *kbdev, struct kbase_context *kctx)1953 void kbasep_js_runpool_release_ctx_nolock(struct kbase_device *kbdev,
1954 						struct kbase_context *kctx)
1955 {
1956 	struct kbasep_js_atom_retained_state katom_retained_state;
1957 
1958 	/* Setup a dummy katom_retained_state */
1959 	kbasep_js_atom_retained_state_init_invalid(&katom_retained_state);
1960 
1961 	kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
1962 							&katom_retained_state);
1963 }
1964 
kbasep_js_runpool_requeue_or_kill_ctx(struct kbase_device *kbdev, struct kbase_context *kctx, bool has_pm_ref)1965 void kbasep_js_runpool_requeue_or_kill_ctx(struct kbase_device *kbdev,
1966 		struct kbase_context *kctx, bool has_pm_ref)
1967 {
1968 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1969 	KBASE_DEBUG_ASSERT(kctx != NULL);
1970 
1971 	/* This is called if and only if you've you've detached the context from
1972 	 * the Runpool Queue, and not added it back to the Runpool
1973 	 */
1974 	KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1975 
1976 	if (kbase_ctx_flag(kctx, KCTX_DYING)) {
1977 		/* Dying: don't requeue, but kill all jobs on the context. This
1978 		 * happens asynchronously
1979 		 */
1980 		dev_dbg(kbdev->dev,
1981 			"JS: ** Killing Context %pK on RunPool Remove **", kctx);
1982 		kbase_js_foreach_ctx_job(kctx, &kbase_jd_cancel);
1983 	}
1984 }
1985 
kbasep_js_runpool_release_ctx_and_katom_retained_state( struct kbase_device *kbdev, struct kbase_context *kctx, struct kbasep_js_atom_retained_state *katom_retained_state)1986 void kbasep_js_runpool_release_ctx_and_katom_retained_state(
1987 		struct kbase_device *kbdev, struct kbase_context *kctx,
1988 		struct kbasep_js_atom_retained_state *katom_retained_state)
1989 {
1990 	struct kbasep_js_device_data *js_devdata;
1991 	struct kbasep_js_kctx_info *js_kctx_info;
1992 	kbasep_js_release_result release_result;
1993 
1994 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1995 	KBASE_DEBUG_ASSERT(kctx != NULL);
1996 	js_kctx_info = &kctx->jctx.sched_info;
1997 	js_devdata = &kbdev->js_data;
1998 
1999 	mutex_lock(&js_devdata->queue_mutex);
2000 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2001 	mutex_lock(&js_devdata->runpool_mutex);
2002 
2003 	release_result = kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
2004 			katom_retained_state);
2005 
2006 	/* Drop the runpool mutex to allow requeing kctx */
2007 	mutex_unlock(&js_devdata->runpool_mutex);
2008 
2009 	if ((release_result & KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED) != 0u)
2010 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, true);
2011 
2012 	/* Drop the jsctx_mutex to allow scheduling in a new context */
2013 
2014 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2015 	mutex_unlock(&js_devdata->queue_mutex);
2016 
2017 	if (release_result & KBASEP_JS_RELEASE_RESULT_SCHED_ALL)
2018 		kbase_js_sched_all(kbdev);
2019 }
2020 
kbasep_js_runpool_release_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)2021 void kbasep_js_runpool_release_ctx(struct kbase_device *kbdev,
2022 		struct kbase_context *kctx)
2023 {
2024 	struct kbasep_js_atom_retained_state katom_retained_state;
2025 
2026 	kbasep_js_atom_retained_state_init_invalid(&katom_retained_state);
2027 
2028 	kbasep_js_runpool_release_ctx_and_katom_retained_state(kbdev, kctx,
2029 			&katom_retained_state);
2030 }
2031 
2032 /* Variant of kbasep_js_runpool_release_ctx() that doesn't call into
2033  * kbase_js_sched_all()
2034  */
kbasep_js_runpool_release_ctx_no_schedule( struct kbase_device *kbdev, struct kbase_context *kctx)2035 static void kbasep_js_runpool_release_ctx_no_schedule(
2036 		struct kbase_device *kbdev, struct kbase_context *kctx)
2037 {
2038 	struct kbasep_js_device_data *js_devdata;
2039 	struct kbasep_js_kctx_info *js_kctx_info;
2040 	kbasep_js_release_result release_result;
2041 	struct kbasep_js_atom_retained_state katom_retained_state_struct;
2042 	struct kbasep_js_atom_retained_state *katom_retained_state =
2043 		&katom_retained_state_struct;
2044 
2045 	KBASE_DEBUG_ASSERT(kbdev != NULL);
2046 	KBASE_DEBUG_ASSERT(kctx != NULL);
2047 	js_kctx_info = &kctx->jctx.sched_info;
2048 	js_devdata = &kbdev->js_data;
2049 	kbasep_js_atom_retained_state_init_invalid(katom_retained_state);
2050 
2051 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2052 	mutex_lock(&js_devdata->runpool_mutex);
2053 
2054 	release_result = kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
2055 			katom_retained_state);
2056 
2057 	/* Drop the runpool mutex to allow requeing kctx */
2058 	mutex_unlock(&js_devdata->runpool_mutex);
2059 	if ((release_result & KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED) != 0u)
2060 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, true);
2061 
2062 	/* Drop the jsctx_mutex to allow scheduling in a new context */
2063 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2064 
2065 	/* NOTE: could return release_result if the caller would like to know
2066 	 * whether it should schedule a new context, but currently no callers do
2067 	 */
2068 }
2069 
kbase_js_set_timeouts(struct kbase_device *kbdev)2070 void kbase_js_set_timeouts(struct kbase_device *kbdev)
2071 {
2072 	lockdep_assert_held(&kbdev->hwaccess_lock);
2073 
2074 	kbase_backend_timeouts_changed(kbdev);
2075 }
2076 
kbasep_js_schedule_ctx(struct kbase_device *kbdev, struct kbase_context *kctx, int js)2077 static bool kbasep_js_schedule_ctx(struct kbase_device *kbdev,
2078 					struct kbase_context *kctx,
2079 					int js)
2080 {
2081 	struct kbasep_js_device_data *js_devdata;
2082 	struct kbasep_js_kctx_info *js_kctx_info;
2083 	unsigned long flags;
2084 	bool kctx_suspended = false;
2085 	int as_nr;
2086 
2087 	dev_dbg(kbdev->dev, "Scheduling kctx %pK (s:%d)\n", kctx, js);
2088 
2089 	js_devdata = &kbdev->js_data;
2090 	js_kctx_info = &kctx->jctx.sched_info;
2091 
2092 	/* Pick available address space for this context */
2093 	mutex_lock(&kbdev->mmu_hw_mutex);
2094 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2095 	as_nr = kbase_ctx_sched_retain_ctx(kctx);
2096 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2097 	mutex_unlock(&kbdev->mmu_hw_mutex);
2098 	if (as_nr == KBASEP_AS_NR_INVALID) {
2099 		as_nr = kbase_backend_find_and_release_free_address_space(
2100 				kbdev, kctx);
2101 		if (as_nr != KBASEP_AS_NR_INVALID) {
2102 			/* Attempt to retain the context again, this should
2103 			 * succeed
2104 			 */
2105 			mutex_lock(&kbdev->mmu_hw_mutex);
2106 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2107 			as_nr = kbase_ctx_sched_retain_ctx(kctx);
2108 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2109 			mutex_unlock(&kbdev->mmu_hw_mutex);
2110 
2111 			WARN_ON(as_nr == KBASEP_AS_NR_INVALID);
2112 		}
2113 	}
2114 	if (as_nr == KBASEP_AS_NR_INVALID)
2115 		return false; /* No address spaces currently available */
2116 
2117 	/*
2118 	 * Atomic transaction on the Context and Run Pool begins
2119 	 */
2120 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2121 	mutex_lock(&js_devdata->runpool_mutex);
2122 	mutex_lock(&kbdev->mmu_hw_mutex);
2123 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2124 
2125 	/* Check to see if context is dying due to kbase_job_zap_context() */
2126 	if (kbase_ctx_flag(kctx, KCTX_DYING)) {
2127 		/* Roll back the transaction so far and return */
2128 		kbase_ctx_sched_release_ctx(kctx);
2129 
2130 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2131 		mutex_unlock(&kbdev->mmu_hw_mutex);
2132 		mutex_unlock(&js_devdata->runpool_mutex);
2133 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2134 
2135 		return false;
2136 	}
2137 
2138 	KBASE_KTRACE_ADD_JM_REFCOUNT(kbdev, JS_TRY_SCHEDULE_HEAD_CTX, kctx, NULL,
2139 				0u,
2140 				kbase_ktrace_get_ctx_refcnt(kctx));
2141 
2142 	kbase_ctx_flag_set(kctx, KCTX_SCHEDULED);
2143 
2144 	/* Assign context to previously chosen address space */
2145 	if (!kbase_backend_use_ctx(kbdev, kctx, as_nr)) {
2146 		/* Roll back the transaction so far and return */
2147 		kbase_ctx_sched_release_ctx(kctx);
2148 		kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
2149 
2150 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2151 		mutex_unlock(&kbdev->mmu_hw_mutex);
2152 		mutex_unlock(&js_devdata->runpool_mutex);
2153 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2154 
2155 		return false;
2156 	}
2157 
2158 	kbdev->hwaccess.active_kctx[js] = kctx;
2159 
2160 	KBASE_TLSTREAM_TL_RET_AS_CTX(kbdev, &kbdev->as[kctx->as_nr], kctx);
2161 
2162 	/* Cause any future waiter-on-termination to wait until the context is
2163 	 * descheduled
2164 	 */
2165 	wake_up(&js_kctx_info->ctx.is_scheduled_wait);
2166 
2167 	/* Re-check for suspending: a suspend could've occurred, and all the
2168 	 * contexts could've been removed from the runpool before we took this
2169 	 * lock. In this case, we don't want to allow this context to run jobs,
2170 	 * we just want it out immediately.
2171 	 *
2172 	 * The DMB required to read the suspend flag was issued recently as part
2173 	 * of the hwaccess_lock locking. If a suspend occurs *after* that lock
2174 	 * was taken (i.e. this condition doesn't execute), then the
2175 	 * kbasep_js_suspend() code will cleanup this context instead (by virtue
2176 	 * of it being called strictly after the suspend flag is set, and will
2177 	 * wait for this lock to drop)
2178 	 */
2179 #ifdef CONFIG_MALI_ARBITER_SUPPORT
2180 	if (kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev)) {
2181 #else
2182 	if (kbase_pm_is_suspending(kbdev)) {
2183 #endif
2184 		/* Cause it to leave at some later point */
2185 		bool retained;
2186 
2187 		retained = kbase_ctx_sched_inc_refcount_nolock(kctx);
2188 		KBASE_DEBUG_ASSERT(retained);
2189 
2190 		kbasep_js_clear_submit_allowed(js_devdata, kctx);
2191 		kctx_suspended = true;
2192 	}
2193 
2194 	kbase_ctx_flag_clear(kctx, KCTX_PULLED_SINCE_ACTIVE_JS0 << js);
2195 
2196 	/* Transaction complete */
2197 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2198 	mutex_unlock(&kbdev->mmu_hw_mutex);
2199 
2200 	/* Synchronize with any timers */
2201 	kbase_backend_ctx_count_changed(kbdev);
2202 
2203 	mutex_unlock(&js_devdata->runpool_mutex);
2204 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2205 	/* Note: after this point, the context could potentially get scheduled
2206 	 * out immediately
2207 	 */
2208 
2209 	if (kctx_suspended) {
2210 		/* Finishing forcing out the context due to a suspend. Use a
2211 		 * variant of kbasep_js_runpool_release_ctx() that doesn't
2212 		 * schedule a new context, to prevent a risk of recursion back
2213 		 * into this function
2214 		 */
2215 		kbasep_js_runpool_release_ctx_no_schedule(kbdev, kctx);
2216 		return false;
2217 	}
2218 	return true;
2219 }
2220 
2221 static bool kbase_js_use_ctx(struct kbase_device *kbdev,
2222 				struct kbase_context *kctx,
2223 				int js)
2224 {
2225 	unsigned long flags;
2226 
2227 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2228 
2229 	if (kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
2230 			kbase_backend_use_ctx_sched(kbdev, kctx, js)) {
2231 
2232 		dev_dbg(kbdev->dev,
2233 			"kctx %pK already has ASID - mark as active (s:%d)\n",
2234 			(void *)kctx, js);
2235 
2236 		if (kbdev->hwaccess.active_kctx[js] != kctx) {
2237 			kbdev->hwaccess.active_kctx[js] = kctx;
2238 			kbase_ctx_flag_clear(kctx,
2239 					KCTX_PULLED_SINCE_ACTIVE_JS0 << js);
2240 		}
2241 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2242 		return true; /* Context already scheduled */
2243 	}
2244 
2245 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2246 	return kbasep_js_schedule_ctx(kbdev, kctx, js);
2247 }
2248 
2249 void kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev,
2250 		struct kbase_context *kctx)
2251 {
2252 	struct kbasep_js_kctx_info *js_kctx_info;
2253 	struct kbasep_js_device_data *js_devdata;
2254 	bool is_scheduled;
2255 
2256 	KBASE_DEBUG_ASSERT(kbdev != NULL);
2257 	KBASE_DEBUG_ASSERT(kctx != NULL);
2258 
2259 	js_devdata = &kbdev->js_data;
2260 	js_kctx_info = &kctx->jctx.sched_info;
2261 
2262 #ifdef CONFIG_MALI_ARBITER_SUPPORT
2263 	/* This should only happen in response to a system call
2264 	 * from a user-space thread.
2265 	 * In a non-arbitrated environment this can never happen
2266 	 * whilst suspending.
2267 	 *
2268 	 * In an arbitrated environment, user-space threads can run
2269 	 * while we are suspended (for example GPU not available
2270 	 * to this VM), however in that case we will block on
2271 	 * the wait event for KCTX_SCHEDULED, since no context
2272 	 * can be scheduled until we have the GPU again.
2273 	 */
2274 	if (kbdev->arb.arb_if == NULL)
2275 		if (WARN_ON(kbase_pm_is_suspending(kbdev)))
2276 			return;
2277 #else
2278 	/* This should only happen in response to a system call
2279 	 * from a user-space thread.
2280 	 * In a non-arbitrated environment this can never happen
2281 	 * whilst suspending.
2282 	 */
2283 	if (WARN_ON(kbase_pm_is_suspending(kbdev)))
2284 		return;
2285 #endif
2286 
2287 	mutex_lock(&js_devdata->queue_mutex);
2288 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2289 
2290 	/* Mark the context as privileged */
2291 	kbase_ctx_flag_set(kctx, KCTX_PRIVILEGED);
2292 
2293 	is_scheduled = kbase_ctx_flag(kctx, KCTX_SCHEDULED);
2294 	if (!is_scheduled) {
2295 		/* Add the context to the pullable list */
2296 		if (kbase_js_ctx_list_add_pullable_head(kbdev, kctx, 0))
2297 			kbase_js_sync_timers(kbdev);
2298 
2299 		/* Fast-starting requires the jsctx_mutex to be dropped,
2300 		 * because it works on multiple ctxs
2301 		 */
2302 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2303 		mutex_unlock(&js_devdata->queue_mutex);
2304 
2305 		/* Try to schedule the context in */
2306 		kbase_js_sched_all(kbdev);
2307 
2308 		/* Wait for the context to be scheduled in */
2309 		wait_event(kctx->jctx.sched_info.ctx.is_scheduled_wait,
2310 			   kbase_ctx_flag(kctx, KCTX_SCHEDULED));
2311 	} else {
2312 		/* Already scheduled in - We need to retain it to keep the
2313 		 * corresponding address space
2314 		 */
2315 		WARN_ON(!kbase_ctx_sched_inc_refcount(kctx));
2316 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2317 		mutex_unlock(&js_devdata->queue_mutex);
2318 	}
2319 }
2320 KBASE_EXPORT_TEST_API(kbasep_js_schedule_privileged_ctx);
2321 
2322 void kbasep_js_release_privileged_ctx(struct kbase_device *kbdev,
2323 		struct kbase_context *kctx)
2324 {
2325 	struct kbasep_js_kctx_info *js_kctx_info;
2326 
2327 	KBASE_DEBUG_ASSERT(kctx != NULL);
2328 	js_kctx_info = &kctx->jctx.sched_info;
2329 
2330 	/* We don't need to use the address space anymore */
2331 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2332 	kbase_ctx_flag_clear(kctx, KCTX_PRIVILEGED);
2333 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2334 
2335 	/* Release the context - it will be scheduled out */
2336 	kbasep_js_runpool_release_ctx(kbdev, kctx);
2337 
2338 	kbase_js_sched_all(kbdev);
2339 }
2340 KBASE_EXPORT_TEST_API(kbasep_js_release_privileged_ctx);
2341 
2342 void kbasep_js_suspend(struct kbase_device *kbdev)
2343 {
2344 	unsigned long flags;
2345 	struct kbasep_js_device_data *js_devdata;
2346 	int i;
2347 	u16 retained = 0u;
2348 
2349 	KBASE_DEBUG_ASSERT(kbdev);
2350 	KBASE_DEBUG_ASSERT(kbase_pm_is_suspending(kbdev));
2351 	js_devdata = &kbdev->js_data;
2352 
2353 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2354 
2355 	/* Prevent all contexts from submitting */
2356 	js_devdata->runpool_irq.submit_allowed = 0;
2357 
2358 	/* Retain each of the contexts, so we can cause it to leave even if it
2359 	 * had no refcount to begin with
2360 	 */
2361 	for (i = BASE_MAX_NR_AS - 1; i >= 0; --i) {
2362 		struct kbase_context *kctx = kbdev->as_to_kctx[i];
2363 
2364 		retained = retained << 1;
2365 
2366 		if (kctx && !(kbdev->as_free & (1u << i))) {
2367 			kbase_ctx_sched_retain_ctx_refcount(kctx);
2368 			retained |= 1u;
2369 			/* This loop will not have an effect on the privileged
2370 			 * contexts as they would have an extra ref count
2371 			 * compared to the normal contexts, so they will hold
2372 			 * on to their address spaces. MMU will re-enabled for
2373 			 * them on resume.
2374 			 */
2375 		}
2376 	}
2377 
2378 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2379 
2380 	/* De-ref the previous retain to ensure each context gets pulled out
2381 	 * sometime later.
2382 	 */
2383 	for (i = 0;
2384 		 i < BASE_MAX_NR_AS;
2385 		 ++i, retained = retained >> 1) {
2386 		struct kbase_context *kctx = kbdev->as_to_kctx[i];
2387 
2388 		if (retained & 1u)
2389 			kbasep_js_runpool_release_ctx(kbdev, kctx);
2390 	}
2391 
2392 	/* Caller must wait for all Power Manager active references to be
2393 	 * dropped
2394 	 */
2395 }
2396 
2397 void kbasep_js_resume(struct kbase_device *kbdev)
2398 {
2399 	struct kbasep_js_device_data *js_devdata;
2400 	int js, prio;
2401 
2402 	KBASE_DEBUG_ASSERT(kbdev);
2403 	js_devdata = &kbdev->js_data;
2404 	KBASE_DEBUG_ASSERT(!kbase_pm_is_suspending(kbdev));
2405 
2406 	mutex_lock(&js_devdata->queue_mutex);
2407 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
2408 		for (prio = KBASE_JS_ATOM_SCHED_PRIO_FIRST;
2409 			prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
2410 			struct kbase_context *kctx, *n;
2411 			unsigned long flags;
2412 
2413 #ifndef CONFIG_MALI_ARBITER_SUPPORT
2414 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2415 
2416 			list_for_each_entry_safe(kctx, n,
2417 				 &kbdev->js_data.ctx_list_unpullable[js][prio],
2418 				 jctx.sched_info.ctx.ctx_list_entry[js]) {
2419 				struct kbasep_js_kctx_info *js_kctx_info;
2420 				bool timer_sync = false;
2421 
2422 				/* Drop lock so we can take kctx mutexes */
2423 				spin_unlock_irqrestore(&kbdev->hwaccess_lock,
2424 						flags);
2425 
2426 				js_kctx_info = &kctx->jctx.sched_info;
2427 
2428 				mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2429 				mutex_lock(&js_devdata->runpool_mutex);
2430 				spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2431 
2432 				if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
2433 					kbase_js_ctx_pullable(kctx, js, false))
2434 					timer_sync =
2435 						kbase_js_ctx_list_add_pullable_nolock(
2436 								kbdev, kctx, js);
2437 
2438 				spin_unlock_irqrestore(&kbdev->hwaccess_lock,
2439 						flags);
2440 
2441 				if (timer_sync)
2442 					kbase_backend_ctx_count_changed(kbdev);
2443 
2444 				mutex_unlock(&js_devdata->runpool_mutex);
2445 				mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2446 
2447 				/* Take lock before accessing list again */
2448 				spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2449 			}
2450 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2451 #else
2452 			bool timer_sync = false;
2453 
2454 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2455 
2456 			list_for_each_entry_safe(kctx, n,
2457 				 &kbdev->js_data.ctx_list_unpullable[js][prio],
2458 				 jctx.sched_info.ctx.ctx_list_entry[js]) {
2459 
2460 				if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
2461 					kbase_js_ctx_pullable(kctx, js, false))
2462 					timer_sync |=
2463 						kbase_js_ctx_list_add_pullable_nolock(
2464 							kbdev, kctx, js);
2465 			}
2466 
2467 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2468 
2469 			if (timer_sync) {
2470 				mutex_lock(&js_devdata->runpool_mutex);
2471 				kbase_backend_ctx_count_changed(kbdev);
2472 				mutex_unlock(&js_devdata->runpool_mutex);
2473 			}
2474 #endif
2475 		}
2476 	}
2477 	mutex_unlock(&js_devdata->queue_mutex);
2478 
2479 	/* Restart atom processing */
2480 	kbase_js_sched_all(kbdev);
2481 
2482 	/* JS Resume complete */
2483 }
2484 
2485 bool kbase_js_is_atom_valid(struct kbase_device *kbdev,
2486 				struct kbase_jd_atom *katom)
2487 {
2488 	if ((katom->core_req & BASE_JD_REQ_FS) &&
2489 	    (katom->core_req & (BASE_JD_REQ_CS | BASE_JD_REQ_ONLY_COMPUTE |
2490 								BASE_JD_REQ_T)))
2491 		return false;
2492 
2493 	if ((katom->core_req & BASE_JD_REQ_JOB_SLOT) &&
2494 			(katom->jobslot >= BASE_JM_MAX_NR_SLOTS))
2495 		return false;
2496 
2497 	return true;
2498 }
2499 
2500 static int kbase_js_get_slot(struct kbase_device *kbdev,
2501 				struct kbase_jd_atom *katom)
2502 {
2503 	if (katom->core_req & BASE_JD_REQ_JOB_SLOT)
2504 		return katom->jobslot;
2505 
2506 	if (katom->core_req & BASE_JD_REQ_FS)
2507 		return 0;
2508 
2509 	if (katom->core_req & BASE_JD_REQ_ONLY_COMPUTE) {
2510 		if (katom->device_nr == 1 &&
2511 				kbdev->gpu_props.num_core_groups == 2)
2512 			return 2;
2513 	}
2514 
2515 	return 1;
2516 }
2517 
2518 bool kbase_js_dep_resolved_submit(struct kbase_context *kctx,
2519 					struct kbase_jd_atom *katom)
2520 {
2521 	bool enqueue_required, add_required = true;
2522 
2523 	katom->slot_nr = kbase_js_get_slot(kctx->kbdev, katom);
2524 
2525 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2526 	lockdep_assert_held(&kctx->jctx.lock);
2527 
2528 	/* If slot will transition from unpullable to pullable then add to
2529 	 * pullable list
2530 	 */
2531 	if (jsctx_rb_none_to_pull(kctx, katom->slot_nr)) {
2532 		enqueue_required = true;
2533 	} else {
2534 		enqueue_required = false;
2535 	}
2536 
2537 	if ((katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) ||
2538 			(katom->pre_dep && (katom->pre_dep->atom_flags &
2539 			KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST))) {
2540 		int prio = katom->sched_priority;
2541 		int js = katom->slot_nr;
2542 		struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
2543 
2544 		dev_dbg(kctx->kbdev->dev, "Add atom %pK to X_DEP list (s:%d)\n",
2545 			(void *)katom, js);
2546 
2547 		list_add_tail(&katom->queue, &queue->x_dep_head);
2548 		katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
2549 		if (kbase_js_atom_blocked_on_x_dep(katom)) {
2550 			enqueue_required = false;
2551 			add_required = false;
2552 		}
2553 	} else {
2554 		dev_dbg(kctx->kbdev->dev, "Atom %pK not added to X_DEP list\n",
2555 			(void *)katom);
2556 	}
2557 
2558 	if (add_required) {
2559 		/* Check if there are lower priority jobs to soft stop */
2560 		kbase_job_slot_ctx_priority_check_locked(kctx, katom);
2561 
2562 		/* Add atom to ring buffer. */
2563 		jsctx_tree_add(kctx, katom);
2564 		katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_TREE;
2565 	}
2566 
2567 	dev_dbg(kctx->kbdev->dev,
2568 		"Enqueue of kctx %pK is %srequired to submit atom %pK\n",
2569 		kctx, enqueue_required ? "" : "not ", katom);
2570 
2571 	return enqueue_required;
2572 }
2573 
2574 /**
2575  * kbase_js_move_to_tree - Move atom (and any dependent atoms) to the
2576  *                         runnable_tree, ready for execution
2577  * @katom: Atom to submit
2578  *
2579  * It is assumed that @katom does not have KBASE_KATOM_FLAG_X_DEP_BLOCKED set,
2580  * but is still present in the x_dep list. If @katom has a same-slot dependent
2581  * atom then that atom (and any dependents) will also be moved.
2582  */
2583 static void kbase_js_move_to_tree(struct kbase_jd_atom *katom)
2584 {
2585 	struct kbase_context *const kctx = katom->kctx;
2586 
2587 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2588 
2589 	while (katom) {
2590 		WARN_ON(!(katom->atom_flags &
2591 				KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST));
2592 
2593 		if (!kbase_js_atom_blocked_on_x_dep(katom)) {
2594 			dev_dbg(kctx->kbdev->dev,
2595 				"Del atom %pK from X_DEP list in js_move_to_tree\n",
2596 				(void *)katom);
2597 
2598 			list_del(&katom->queue);
2599 			katom->atom_flags &=
2600 					~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
2601 			/* For incremental rendering, an end-of-renderpass atom
2602 			 * may have had its dependency on start-of-renderpass
2603 			 * ignored and may therefore already be in the tree.
2604 			 */
2605 			if (!(katom->atom_flags &
2606 				KBASE_KATOM_FLAG_JSCTX_IN_TREE)) {
2607 				jsctx_tree_add(kctx, katom);
2608 				katom->atom_flags |=
2609 					KBASE_KATOM_FLAG_JSCTX_IN_TREE;
2610 			}
2611 		} else {
2612 			dev_dbg(kctx->kbdev->dev,
2613 				"Atom %pK blocked on x-dep in js_move_to_tree\n",
2614 				(void *)katom);
2615 			break;
2616 		}
2617 
2618 		katom = katom->post_dep;
2619 	}
2620 }
2621 
2622 
2623 /**
2624  * kbase_js_evict_deps - Evict dependencies of a failed atom.
2625  * @kctx:       Context pointer
2626  * @katom:      Pointer to the atom that has failed.
2627  * @js:         The job slot the katom was run on.
2628  * @prio:       Priority of the katom.
2629  *
2630  * Remove all post dependencies of an atom from the context ringbuffers.
2631  *
2632  * The original atom's event_code will be propogated to all dependent atoms.
2633  *
2634  * Context: Caller must hold the HW access lock
2635  */
2636 static void kbase_js_evict_deps(struct kbase_context *kctx,
2637 				struct kbase_jd_atom *katom, int js, int prio)
2638 {
2639 	struct kbase_jd_atom *x_dep = katom->x_post_dep;
2640 	struct kbase_jd_atom *next_katom = katom->post_dep;
2641 
2642 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2643 
2644 	if (next_katom) {
2645 		KBASE_DEBUG_ASSERT(next_katom->status !=
2646 				KBASE_JD_ATOM_STATE_HW_COMPLETED);
2647 		next_katom->will_fail_event_code = katom->event_code;
2648 
2649 	}
2650 
2651 	/* Has cross slot depenency. */
2652 	if (x_dep && (x_dep->atom_flags & (KBASE_KATOM_FLAG_JSCTX_IN_TREE |
2653 				KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST))) {
2654 		/* Remove dependency.*/
2655 		x_dep->atom_flags &= ~KBASE_KATOM_FLAG_X_DEP_BLOCKED;
2656 
2657 		dev_dbg(kctx->kbdev->dev, "Cleared X_DEP flag on atom %pK\n",
2658 			(void *)x_dep);
2659 
2660 		/* Fail if it had a data dependency. */
2661 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) {
2662 			x_dep->will_fail_event_code = katom->event_code;
2663 		}
2664 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST)
2665 			kbase_js_move_to_tree(x_dep);
2666 	}
2667 }
2668 
2669 struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, int js)
2670 {
2671 	struct kbase_jd_atom *katom;
2672 	struct kbasep_js_device_data *js_devdata;
2673 	struct kbase_device *kbdev;
2674 	int pulled;
2675 
2676 	KBASE_DEBUG_ASSERT(kctx);
2677 
2678 	kbdev = kctx->kbdev;
2679 	dev_dbg(kbdev->dev, "JS: pulling an atom from kctx %pK (s:%d)\n",
2680 		(void *)kctx, js);
2681 
2682 	js_devdata = &kbdev->js_data;
2683 	lockdep_assert_held(&kbdev->hwaccess_lock);
2684 
2685 	if (!kbasep_js_is_submit_allowed(js_devdata, kctx)) {
2686 		dev_dbg(kbdev->dev, "JS: No submit allowed for kctx %pK\n",
2687 			(void *)kctx);
2688 		return NULL;
2689 	}
2690 #ifdef CONFIG_MALI_ARBITER_SUPPORT
2691 	if (kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev))
2692 #else
2693 	if (kbase_pm_is_suspending(kbdev))
2694 #endif
2695 		return NULL;
2696 
2697 	katom = jsctx_rb_peek(kctx, js);
2698 	if (!katom) {
2699 		dev_dbg(kbdev->dev, "JS: No pullable atom in kctx %pK (s:%d)\n",
2700 			(void *)kctx, js);
2701 		return NULL;
2702 	}
2703 	if (kbase_jsctx_slot_prio_is_blocked(kctx, js, katom->sched_priority)) {
2704 		dev_dbg(kbdev->dev,
2705 			"JS: kctx %pK is blocked from submitting atoms at priority %d and lower (s:%d)\n",
2706 			(void *)kctx, katom->sched_priority, js);
2707 		return NULL;
2708 	}
2709 	if (atomic_read(&katom->blocked)) {
2710 		dev_dbg(kbdev->dev, "JS: Atom %pK is blocked in js_pull\n",
2711 			(void *)katom);
2712 		return NULL;
2713 	}
2714 
2715 	/* Due to ordering restrictions when unpulling atoms on failure, we do
2716 	 * not allow multiple runs of fail-dep atoms from the same context to be
2717 	 * present on the same slot
2718 	 */
2719 	if (katom->pre_dep && kbase_jsctx_slot_atoms_pulled(kctx, js)) {
2720 		struct kbase_jd_atom *prev_atom =
2721 				kbase_backend_inspect_tail(kbdev, js);
2722 
2723 		if (prev_atom && prev_atom->kctx != kctx)
2724 			return NULL;
2725 	}
2726 
2727 	if (kbase_js_atom_blocked_on_x_dep(katom)) {
2728 		if (katom->x_pre_dep->gpu_rb_state ==
2729 				KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
2730 				katom->x_pre_dep->will_fail_event_code)	{
2731 			dev_dbg(kbdev->dev,
2732 				"JS: X pre-dep %pK is not present in slot FIFO or will fail\n",
2733 				(void *)katom->x_pre_dep);
2734 			return NULL;
2735 		}
2736 		if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
2737 				kbase_backend_nr_atoms_on_slot(kbdev, js)) {
2738 			dev_dbg(kbdev->dev,
2739 				"JS: Atom %pK has cross-slot fail dependency and atoms on slot (s:%d)\n",
2740 				(void *)katom, js);
2741 			return NULL;
2742 		}
2743 	}
2744 
2745 	KBASE_KTRACE_ADD_JM_SLOT_INFO(kbdev, JS_PULL_JOB, kctx, katom,
2746 				      katom->jc, js, katom->sched_priority);
2747 	kbase_ctx_flag_set(kctx, KCTX_PULLED);
2748 	kbase_ctx_flag_set(kctx, (KCTX_PULLED_SINCE_ACTIVE_JS0 << js));
2749 
2750 	pulled = kbase_jsctx_slot_atom_pulled_inc(kctx, katom);
2751 	if (pulled == 1 && !kctx->slots_pullable) {
2752 		WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
2753 		kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
2754 		atomic_inc(&kbdev->js_data.nr_contexts_runnable);
2755 	}
2756 	jsctx_rb_pull(kctx, katom);
2757 
2758 	kbase_ctx_sched_retain_ctx_refcount(kctx);
2759 
2760 	katom->ticks = 0;
2761 
2762 	dev_dbg(kbdev->dev, "JS: successfully pulled atom %pK from kctx %pK (s:%d)\n",
2763 		(void *)katom, (void *)kctx, js);
2764 
2765 	return katom;
2766 }
2767 
2768 /**
2769  * js_return_of_start_rp() - Handle soft-stop of an atom that starts a
2770  *                           renderpass
2771  * @start_katom: Pointer to the start-of-renderpass atom that was soft-stopped
2772  *
2773  * This function is called to switch to incremental rendering if the tiler job
2774  * chain at the start of a renderpass has used too much memory. It prevents the
2775  * tiler job being pulled for execution in the job scheduler again until the
2776  * next phase of incremental rendering is complete.
2777  *
2778  * If the end-of-renderpass atom is already in the job scheduler (because a
2779  * previous attempt at tiling used too much memory during the same renderpass)
2780  * then it is unblocked; otherwise, it is run by handing it to the scheduler.
2781  */
2782 static void js_return_of_start_rp(struct kbase_jd_atom *const start_katom)
2783 {
2784 	struct kbase_context *const kctx = start_katom->kctx;
2785 	struct kbase_device *const kbdev = kctx->kbdev;
2786 	struct kbase_jd_renderpass *rp;
2787 	struct kbase_jd_atom *end_katom;
2788 	unsigned long flags;
2789 
2790 	lockdep_assert_held(&kctx->jctx.lock);
2791 
2792 	if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
2793 		return;
2794 
2795 	compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
2796 			ARRAY_SIZE(kctx->jctx.renderpasses),
2797 			"Should check invalid access to renderpasses");
2798 
2799 	rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
2800 
2801 	if (WARN_ON(rp->start_katom != start_katom))
2802 		return;
2803 
2804 	dev_dbg(kctx->kbdev->dev,
2805 		"JS return start atom %pK in state %d of RP %d\n",
2806 		(void *)start_katom, (int)rp->state,
2807 		start_katom->renderpass_id);
2808 
2809 	if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
2810 		return;
2811 
2812 	/* The tiler job might have been soft-stopped for some reason other
2813 	 * than running out of memory.
2814 	 */
2815 	if (rp->state == KBASE_JD_RP_START || rp->state == KBASE_JD_RP_RETRY) {
2816 		dev_dbg(kctx->kbdev->dev,
2817 			"JS return isn't OOM in state %d of RP %d\n",
2818 			(int)rp->state, start_katom->renderpass_id);
2819 		return;
2820 	}
2821 
2822 	dev_dbg(kctx->kbdev->dev,
2823 		"JS return confirm OOM in state %d of RP %d\n",
2824 		(int)rp->state, start_katom->renderpass_id);
2825 
2826 	if (WARN_ON(rp->state != KBASE_JD_RP_PEND_OOM &&
2827 		rp->state != KBASE_JD_RP_RETRY_PEND_OOM))
2828 		return;
2829 
2830 	/* Prevent the tiler job being pulled for execution in the
2831 	 * job scheduler again.
2832 	 */
2833 	dev_dbg(kbdev->dev, "Blocking start atom %pK\n",
2834 		(void *)start_katom);
2835 	atomic_inc(&start_katom->blocked);
2836 
2837 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2838 
2839 	rp->state = (rp->state == KBASE_JD_RP_PEND_OOM) ?
2840 		KBASE_JD_RP_OOM : KBASE_JD_RP_RETRY_OOM;
2841 
2842 	/* Was the fragment job chain submitted to kbase yet? */
2843 	end_katom = rp->end_katom;
2844 	if (end_katom) {
2845 		dev_dbg(kctx->kbdev->dev, "JS return add end atom %pK\n",
2846 			(void *)end_katom);
2847 
2848 		if (rp->state == KBASE_JD_RP_RETRY_OOM) {
2849 			/* Allow the end of the renderpass to be pulled for
2850 			 * execution again to continue incremental rendering.
2851 			 */
2852 			dev_dbg(kbdev->dev, "Unblocking end atom %pK\n",
2853 				(void *)end_katom);
2854 			atomic_dec(&end_katom->blocked);
2855 			WARN_ON(!(end_katom->atom_flags &
2856 				KBASE_KATOM_FLAG_JSCTX_IN_TREE));
2857 			WARN_ON(end_katom->status != KBASE_JD_ATOM_STATE_IN_JS);
2858 
2859 			kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx,
2860 				end_katom->slot_nr);
2861 
2862 			/* Expect the fragment job chain to be scheduled without
2863 			 * further action because this function is called when
2864 			 * returning an atom to the job scheduler ringbuffer.
2865 			 */
2866 			end_katom = NULL;
2867 		} else {
2868 			WARN_ON(end_katom->status !=
2869 				KBASE_JD_ATOM_STATE_QUEUED &&
2870 				end_katom->status != KBASE_JD_ATOM_STATE_IN_JS);
2871 		}
2872 	}
2873 
2874 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2875 
2876 	if (end_katom)
2877 		kbase_jd_dep_clear_locked(end_katom);
2878 }
2879 
2880 /**
2881  * js_return_of_end_rp() - Handle completion of an atom that ends a renderpass
2882  * @end_katom: Pointer to the end-of-renderpass atom that was completed
2883  *
2884  * This function is called to continue incremental rendering if the tiler job
2885  * chain at the start of a renderpass used too much memory. It resets the
2886  * mechanism for detecting excessive memory usage then allows the soft-stopped
2887  * tiler job chain to be pulled for execution again.
2888  *
2889  * The start-of-renderpass atom must already been submitted to kbase.
2890  */
2891 static void js_return_of_end_rp(struct kbase_jd_atom *const end_katom)
2892 {
2893 	struct kbase_context *const kctx = end_katom->kctx;
2894 	struct kbase_device *const kbdev = kctx->kbdev;
2895 	struct kbase_jd_renderpass *rp;
2896 	struct kbase_jd_atom *start_katom;
2897 	unsigned long flags;
2898 
2899 	lockdep_assert_held(&kctx->jctx.lock);
2900 
2901 	if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
2902 		return;
2903 
2904 	compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
2905 			ARRAY_SIZE(kctx->jctx.renderpasses),
2906 			"Should check invalid access to renderpasses");
2907 
2908 	rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
2909 
2910 	if (WARN_ON(rp->end_katom != end_katom))
2911 		return;
2912 
2913 	dev_dbg(kctx->kbdev->dev,
2914 		"JS return end atom %pK in state %d of RP %d\n",
2915 		(void *)end_katom, (int)rp->state, end_katom->renderpass_id);
2916 
2917 	if (WARN_ON(rp->state != KBASE_JD_RP_OOM &&
2918 		rp->state != KBASE_JD_RP_RETRY_OOM))
2919 		return;
2920 
2921 	/* Reduce the number of mapped pages in the memory regions that
2922 	 * triggered out-of-memory last time so that we can detect excessive
2923 	 * memory usage again.
2924 	 */
2925 	kbase_gpu_vm_lock(kctx);
2926 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2927 
2928 	while (!list_empty(&rp->oom_reg_list)) {
2929 		struct kbase_va_region *reg =
2930 			list_first_entry(&rp->oom_reg_list,
2931 					 struct kbase_va_region, link);
2932 
2933 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2934 
2935 		dev_dbg(kbdev->dev,
2936 			"Reset backing to %zu pages for region %pK\n",
2937 			reg->threshold_pages, (void *)reg);
2938 
2939 		if (!WARN_ON(reg->flags & KBASE_REG_VA_FREED))
2940 			kbase_mem_shrink(kctx, reg, reg->threshold_pages);
2941 
2942 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2943 		dev_dbg(kbdev->dev, "Deleting region %pK from list\n",
2944 			(void *)reg);
2945 		list_del_init(&reg->link);
2946 		kbase_va_region_alloc_put(kctx, reg);
2947 	}
2948 
2949 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2950 	kbase_gpu_vm_unlock(kctx);
2951 
2952 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2953 	rp->state = KBASE_JD_RP_RETRY;
2954 	dev_dbg(kbdev->dev, "Changed state to %d for retry\n", rp->state);
2955 
2956 	/* Allow the start of the renderpass to be pulled for execution again
2957 	 * to begin/continue incremental rendering.
2958 	 */
2959 	start_katom = rp->start_katom;
2960 	if (!WARN_ON(!start_katom)) {
2961 		dev_dbg(kbdev->dev, "Unblocking start atom %pK\n",
2962 			(void *)start_katom);
2963 		atomic_dec(&start_katom->blocked);
2964 		(void)kbase_js_ctx_list_add_pullable_head_nolock(kbdev, kctx,
2965 			start_katom->slot_nr);
2966 	}
2967 
2968 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2969 }
2970 
2971 static void js_return_worker(struct work_struct *data)
2972 {
2973 	struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom,
2974 									work);
2975 	struct kbase_context *kctx = katom->kctx;
2976 	struct kbase_device *kbdev = kctx->kbdev;
2977 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
2978 	struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
2979 	struct kbasep_js_atom_retained_state retained_state;
2980 	int js = katom->slot_nr;
2981 	bool slot_became_unblocked;
2982 	bool timer_sync = false;
2983 	bool context_idle = false;
2984 	unsigned long flags;
2985 	base_jd_core_req core_req = katom->core_req;
2986 	u64 cache_jc = katom->jc;
2987 
2988 	dev_dbg(kbdev->dev, "%s for atom %pK with event code 0x%x\n",
2989 		__func__, (void *)katom, katom->event_code);
2990 
2991 	KBASE_KTRACE_ADD_JM(kbdev, JS_RETURN_WORKER, kctx, katom, katom->jc, 0);
2992 
2993 	if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
2994 		KBASE_TLSTREAM_TL_EVENT_ATOM_SOFTSTOP_EX(kbdev, katom);
2995 
2996 	kbase_backend_complete_wq(kbdev, katom);
2997 
2998 	kbasep_js_atom_retained_state_copy(&retained_state, katom);
2999 
3000 	mutex_lock(&js_devdata->queue_mutex);
3001 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
3002 
3003 	if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
3004 		atomic_dec(&katom->blocked);
3005 
3006 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3007 
3008 	slot_became_unblocked = kbase_jsctx_slot_atom_pulled_dec(kctx, katom);
3009 
3010 	if (!kbase_jsctx_slot_atoms_pulled(kctx, js) &&
3011 	    jsctx_rb_none_to_pull(kctx, js))
3012 		timer_sync |= kbase_js_ctx_list_remove_nolock(kbdev, kctx, js);
3013 
3014 	/* If the context is now unblocked on this slot after soft-stopped
3015 	 * atoms, then only mark it as pullable on this slot if it is not
3016 	 * idle
3017 	 */
3018 	if (slot_became_unblocked && kbase_jsctx_atoms_pulled(kctx) &&
3019 	    kbase_js_ctx_pullable(kctx, js, true))
3020 		timer_sync |=
3021 			kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx, js);
3022 
3023 	if (!kbase_jsctx_atoms_pulled(kctx)) {
3024 		dev_dbg(kbdev->dev,
3025 			"No atoms currently pulled from context %pK\n",
3026 			(void *)kctx);
3027 
3028 		if (!kctx->slots_pullable) {
3029 			dev_dbg(kbdev->dev,
3030 				"Context %pK %s counted as runnable\n",
3031 				(void *)kctx,
3032 				kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF) ?
3033 					"is" : "isn't");
3034 
3035 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
3036 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
3037 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
3038 			timer_sync = true;
3039 		}
3040 
3041 		if (kctx->as_nr != KBASEP_AS_NR_INVALID &&
3042 				!kbase_ctx_flag(kctx, KCTX_DYING)) {
3043 			int num_slots = kbdev->gpu_props.num_job_slots;
3044 			int slot;
3045 
3046 			if (!kbasep_js_is_submit_allowed(js_devdata, kctx))
3047 				kbasep_js_set_submit_allowed(js_devdata, kctx);
3048 
3049 			for (slot = 0; slot < num_slots; slot++) {
3050 				if (kbase_js_ctx_pullable(kctx, slot, true))
3051 					timer_sync |=
3052 					kbase_js_ctx_list_add_pullable_nolock(
3053 							kbdev, kctx, slot);
3054 			}
3055 		}
3056 
3057 		kbase_jm_idle_ctx(kbdev, kctx);
3058 
3059 		context_idle = true;
3060 	}
3061 
3062 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3063 
3064 	if (context_idle) {
3065 		dev_dbg(kbdev->dev,
3066 			"Context %pK %s counted as active\n",
3067 			(void *)kctx,
3068 			kbase_ctx_flag(kctx, KCTX_ACTIVE) ?
3069 				"is" : "isn't");
3070 		WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
3071 		kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
3072 		kbase_pm_context_idle(kbdev);
3073 	}
3074 
3075 	if (timer_sync)
3076 		kbase_js_sync_timers(kbdev);
3077 
3078 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
3079 	mutex_unlock(&js_devdata->queue_mutex);
3080 
3081 	if (katom->core_req & BASE_JD_REQ_START_RENDERPASS) {
3082 		mutex_lock(&kctx->jctx.lock);
3083 		js_return_of_start_rp(katom);
3084 		mutex_unlock(&kctx->jctx.lock);
3085 	} else if (katom->event_code == BASE_JD_EVENT_END_RP_DONE) {
3086 		mutex_lock(&kctx->jctx.lock);
3087 		js_return_of_end_rp(katom);
3088 		mutex_unlock(&kctx->jctx.lock);
3089 	}
3090 
3091 	dev_dbg(kbdev->dev, "JS: retained state %s finished",
3092 		kbasep_js_has_atom_finished(&retained_state) ?
3093 		"has" : "hasn't");
3094 
3095 	WARN_ON(kbasep_js_has_atom_finished(&retained_state));
3096 
3097 	kbasep_js_runpool_release_ctx_and_katom_retained_state(kbdev, kctx,
3098 							&retained_state);
3099 
3100 	kbase_js_sched_all(kbdev);
3101 
3102 	kbase_backend_complete_wq_post_sched(kbdev, core_req);
3103 
3104 	KBASE_KTRACE_ADD_JM(kbdev, JS_RETURN_WORKER_END, kctx, NULL, cache_jc,
3105 			    0);
3106 
3107 	dev_dbg(kbdev->dev, "Leaving %s for atom %pK\n",
3108 		__func__, (void *)katom);
3109 }
3110 
3111 void kbase_js_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
3112 {
3113 	dev_dbg(kctx->kbdev->dev, "Unpulling atom %pK in kctx %pK\n",
3114 		(void *)katom, (void *)kctx);
3115 
3116 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
3117 
3118 	jsctx_rb_unpull(kctx, katom);
3119 
3120 	WARN_ON(work_pending(&katom->work));
3121 
3122 	/* Block re-submission until workqueue has run */
3123 	atomic_inc(&katom->blocked);
3124 
3125 	kbase_job_check_leave_disjoint(kctx->kbdev, katom);
3126 
3127 	INIT_WORK(&katom->work, js_return_worker);
3128 	queue_work(kctx->jctx.job_done_wq, &katom->work);
3129 }
3130 
3131 /**
3132  * js_complete_start_rp() - Handle completion of atom that starts a renderpass
3133  * @kctx:        Context pointer
3134  * @start_katom: Pointer to the atom that completed
3135  *
3136  * Put any references to virtual memory regions that might have been added by
3137  * kbase_job_slot_softstop_start_rp() because the tiler job chain completed
3138  * despite any pending soft-stop request.
3139  *
3140  * If the atom that just completed was soft-stopped during a previous attempt to
3141  * run it then there should be a blocked end-of-renderpass atom waiting for it,
3142  * which we must unblock to process the output of the tiler job chain.
3143  *
3144  * Return: true if caller should call kbase_backend_ctx_count_changed()
3145  */
3146 static bool js_complete_start_rp(struct kbase_context *kctx,
3147 	struct kbase_jd_atom *const start_katom)
3148 {
3149 	struct kbase_device *const kbdev = kctx->kbdev;
3150 	struct kbase_jd_renderpass *rp;
3151 	bool timer_sync = false;
3152 
3153 	lockdep_assert_held(&kctx->jctx.lock);
3154 
3155 	if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
3156 		return false;
3157 
3158 	compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
3159 			ARRAY_SIZE(kctx->jctx.renderpasses),
3160 			"Should check invalid access to renderpasses");
3161 
3162 	rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
3163 
3164 	if (WARN_ON(rp->start_katom != start_katom))
3165 		return false;
3166 
3167 	dev_dbg(kctx->kbdev->dev,
3168 		"Start atom %pK is done in state %d of RP %d\n",
3169 		(void *)start_katom, (int)rp->state,
3170 		start_katom->renderpass_id);
3171 
3172 	if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
3173 		return false;
3174 
3175 	if (rp->state == KBASE_JD_RP_PEND_OOM ||
3176 		rp->state == KBASE_JD_RP_RETRY_PEND_OOM) {
3177 		unsigned long flags;
3178 
3179 		dev_dbg(kctx->kbdev->dev,
3180 			"Start atom %pK completed before soft-stop\n",
3181 			(void *)start_katom);
3182 
3183 		kbase_gpu_vm_lock(kctx);
3184 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3185 
3186 		while (!list_empty(&rp->oom_reg_list)) {
3187 			struct kbase_va_region *reg =
3188 				list_first_entry(&rp->oom_reg_list,
3189 						 struct kbase_va_region, link);
3190 
3191 			WARN_ON(reg->flags & KBASE_REG_VA_FREED);
3192 			dev_dbg(kctx->kbdev->dev, "Deleting region %pK from list\n",
3193 				(void *)reg);
3194 			list_del_init(&reg->link);
3195 			kbase_va_region_alloc_put(kctx, reg);
3196 		}
3197 
3198 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3199 		kbase_gpu_vm_unlock(kctx);
3200 	} else {
3201 		dev_dbg(kctx->kbdev->dev,
3202 			"Start atom %pK did not exceed memory threshold\n",
3203 			(void *)start_katom);
3204 
3205 		WARN_ON(rp->state != KBASE_JD_RP_START &&
3206 			rp->state != KBASE_JD_RP_RETRY);
3207 	}
3208 
3209 	if (rp->state == KBASE_JD_RP_RETRY ||
3210 		rp->state == KBASE_JD_RP_RETRY_PEND_OOM) {
3211 		struct kbase_jd_atom *const end_katom = rp->end_katom;
3212 
3213 		if (!WARN_ON(!end_katom)) {
3214 			unsigned long flags;
3215 
3216 			/* Allow the end of the renderpass to be pulled for
3217 			 * execution again to continue incremental rendering.
3218 			 */
3219 			dev_dbg(kbdev->dev, "Unblocking end atom %pK!\n",
3220 				(void *)end_katom);
3221 			atomic_dec(&end_katom->blocked);
3222 
3223 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3224 			timer_sync = kbase_js_ctx_list_add_pullable_nolock(
3225 					kbdev, kctx, end_katom->slot_nr);
3226 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3227 		}
3228 	}
3229 
3230 	return timer_sync;
3231 }
3232 
3233 /**
3234  * js_complete_end_rp() - Handle final completion of atom that ends a renderpass
3235  * @kctx:      Context pointer
3236  * @end_katom: Pointer to the atom that completed for the last time
3237  *
3238  * This function must only be called if the renderpass actually completed
3239  * without the tiler job chain at the start using too much memory; otherwise
3240  * completion of the end-of-renderpass atom is handled similarly to a soft-stop.
3241  */
3242 static void js_complete_end_rp(struct kbase_context *kctx,
3243 	struct kbase_jd_atom *const end_katom)
3244 {
3245 	struct kbase_device *const kbdev = kctx->kbdev;
3246 	unsigned long flags;
3247 	struct kbase_jd_renderpass *rp;
3248 
3249 	lockdep_assert_held(&kctx->jctx.lock);
3250 
3251 	if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
3252 		return;
3253 
3254 	compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
3255 			ARRAY_SIZE(kctx->jctx.renderpasses),
3256 			"Should check invalid access to renderpasses");
3257 
3258 	rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
3259 
3260 	if (WARN_ON(rp->end_katom != end_katom))
3261 		return;
3262 
3263 	dev_dbg(kbdev->dev, "End atom %pK is done in state %d of RP %d\n",
3264 		(void *)end_katom, (int)rp->state, end_katom->renderpass_id);
3265 
3266 	if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE) ||
3267 		WARN_ON(rp->state == KBASE_JD_RP_OOM) ||
3268 		WARN_ON(rp->state == KBASE_JD_RP_RETRY_OOM))
3269 		return;
3270 
3271 	/* Rendering completed without running out of memory.
3272 	 */
3273 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3274 	WARN_ON(!list_empty(&rp->oom_reg_list));
3275 	rp->state = KBASE_JD_RP_COMPLETE;
3276 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3277 
3278 	dev_dbg(kbdev->dev, "Renderpass %d is complete\n",
3279 		end_katom->renderpass_id);
3280 }
3281 
3282 bool kbase_js_complete_atom_wq(struct kbase_context *kctx,
3283 						struct kbase_jd_atom *katom)
3284 {
3285 	struct kbasep_js_kctx_info *js_kctx_info;
3286 	struct kbasep_js_device_data *js_devdata;
3287 	struct kbase_device *kbdev;
3288 	unsigned long flags;
3289 	bool timer_sync = false;
3290 	int atom_slot;
3291 	bool context_idle = false;
3292 	int prio = katom->sched_priority;
3293 
3294 	kbdev = kctx->kbdev;
3295 	atom_slot = katom->slot_nr;
3296 
3297 	dev_dbg(kbdev->dev, "%s for atom %pK (s:%d)\n",
3298 		__func__, (void *)katom, atom_slot);
3299 
3300 	/* Update the incremental rendering state machine.
3301 	 */
3302 	if (katom->core_req & BASE_JD_REQ_START_RENDERPASS)
3303 		timer_sync |= js_complete_start_rp(kctx, katom);
3304 	else if (katom->core_req & BASE_JD_REQ_END_RENDERPASS)
3305 		js_complete_end_rp(kctx, katom);
3306 
3307 	js_kctx_info = &kctx->jctx.sched_info;
3308 	js_devdata = &kbdev->js_data;
3309 
3310 	lockdep_assert_held(&js_kctx_info->ctx.jsctx_mutex);
3311 
3312 	mutex_lock(&js_devdata->runpool_mutex);
3313 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3314 
3315 	if (katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE) {
3316 		bool slot_became_unblocked;
3317 
3318 		dev_dbg(kbdev->dev, "Atom %pK is in runnable_tree\n",
3319 			(void *)katom);
3320 
3321 		slot_became_unblocked =
3322 			kbase_jsctx_slot_atom_pulled_dec(kctx, katom);
3323 		context_idle = !kbase_jsctx_atoms_pulled(kctx);
3324 
3325 		if (!kbase_jsctx_atoms_pulled(kctx) && !kctx->slots_pullable) {
3326 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
3327 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
3328 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
3329 			timer_sync = true;
3330 		}
3331 
3332 		/* If this slot has been blocked due to soft-stopped atoms, and
3333 		 * all atoms have now been processed at this priority level and
3334 		 * higher, then unblock the slot
3335 		 */
3336 		if (slot_became_unblocked) {
3337 			dev_dbg(kbdev->dev,
3338 				"kctx %pK is no longer blocked from submitting on slot %d at priority %d or higher\n",
3339 				(void *)kctx, atom_slot, prio);
3340 
3341 			if (kbase_js_ctx_pullable(kctx, atom_slot, true))
3342 				timer_sync |=
3343 					kbase_js_ctx_list_add_pullable_nolock(
3344 						kbdev, kctx, atom_slot);
3345 		}
3346 	}
3347 	WARN_ON(!(katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE));
3348 
3349 	if (!kbase_jsctx_slot_atoms_pulled(kctx, atom_slot) &&
3350 	    jsctx_rb_none_to_pull(kctx, atom_slot)) {
3351 		if (!list_empty(
3352 			&kctx->jctx.sched_info.ctx.ctx_list_entry[atom_slot]))
3353 			timer_sync |= kbase_js_ctx_list_remove_nolock(
3354 					kctx->kbdev, kctx, atom_slot);
3355 	}
3356 
3357 	/*
3358 	 * If submission is disabled on this context (most likely due to an
3359 	 * atom failure) and there are now no atoms left in the system then
3360 	 * re-enable submission so that context can be scheduled again.
3361 	 */
3362 	if (!kbasep_js_is_submit_allowed(js_devdata, kctx) &&
3363 	    !kbase_jsctx_atoms_pulled(kctx) &&
3364 	    !kbase_ctx_flag(kctx, KCTX_DYING)) {
3365 		int js;
3366 
3367 		kbasep_js_set_submit_allowed(js_devdata, kctx);
3368 
3369 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
3370 			if (kbase_js_ctx_pullable(kctx, js, true))
3371 				timer_sync |=
3372 					kbase_js_ctx_list_add_pullable_nolock(
3373 							kbdev, kctx, js);
3374 		}
3375 	} else if (katom->x_post_dep &&
3376 			kbasep_js_is_submit_allowed(js_devdata, kctx)) {
3377 		int js;
3378 
3379 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
3380 			if (kbase_js_ctx_pullable(kctx, js, true))
3381 				timer_sync |=
3382 					kbase_js_ctx_list_add_pullable_nolock(
3383 							kbdev, kctx, js);
3384 		}
3385 	}
3386 
3387 	/* Mark context as inactive. The pm reference will be dropped later in
3388 	 * jd_done_worker().
3389 	 */
3390 	if (context_idle) {
3391 		dev_dbg(kbdev->dev, "kctx %pK is no longer active\n",
3392 			(void *)kctx);
3393 		kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
3394 	}
3395 
3396 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3397 	if (timer_sync)
3398 		kbase_backend_ctx_count_changed(kbdev);
3399 	mutex_unlock(&js_devdata->runpool_mutex);
3400 
3401 	dev_dbg(kbdev->dev, "Leaving %s\n", __func__);
3402 	return context_idle;
3403 }
3404 
3405 /**
3406  * js_end_rp_is_complete() - Check whether an atom that ends a renderpass has
3407  *                           completed for the last time.
3408  *
3409  * @end_katom: Pointer to the atom that completed on the hardware.
3410  *
3411  * An atom that ends a renderpass may be run on the hardware several times
3412  * before notifying userspace or allowing dependent atoms to be executed.
3413  *
3414  * This function is used to decide whether or not to allow end-of-renderpass
3415  * atom completion. It only returns false if the atom at the start of the
3416  * renderpass was soft-stopped because it used too much memory during the most
3417  * recent attempt at tiling.
3418  *
3419  * Return: True if the atom completed for the last time.
3420  */
3421 static bool js_end_rp_is_complete(struct kbase_jd_atom *const end_katom)
3422 {
3423 	struct kbase_context *const kctx = end_katom->kctx;
3424 	struct kbase_device *const kbdev = kctx->kbdev;
3425 	struct kbase_jd_renderpass *rp;
3426 
3427 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
3428 
3429 	if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
3430 		return true;
3431 
3432 	compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
3433 			ARRAY_SIZE(kctx->jctx.renderpasses),
3434 			"Should check invalid access to renderpasses");
3435 
3436 	rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
3437 
3438 	if (WARN_ON(rp->end_katom != end_katom))
3439 		return true;
3440 
3441 	dev_dbg(kbdev->dev,
3442 		"JS complete end atom %pK in state %d of RP %d\n",
3443 		(void *)end_katom, (int)rp->state,
3444 		end_katom->renderpass_id);
3445 
3446 	if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
3447 		return true;
3448 
3449 	/* Failure of end-of-renderpass atoms must not return to the
3450 	 * start of the renderpass.
3451 	 */
3452 	if (end_katom->event_code != BASE_JD_EVENT_DONE)
3453 		return true;
3454 
3455 	if (rp->state != KBASE_JD_RP_OOM &&
3456 		rp->state != KBASE_JD_RP_RETRY_OOM)
3457 		return true;
3458 
3459 	dev_dbg(kbdev->dev, "Suppressing end atom completion\n");
3460 	return false;
3461 }
3462 
3463 struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom,
3464 		ktime_t *end_timestamp)
3465 {
3466 	struct kbase_device *kbdev;
3467 	struct kbase_context *kctx = katom->kctx;
3468 	struct kbase_jd_atom *x_dep = katom->x_post_dep;
3469 
3470 	kbdev = kctx->kbdev;
3471 	dev_dbg(kbdev->dev, "Atom %pK complete in kctx %pK (post-dep %pK)\n",
3472 		(void *)katom, (void *)kctx, (void *)x_dep);
3473 
3474 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
3475 
3476 	if ((katom->core_req & BASE_JD_REQ_END_RENDERPASS) &&
3477 		!js_end_rp_is_complete(katom)) {
3478 		katom->event_code = BASE_JD_EVENT_END_RP_DONE;
3479 		kbase_js_unpull(kctx, katom);
3480 		return NULL;
3481 	}
3482 
3483 	if (katom->will_fail_event_code)
3484 		katom->event_code = katom->will_fail_event_code;
3485 
3486 	katom->status = KBASE_JD_ATOM_STATE_HW_COMPLETED;
3487 	dev_dbg(kbdev->dev, "Atom %pK status to HW completed\n", (void *)katom);
3488 
3489 	if (katom->event_code != BASE_JD_EVENT_DONE) {
3490 		kbase_js_evict_deps(kctx, katom, katom->slot_nr,
3491 				katom->sched_priority);
3492 	}
3493 
3494 	KBASE_TLSTREAM_AUX_EVENT_JOB_SLOT(kbdev, NULL,
3495 		katom->slot_nr, 0, TL_JS_EVENT_STOP);
3496 
3497 	trace_sysgraph_gpu(SGR_COMPLETE, kctx->id,
3498 			kbase_jd_atom_id(katom->kctx, katom), katom->slot_nr);
3499 
3500 	KBASE_TLSTREAM_TL_JD_DONE_START(kbdev, katom);
3501 	kbase_jd_done(katom, katom->slot_nr, end_timestamp, 0);
3502 	KBASE_TLSTREAM_TL_JD_DONE_END(kbdev, katom);
3503 
3504 	/* Unblock cross dependency if present */
3505 	if (x_dep && (katom->event_code == BASE_JD_EVENT_DONE ||
3506 		!(x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER)) &&
3507 		(x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST)) {
3508 		bool was_pullable = kbase_js_ctx_pullable(kctx, x_dep->slot_nr,
3509 				false);
3510 		x_dep->atom_flags &= ~KBASE_KATOM_FLAG_X_DEP_BLOCKED;
3511 		dev_dbg(kbdev->dev, "Cleared X_DEP flag on atom %pK\n",
3512 			(void *)x_dep);
3513 
3514 		kbase_js_move_to_tree(x_dep);
3515 
3516 		if (!was_pullable && kbase_js_ctx_pullable(kctx, x_dep->slot_nr,
3517 				false))
3518 			kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx,
3519 					x_dep->slot_nr);
3520 
3521 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE) {
3522 			dev_dbg(kbdev->dev, "Atom %pK is in runnable tree\n",
3523 				(void *)x_dep);
3524 			return x_dep;
3525 		}
3526 	} else {
3527 		dev_dbg(kbdev->dev,
3528 			"No cross-slot dep to unblock for atom %pK\n",
3529 			(void *)katom);
3530 	}
3531 
3532 	return NULL;
3533 }
3534 
3535 /**
3536  * kbase_js_atom_blocked_on_x_dep - Decide whether to ignore a cross-slot
3537  *                                  dependency
3538  * @katom:	Pointer to an atom in the slot ringbuffer
3539  *
3540  * A cross-slot dependency is ignored if necessary to unblock incremental
3541  * rendering. If the atom at the start of a renderpass used too much memory
3542  * and was soft-stopped then the atom at the end of a renderpass is submitted
3543  * to hardware regardless of its dependency on the start-of-renderpass atom.
3544  * This can happen multiple times for the same pair of atoms.
3545  *
3546  * Return: true to block the atom or false to allow it to be submitted to
3547  *         hardware
3548  */
3549 bool kbase_js_atom_blocked_on_x_dep(struct kbase_jd_atom *const katom)
3550 {
3551 	struct kbase_context *const kctx = katom->kctx;
3552 	struct kbase_device *kbdev = kctx->kbdev;
3553 	struct kbase_jd_renderpass *rp;
3554 
3555 	lockdep_assert_held(&kbdev->hwaccess_lock);
3556 
3557 	if (!(katom->atom_flags &
3558 			KBASE_KATOM_FLAG_X_DEP_BLOCKED)) {
3559 		dev_dbg(kbdev->dev, "Atom %pK is not blocked on a cross-slot dependency",
3560 			(void *)katom);
3561 		return false;
3562 	}
3563 
3564 	if (!(katom->core_req & BASE_JD_REQ_END_RENDERPASS)) {
3565 		dev_dbg(kbdev->dev, "Atom %pK is blocked on a cross-slot dependency",
3566 			(void *)katom);
3567 		return true;
3568 	}
3569 
3570 	compiletime_assert((1ull << (sizeof(katom->renderpass_id) * 8)) <=
3571 			ARRAY_SIZE(kctx->jctx.renderpasses),
3572 			"Should check invalid access to renderpasses");
3573 
3574 	rp = &kctx->jctx.renderpasses[katom->renderpass_id];
3575 	/* We can read a subset of renderpass state without holding
3576 	 * higher-level locks (but not end_katom, for example).
3577 	 */
3578 
3579 	WARN_ON(rp->state == KBASE_JD_RP_COMPLETE);
3580 
3581 	dev_dbg(kbdev->dev, "End atom has cross-slot dep in state %d\n",
3582 		(int)rp->state);
3583 
3584 	if (rp->state != KBASE_JD_RP_OOM && rp->state != KBASE_JD_RP_RETRY_OOM)
3585 		return true;
3586 
3587 	/* Tiler ran out of memory so allow the fragment job chain to run
3588 	 * if it only depends on the tiler job chain.
3589 	 */
3590 	if (katom->x_pre_dep != rp->start_katom) {
3591 		dev_dbg(kbdev->dev, "Dependency is on %pK not start atom %pK\n",
3592 			(void *)katom->x_pre_dep, (void *)rp->start_katom);
3593 		return true;
3594 	}
3595 
3596 	dev_dbg(kbdev->dev, "Ignoring cross-slot dep on atom %pK\n",
3597 		(void *)katom->x_pre_dep);
3598 
3599 	return false;
3600 }
3601 
3602 void kbase_js_sched(struct kbase_device *kbdev, int js_mask)
3603 {
3604 	struct kbasep_js_device_data *js_devdata;
3605 	struct kbase_context *last_active[BASE_JM_MAX_NR_SLOTS];
3606 	bool timer_sync = false;
3607 	bool ctx_waiting[BASE_JM_MAX_NR_SLOTS];
3608 	int js;
3609 
3610 	KBASE_TLSTREAM_TL_JS_SCHED_START(kbdev, 0);
3611 
3612 	dev_dbg(kbdev->dev, "%s kbdev %pK mask 0x%x\n",
3613 		__func__, (void *)kbdev, (unsigned int)js_mask);
3614 
3615 	js_devdata = &kbdev->js_data;
3616 
3617 	down(&js_devdata->schedule_sem);
3618 	mutex_lock(&js_devdata->queue_mutex);
3619 
3620 	for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
3621 		last_active[js] = kbdev->hwaccess.active_kctx[js];
3622 		ctx_waiting[js] = false;
3623 	}
3624 
3625 	while (js_mask) {
3626 		js = ffs(js_mask) - 1;
3627 
3628 		while (1) {
3629 			struct kbase_context *kctx;
3630 			unsigned long flags;
3631 			bool context_idle = false;
3632 
3633 			kctx = kbase_js_ctx_list_pop_head(kbdev, js);
3634 
3635 			if (!kctx) {
3636 				js_mask &= ~(1 << js);
3637 				dev_dbg(kbdev->dev,
3638 					"No kctx on pullable list (s:%d)\n",
3639 					js);
3640 				break;
3641 			}
3642 
3643 			if (!kbase_ctx_flag(kctx, KCTX_ACTIVE)) {
3644 				context_idle = true;
3645 
3646 				dev_dbg(kbdev->dev,
3647 					"kctx %pK is not active (s:%d)\n",
3648 					(void *)kctx, js);
3649 
3650 				if (kbase_pm_context_active_handle_suspend(
3651 									kbdev,
3652 				      KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
3653 					dev_dbg(kbdev->dev,
3654 						"Suspend pending (s:%d)\n", js);
3655 					/* Suspend pending - return context to
3656 					 * queue and stop scheduling
3657 					 */
3658 					mutex_lock(
3659 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
3660 					if (kbase_js_ctx_list_add_pullable_head(
3661 						kctx->kbdev, kctx, js))
3662 						kbase_js_sync_timers(kbdev);
3663 					mutex_unlock(
3664 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
3665 					mutex_unlock(&js_devdata->queue_mutex);
3666 					up(&js_devdata->schedule_sem);
3667 					KBASE_TLSTREAM_TL_JS_SCHED_END(kbdev,
3668 									  0);
3669 					return;
3670 				}
3671 				kbase_ctx_flag_set(kctx, KCTX_ACTIVE);
3672 			}
3673 
3674 			if (!kbase_js_use_ctx(kbdev, kctx, js)) {
3675 				mutex_lock(
3676 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
3677 
3678 				dev_dbg(kbdev->dev,
3679 					"kctx %pK cannot be used at this time\n",
3680 					kctx);
3681 
3682 				spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3683 				if (kbase_js_ctx_pullable(kctx, js, false)
3684 				    || kbase_ctx_flag(kctx, KCTX_PRIVILEGED))
3685 					timer_sync |=
3686 					kbase_js_ctx_list_add_pullable_head_nolock(
3687 							kctx->kbdev, kctx, js);
3688 				else
3689 					timer_sync |=
3690 					kbase_js_ctx_list_add_unpullable_nolock(
3691 							kctx->kbdev, kctx, js);
3692 				spin_unlock_irqrestore(&kbdev->hwaccess_lock,
3693 						flags);
3694 				mutex_unlock(
3695 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
3696 				if (context_idle) {
3697 					WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
3698 					kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
3699 					kbase_pm_context_idle(kbdev);
3700 				}
3701 
3702 				/* No more jobs can be submitted on this slot */
3703 				js_mask &= ~(1 << js);
3704 				break;
3705 			}
3706 			mutex_lock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
3707 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3708 
3709 			kbase_ctx_flag_clear(kctx, KCTX_PULLED);
3710 
3711 			if (!kbase_jm_kick(kbdev, 1 << js)) {
3712 				dev_dbg(kbdev->dev,
3713 					"No more jobs can be submitted (s:%d)\n",
3714 					js);
3715 				js_mask &= ~(1 << js);
3716 			}
3717 			if (!kbase_ctx_flag(kctx, KCTX_PULLED)) {
3718 				bool pullable;
3719 
3720 				dev_dbg(kbdev->dev,
3721 					"No atoms pulled from kctx %pK (s:%d)\n",
3722 					(void *)kctx, js);
3723 
3724 				pullable = kbase_js_ctx_pullable(kctx, js,
3725 						true);
3726 
3727 				/* Failed to pull jobs - push to head of list.
3728 				 * Unless this context is already 'active', in
3729 				 * which case it's effectively already scheduled
3730 				 * so push it to the back of the list.
3731 				 */
3732 				if (pullable && kctx == last_active[js] &&
3733 						kbase_ctx_flag(kctx,
3734 						(KCTX_PULLED_SINCE_ACTIVE_JS0 <<
3735 						js)))
3736 					timer_sync |=
3737 					kbase_js_ctx_list_add_pullable_nolock(
3738 							kctx->kbdev,
3739 							kctx, js);
3740 				else if (pullable)
3741 					timer_sync |=
3742 					kbase_js_ctx_list_add_pullable_head_nolock(
3743 							kctx->kbdev,
3744 							kctx, js);
3745 				else
3746 					timer_sync |=
3747 					kbase_js_ctx_list_add_unpullable_nolock(
3748 								kctx->kbdev,
3749 								kctx, js);
3750 
3751 				/* If this context is not the active context,
3752 				 * but the active context is pullable on this
3753 				 * slot, then we need to remove the active
3754 				 * marker to prevent it from submitting atoms in
3755 				 * the IRQ handler, which would prevent this
3756 				 * context from making progress.
3757 				 */
3758 				if (last_active[js] && kctx != last_active[js]
3759 						&& kbase_js_ctx_pullable(
3760 						last_active[js], js, true))
3761 					ctx_waiting[js] = true;
3762 
3763 				if (context_idle) {
3764 					kbase_jm_idle_ctx(kbdev, kctx);
3765 					spin_unlock_irqrestore(
3766 							&kbdev->hwaccess_lock,
3767 							flags);
3768 					WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
3769 					kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
3770 					kbase_pm_context_idle(kbdev);
3771 				} else {
3772 					spin_unlock_irqrestore(
3773 							&kbdev->hwaccess_lock,
3774 							flags);
3775 				}
3776 				mutex_unlock(
3777 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
3778 
3779 				js_mask &= ~(1 << js);
3780 				break; /* Could not run atoms on this slot */
3781 			}
3782 
3783 			dev_dbg(kbdev->dev, "Push kctx %pK to back of list\n",
3784 				(void *)kctx);
3785 			if (kbase_js_ctx_pullable(kctx, js, true))
3786 				timer_sync |=
3787 					kbase_js_ctx_list_add_pullable_nolock(
3788 							kctx->kbdev, kctx, js);
3789 			else
3790 				timer_sync |=
3791 					kbase_js_ctx_list_add_unpullable_nolock(
3792 							kctx->kbdev, kctx, js);
3793 
3794 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3795 			mutex_unlock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
3796 		}
3797 	}
3798 
3799 	if (timer_sync)
3800 		kbase_js_sync_timers(kbdev);
3801 
3802 	for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
3803 		if (kbdev->hwaccess.active_kctx[js] == last_active[js] &&
3804 				ctx_waiting[js]) {
3805 			dev_dbg(kbdev->dev, "Marking kctx %pK as inactive (s:%d)\n",
3806 					(void *)last_active[js], js);
3807 			kbdev->hwaccess.active_kctx[js] = NULL;
3808 		}
3809 	}
3810 
3811 	mutex_unlock(&js_devdata->queue_mutex);
3812 	up(&js_devdata->schedule_sem);
3813 	KBASE_TLSTREAM_TL_JS_SCHED_END(kbdev, 0);
3814 }
3815 
3816 void kbase_js_zap_context(struct kbase_context *kctx)
3817 {
3818 	struct kbase_device *kbdev = kctx->kbdev;
3819 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
3820 	struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
3821 
3822 	/*
3823 	 * Critical assumption: No more submission is possible outside of the
3824 	 * workqueue. This is because the OS *must* prevent U/K calls (IOCTLs)
3825 	 * whilst the struct kbase_context is terminating.
3826 	 */
3827 
3828 	/* First, atomically do the following:
3829 	 * - mark the context as dying
3830 	 * - try to evict it from the queue
3831 	 */
3832 	mutex_lock(&kctx->jctx.lock);
3833 	mutex_lock(&js_devdata->queue_mutex);
3834 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
3835 	kbase_ctx_flag_set(kctx, KCTX_DYING);
3836 
3837 	dev_dbg(kbdev->dev, "Zap: Try Evict Ctx %pK", kctx);
3838 
3839 	/*
3840 	 * At this point we know:
3841 	 * - If eviction succeeded, it was in the queue, but now no
3842 	 *   longer is
3843 	 *  - We must cancel the jobs here. No Power Manager active reference to
3844 	 *    release.
3845 	 *  - This happens asynchronously - kbase_jd_zap_context() will wait for
3846 	 *    those jobs to be killed.
3847 	 * - If eviction failed, then it wasn't in the queue. It is one
3848 	 *   of the following:
3849 	 *  - a. it didn't have any jobs, and so is not in the Queue or
3850 	 *       the Run Pool (not scheduled)
3851 	 *   - Hence, no more work required to cancel jobs. No Power Manager
3852 	 *     active reference to release.
3853 	 *  - b. it was in the middle of a scheduling transaction (and thus must
3854 	 *       have at least 1 job). This can happen from a syscall or a
3855 	 *       kernel thread. We still hold the jsctx_mutex, and so the thread
3856 	 *       must be waiting inside kbasep_js_try_schedule_head_ctx(),
3857 	 *       before checking whether the runpool is full. That thread will
3858 	 *       continue after we drop the mutex, and will notice the context
3859 	 *       is dying. It will rollback the transaction, killing all jobs at
3860 	 *       the same time. kbase_jd_zap_context() will wait for those jobs
3861 	 *       to be killed.
3862 	 *   - Hence, no more work required to cancel jobs, or to release the
3863 	 *     Power Manager active reference.
3864 	 *  - c. it is scheduled, and may or may not be running jobs
3865 	 * - We must cause it to leave the runpool by stopping it from
3866 	 * submitting any more jobs. When it finally does leave,
3867 	 * kbasep_js_runpool_requeue_or_kill_ctx() will kill all remaining jobs
3868 	 * (because it is dying), release the Power Manager active reference,
3869 	 * and will not requeue the context in the queue.
3870 	 * kbase_jd_zap_context() will wait for those jobs to be killed.
3871 	 *  - Hence, work required just to make it leave the runpool. Cancelling
3872 	 *    jobs and releasing the Power manager active reference will be
3873 	 *    handled when it leaves the runpool.
3874 	 */
3875 	if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED)) {
3876 		unsigned long flags;
3877 		int js;
3878 
3879 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3880 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
3881 			if (!list_empty(
3882 				&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
3883 				list_del_init(
3884 				&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
3885 		}
3886 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3887 
3888 		/* The following events require us to kill off remaining jobs
3889 		 * and update PM book-keeping:
3890 		 * - we evicted it correctly (it must have jobs to be in the
3891 		 *   Queue)
3892 		 *
3893 		 * These events need no action, but take this path anyway:
3894 		 * - Case a: it didn't have any jobs, and was never in the Queue
3895 		 * - Case b: scheduling transaction will be partially rolled-
3896 		 *           back (this already cancels the jobs)
3897 		 */
3898 
3899 		KBASE_KTRACE_ADD_JM(kbdev, JM_ZAP_NON_SCHEDULED, kctx, NULL, 0u, kbase_ctx_flag(kctx, KCTX_SCHEDULED));
3900 
3901 		dev_dbg(kbdev->dev, "Zap: Ctx %pK scheduled=0", kctx);
3902 
3903 		/* Only cancel jobs when we evicted from the
3904 		 * queue. No Power Manager active reference was held.
3905 		 *
3906 		 * Having is_dying set ensures that this kills, and doesn't
3907 		 * requeue
3908 		 */
3909 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, false);
3910 
3911 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
3912 		mutex_unlock(&js_devdata->queue_mutex);
3913 		mutex_unlock(&kctx->jctx.lock);
3914 	} else {
3915 		unsigned long flags;
3916 		bool was_retained;
3917 
3918 		/* Case c: didn't evict, but it is scheduled - it's in the Run
3919 		 * Pool
3920 		 */
3921 		KBASE_KTRACE_ADD_JM(kbdev, JM_ZAP_SCHEDULED, kctx, NULL, 0u, kbase_ctx_flag(kctx, KCTX_SCHEDULED));
3922 		dev_dbg(kbdev->dev, "Zap: Ctx %pK is in RunPool", kctx);
3923 
3924 		/* Disable the ctx from submitting any more jobs */
3925 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
3926 
3927 		kbasep_js_clear_submit_allowed(js_devdata, kctx);
3928 
3929 		/* Retain and (later) release the context whilst it is is now
3930 		 * disallowed from submitting jobs - ensures that someone
3931 		 * somewhere will be removing the context later on
3932 		 */
3933 		was_retained = kbase_ctx_sched_inc_refcount_nolock(kctx);
3934 
3935 		/* Since it's scheduled and we have the jsctx_mutex, it must be
3936 		 * retained successfully
3937 		 */
3938 		KBASE_DEBUG_ASSERT(was_retained);
3939 
3940 		dev_dbg(kbdev->dev, "Zap: Ctx %pK Kill Any Running jobs", kctx);
3941 
3942 		/* Cancel any remaining running jobs for this kctx - if any.
3943 		 * Submit is disallowed which takes effect immediately, so no
3944 		 * more new jobs will appear after we do this.
3945 		 */
3946 		kbase_backend_jm_kill_running_jobs_from_kctx(kctx);
3947 
3948 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
3949 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
3950 		mutex_unlock(&js_devdata->queue_mutex);
3951 		mutex_unlock(&kctx->jctx.lock);
3952 
3953 		dev_dbg(kbdev->dev, "Zap: Ctx %pK Release (may or may not schedule out immediately)",
3954 									kctx);
3955 
3956 		kbasep_js_runpool_release_ctx(kbdev, kctx);
3957 	}
3958 
3959 	KBASE_KTRACE_ADD_JM(kbdev, JM_ZAP_DONE, kctx, NULL, 0u, 0u);
3960 
3961 	/* After this, you must wait on both the
3962 	 * kbase_jd_context::zero_jobs_wait and the
3963 	 * kbasep_js_kctx_info::ctx::is_scheduled_waitq - to wait for the jobs
3964 	 * to be destroyed, and the context to be de-scheduled (if it was on the
3965 	 * runpool).
3966 	 *
3967 	 * kbase_jd_zap_context() will do this.
3968 	 */
3969 }
3970 
3971 static inline int trace_get_refcnt(struct kbase_device *kbdev,
3972 					struct kbase_context *kctx)
3973 {
3974 	return atomic_read(&kctx->refcount);
3975 }
3976 
3977 /**
3978  * kbase_js_foreach_ctx_job(): - Call a function on all jobs in context
3979  * @kctx:     Pointer to context.
3980  * @callback: Pointer to function to call for each job.
3981  *
3982  * Call a function on all jobs belonging to a non-queued, non-running
3983  * context, and detach the jobs from the context as it goes.
3984  *
3985  * Due to the locks that might be held at the time of the call, the callback
3986  * may need to defer work on a workqueue to complete its actions (e.g. when
3987  * cancelling jobs)
3988  *
3989  * Atoms will be removed from the queue, so this must only be called when
3990  * cancelling jobs (which occurs as part of context destruction).
3991  *
3992  * The locking conditions on the caller are as follows:
3993  * - it will be holding kbasep_js_kctx_info::ctx::jsctx_mutex.
3994  */
3995 static void kbase_js_foreach_ctx_job(struct kbase_context *kctx,
3996 				     kbasep_js_ctx_job_cb *callback)
3997 {
3998 	struct kbase_device *kbdev;
3999 	unsigned long flags;
4000 	u32 js;
4001 
4002 	kbdev = kctx->kbdev;
4003 
4004 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
4005 
4006 	KBASE_KTRACE_ADD_JM_REFCOUNT(kbdev, JS_POLICY_FOREACH_CTX_JOBS, kctx, NULL,
4007 					0u, trace_get_refcnt(kbdev, kctx));
4008 
4009 	/* Invoke callback on jobs on each slot in turn */
4010 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++)
4011 		jsctx_queue_foreach(kctx, js, callback);
4012 
4013 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
4014 }
4015 
4016 base_jd_prio kbase_js_priority_check(struct kbase_device *kbdev, base_jd_prio priority)
4017 {
4018 	struct priority_control_manager_device *pcm_device = kbdev->pcm_dev;
4019 	int req_priority, out_priority;
4020 	base_jd_prio out_jd_priority = priority;
4021 
4022 	if (pcm_device)	{
4023 		req_priority = kbasep_js_atom_prio_to_sched_prio(priority);
4024 		out_priority = pcm_device->ops.pcm_scheduler_priority_check(pcm_device, current, req_priority);
4025 		out_jd_priority = kbasep_js_sched_prio_to_atom_prio(out_priority);
4026 	}
4027 	return out_jd_priority;
4028 }
4029 
4030