1 /*
2  *
3  * (C) COPYRIGHT 2011-2017 ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * A copy of the licence is included with the program, and can also be obtained
11  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12  * Boston, MA  02110-1301, USA.
13  *
14  */
15 
16 /* #define ENABLE_DEBUG_LOG */
17 #include "./platform/rk/custom_log.h"
18 
19 /*
20  * Job Scheduler Implementation
21  */
22 #include <mali_kbase.h>
23 #include <mali_kbase_js.h>
24 #if defined(CONFIG_MALI_GATOR_SUPPORT)
25 #include <mali_kbase_gator.h>
26 #endif
27 #include <mali_kbase_tlstream.h>
28 #include <mali_kbase_hw.h>
29 #include <mali_kbase_ctx_sched.h>
30 
31 #include <mali_kbase_defs.h>
32 #include <mali_kbase_config_defaults.h>
33 
34 #include "mali_kbase_jm.h"
35 #include "mali_kbase_hwaccess_jm.h"
36 
37 /*
38  * Private types
39  */
40 
41 /* Bitpattern indicating the result of releasing a context */
42 enum {
43 	/* The context was descheduled - caller should try scheduling in a new
44 	 * one to keep the runpool full */
45 	KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED = (1u << 0),
46 	/* Ctx attributes were changed - caller should try scheduling all
47 	 * contexts */
48 	KBASEP_JS_RELEASE_RESULT_SCHED_ALL = (1u << 1)
49 };
50 
51 typedef u32 kbasep_js_release_result;
52 
53 const int kbasep_js_atom_priority_to_relative[BASE_JD_NR_PRIO_LEVELS] = {
54 	KBASE_JS_ATOM_SCHED_PRIO_MED, /* BASE_JD_PRIO_MEDIUM */
55 	KBASE_JS_ATOM_SCHED_PRIO_HIGH, /* BASE_JD_PRIO_HIGH */
56 	KBASE_JS_ATOM_SCHED_PRIO_LOW  /* BASE_JD_PRIO_LOW */
57 };
58 
59 const base_jd_prio
60 kbasep_js_relative_priority_to_atom[KBASE_JS_ATOM_SCHED_PRIO_COUNT] = {
61 	BASE_JD_PRIO_HIGH,   /* KBASE_JS_ATOM_SCHED_PRIO_HIGH */
62 	BASE_JD_PRIO_MEDIUM, /* KBASE_JS_ATOM_SCHED_PRIO_MED */
63 	BASE_JD_PRIO_LOW     /* KBASE_JS_ATOM_SCHED_PRIO_LOW */
64 };
65 
66 
67 /*
68  * Private function prototypes
69  */
70 static kbasep_js_release_result kbasep_js_runpool_release_ctx_internal(
71 		struct kbase_device *kbdev, struct kbase_context *kctx,
72 		struct kbasep_js_atom_retained_state *katom_retained_state);
73 
74 static int kbase_js_get_slot(struct kbase_device *kbdev,
75 				struct kbase_jd_atom *katom);
76 
77 static void kbase_js_foreach_ctx_job(struct kbase_context *kctx,
78 		kbasep_js_ctx_job_cb callback);
79 
80 /* Helper for trace subcodes */
81 #if KBASE_TRACE_ENABLE
kbasep_js_trace_get_refcnt(struct kbase_device *kbdev, struct kbase_context *kctx)82 static int kbasep_js_trace_get_refcnt(struct kbase_device *kbdev,
83 		struct kbase_context *kctx)
84 {
85 	return atomic_read(&kctx->refcount);
86 }
87 #else				/* KBASE_TRACE_ENABLE  */
kbasep_js_trace_get_refcnt(struct kbase_device *kbdev, struct kbase_context *kctx)88 static int kbasep_js_trace_get_refcnt(struct kbase_device *kbdev,
89 		struct kbase_context *kctx)
90 {
91 	CSTD_UNUSED(kbdev);
92 	CSTD_UNUSED(kctx);
93 	return 0;
94 }
95 #endif				/* KBASE_TRACE_ENABLE  */
96 
97 /*
98  * Private functions
99  */
100 
101 /**
102  * core_reqs_from_jsn_features - Convert JSn_FEATURES to core requirements
103  * @features: JSn_FEATURE register value
104  *
105  * Given a JSn_FEATURE register value returns the core requirements that match
106  *
107  * Return: Core requirement bit mask
108  */
core_reqs_from_jsn_features(u16 features)109 static base_jd_core_req core_reqs_from_jsn_features(u16 features)
110 {
111 	base_jd_core_req core_req = 0u;
112 
113 	if ((features & JS_FEATURE_SET_VALUE_JOB) != 0)
114 		core_req |= BASE_JD_REQ_V;
115 
116 	if ((features & JS_FEATURE_CACHE_FLUSH_JOB) != 0)
117 		core_req |= BASE_JD_REQ_CF;
118 
119 	if ((features & JS_FEATURE_COMPUTE_JOB) != 0)
120 		core_req |= BASE_JD_REQ_CS;
121 
122 	if ((features & JS_FEATURE_TILER_JOB) != 0)
123 		core_req |= BASE_JD_REQ_T;
124 
125 	if ((features & JS_FEATURE_FRAGMENT_JOB) != 0)
126 		core_req |= BASE_JD_REQ_FS;
127 
128 	return core_req;
129 }
130 
kbase_js_sync_timers(struct kbase_device *kbdev)131 static void kbase_js_sync_timers(struct kbase_device *kbdev)
132 {
133 	mutex_lock(&kbdev->js_data.runpool_mutex);
134 	kbase_backend_ctx_count_changed(kbdev);
135 	mutex_unlock(&kbdev->js_data.runpool_mutex);
136 }
137 
138 /* Hold the mmu_hw_mutex and hwaccess_lock for this */
kbasep_js_runpool_retain_ctx_nolock(struct kbase_device *kbdev, struct kbase_context *kctx)139 bool kbasep_js_runpool_retain_ctx_nolock(struct kbase_device *kbdev,
140 		struct kbase_context *kctx)
141 {
142 	struct kbasep_js_device_data *js_devdata;
143 	bool result = false;
144 	int as_nr;
145 
146 	KBASE_DEBUG_ASSERT(kbdev != NULL);
147 	KBASE_DEBUG_ASSERT(kctx != NULL);
148 	js_devdata = &kbdev->js_data;
149 
150 	lockdep_assert_held(&kbdev->hwaccess_lock);
151 
152 	as_nr = kctx->as_nr;
153 	if (atomic_read(&kctx->refcount) > 0) {
154 		KBASE_DEBUG_ASSERT(as_nr >= 0);
155 
156 		kbase_ctx_sched_retain_ctx_refcount(kctx);
157 		KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_RETAIN_CTX_NOLOCK, kctx,
158 				NULL, 0u, atomic_read(&kctx->refcount));
159 		result = true;
160 	}
161 
162 	return result;
163 }
164 
165 /**
166  * jsctx_rb_none_to_pull_prio(): - Check if there are no pullable atoms
167  * @kctx: Pointer to kbase context with ring buffer.
168  * @js:   Job slot id to check.
169  * @prio: Priority to check.
170  *
171  * Return true if there are no atoms to pull. There may be running atoms in the
172  * ring buffer even if there are no atoms to pull. It is also possible for the
173  * ring buffer to be full (with running atoms) when this functions returns
174  * true.
175  *
176  * Return: true if there are no atoms to pull, false otherwise.
177  */
178 static inline bool
jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, int js, int prio)179 jsctx_rb_none_to_pull_prio(struct kbase_context *kctx, int js, int prio)
180 {
181 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
182 
183 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
184 
185 	return RB_EMPTY_ROOT(&rb->runnable_tree);
186 }
187 
188 /**
189  * jsctx_rb_none_to_pull(): - Check if all priority ring buffers have no
190  * pullable atoms
191  * @kctx: Pointer to kbase context with ring buffer.
192  * @js:   Job slot id to check.
193  *
194  * Caller must hold hwaccess_lock
195  *
196  * Return: true if the ring buffers for all priorities have no pullable atoms,
197  *	   false otherwise.
198  */
199 static inline bool
jsctx_rb_none_to_pull(struct kbase_context *kctx, int js)200 jsctx_rb_none_to_pull(struct kbase_context *kctx, int js)
201 {
202 	int prio;
203 
204 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
205 
206 	for (prio = 0; prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
207 		if (!jsctx_rb_none_to_pull_prio(kctx, js, prio))
208 			return false;
209 	}
210 
211 	return true;
212 }
213 
214 /**
215  * jsctx_queue_foreach_prio(): - Execute callback for each entry in the queue.
216  * @kctx:     Pointer to kbase context with the queue.
217  * @js:       Job slot id to iterate.
218  * @prio:     Priority id to iterate.
219  * @callback: Function pointer to callback.
220  *
221  * Iterate over a queue and invoke @callback for each entry in the queue, and
222  * remove the entry from the queue.
223  *
224  * If entries are added to the queue while this is running those entries may, or
225  * may not be covered. To ensure that all entries in the buffer have been
226  * enumerated when this function returns jsctx->lock must be held when calling
227  * this function.
228  *
229  * The HW access lock must always be held when calling this function.
230  */
231 static void
jsctx_queue_foreach_prio(struct kbase_context *kctx, int js, int prio, kbasep_js_ctx_job_cb callback)232 jsctx_queue_foreach_prio(struct kbase_context *kctx, int js, int prio,
233 		kbasep_js_ctx_job_cb callback)
234 {
235 	struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
236 
237 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
238 
239 	while (!RB_EMPTY_ROOT(&queue->runnable_tree)) {
240 		struct rb_node *node = rb_first(&queue->runnable_tree);
241 		struct kbase_jd_atom *entry = rb_entry(node,
242 				struct kbase_jd_atom, runnable_tree_node);
243 
244 		rb_erase(node, &queue->runnable_tree);
245 		callback(kctx->kbdev, entry);
246 	}
247 
248 	while (!list_empty(&queue->x_dep_head)) {
249 		struct kbase_jd_atom *entry = list_entry(queue->x_dep_head.next,
250 				struct kbase_jd_atom, queue);
251 
252 		list_del(queue->x_dep_head.next);
253 
254 		callback(kctx->kbdev, entry);
255 	}
256 }
257 
258 /**
259  * jsctx_queue_foreach(): - Execute callback for each entry in every queue
260  * @kctx:     Pointer to kbase context with queue.
261  * @js:       Job slot id to iterate.
262  * @callback: Function pointer to callback.
263  *
264  * Iterate over all the different priorities, and for each call
265  * jsctx_queue_foreach_prio() to iterate over the queue and invoke @callback
266  * for each entry, and remove the entry from the queue.
267  */
268 static inline void
jsctx_queue_foreach(struct kbase_context *kctx, int js, kbasep_js_ctx_job_cb callback)269 jsctx_queue_foreach(struct kbase_context *kctx, int js,
270 		kbasep_js_ctx_job_cb callback)
271 {
272 	int prio;
273 
274 	for (prio = 0; prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++)
275 		jsctx_queue_foreach_prio(kctx, js, prio, callback);
276 }
277 
278 /**
279  * jsctx_rb_peek_prio(): - Check buffer and get next atom
280  * @kctx: Pointer to kbase context with ring buffer.
281  * @js:   Job slot id to check.
282  * @prio: Priority id to check.
283  *
284  * Check the ring buffer for the specified @js and @prio and return a pointer to
285  * the next atom, unless the ring buffer is empty.
286  *
287  * Return: Pointer to next atom in buffer, or NULL if there is no atom.
288  */
289 static inline struct kbase_jd_atom *
jsctx_rb_peek_prio(struct kbase_context *kctx, int js, int prio)290 jsctx_rb_peek_prio(struct kbase_context *kctx, int js, int prio)
291 {
292 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
293 	struct rb_node *node;
294 
295 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
296 
297 	node = rb_first(&rb->runnable_tree);
298 	if (!node)
299 		return NULL;
300 
301 	return rb_entry(node, struct kbase_jd_atom, runnable_tree_node);
302 }
303 
304 /**
305  * jsctx_rb_peek(): - Check all priority buffers and get next atom
306  * @kctx: Pointer to kbase context with ring buffer.
307  * @js:   Job slot id to check.
308  *
309  * Check the ring buffers for all priorities, starting from
310  * KBASE_JS_ATOM_SCHED_PRIO_HIGH, for the specified @js and @prio and return a
311  * pointer to the next atom, unless all the priority's ring buffers are empty.
312  *
313  * Caller must hold the hwaccess_lock.
314  *
315  * Return: Pointer to next atom in buffer, or NULL if there is no atom.
316  */
317 static inline struct kbase_jd_atom *
jsctx_rb_peek(struct kbase_context *kctx, int js)318 jsctx_rb_peek(struct kbase_context *kctx, int js)
319 {
320 	int prio;
321 
322 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
323 
324 	for (prio = 0; prio < KBASE_JS_ATOM_SCHED_PRIO_COUNT; prio++) {
325 		struct kbase_jd_atom *katom;
326 
327 		katom = jsctx_rb_peek_prio(kctx, js, prio);
328 		if (katom)
329 			return katom;
330 	}
331 
332 	return NULL;
333 }
334 
335 /**
336  * jsctx_rb_pull(): - Mark atom in list as running
337  * @kctx:  Pointer to kbase context with ring buffer.
338  * @katom: Pointer to katom to pull.
339  *
340  * Mark an atom previously obtained from jsctx_rb_peek() as running.
341  *
342  * @katom must currently be at the head of the ring buffer.
343  */
344 static inline void
jsctx_rb_pull(struct kbase_context *kctx, struct kbase_jd_atom *katom)345 jsctx_rb_pull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
346 {
347 	int prio = katom->sched_priority;
348 	int js = katom->slot_nr;
349 	struct jsctx_queue *rb = &kctx->jsctx_queue[prio][js];
350 
351 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
352 
353 	/* Atoms must be pulled in the correct order. */
354 	WARN_ON(katom != jsctx_rb_peek_prio(kctx, js, prio));
355 
356 	rb_erase(&katom->runnable_tree_node, &rb->runnable_tree);
357 }
358 
359 #define LESS_THAN_WRAP(a, b) ((s32)(a - b) < 0)
360 
361 static void
jsctx_tree_add(struct kbase_context *kctx, struct kbase_jd_atom *katom)362 jsctx_tree_add(struct kbase_context *kctx, struct kbase_jd_atom *katom)
363 {
364 	int prio = katom->sched_priority;
365 	int js = katom->slot_nr;
366 	struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
367 	struct rb_node **new = &(queue->runnable_tree.rb_node), *parent = NULL;
368 
369 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
370 
371 	while (*new) {
372 		struct kbase_jd_atom *entry = container_of(*new,
373 				struct kbase_jd_atom, runnable_tree_node);
374 
375 		parent = *new;
376 		if (LESS_THAN_WRAP(katom->age, entry->age))
377 			new = &((*new)->rb_left);
378 		else
379 			new = &((*new)->rb_right);
380 	}
381 
382 	/* Add new node and rebalance tree. */
383 	rb_link_node(&katom->runnable_tree_node, parent, new);
384 	rb_insert_color(&katom->runnable_tree_node, &queue->runnable_tree);
385 }
386 
387 /**
388  * jsctx_rb_unpull(): - Undo marking of atom in list as running
389  * @kctx:  Pointer to kbase context with ring buffer.
390  * @katom: Pointer to katom to unpull.
391  *
392  * Undo jsctx_rb_pull() and put @katom back in the queue.
393  *
394  * jsctx_rb_unpull() must be called on atoms in the same order the atoms were
395  * pulled.
396  */
397 static inline void
jsctx_rb_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)398 jsctx_rb_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
399 {
400 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
401 
402 	jsctx_tree_add(kctx, katom);
403 }
404 
405 static bool kbase_js_ctx_pullable(struct kbase_context *kctx,
406 					int js,
407 					bool is_scheduled);
408 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
409 						struct kbase_context *kctx,
410 						int js);
411 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
412 						struct kbase_context *kctx,
413 						int js);
414 
415 /*
416  * Functions private to KBase ('Protected' functions)
417  */
kbasep_js_devdata_init(struct kbase_device * const kbdev)418 int kbasep_js_devdata_init(struct kbase_device * const kbdev)
419 {
420 	struct kbasep_js_device_data *jsdd;
421 	int i;
422 
423 	KBASE_DEBUG_ASSERT(kbdev != NULL);
424 
425 	jsdd = &kbdev->js_data;
426 
427 #ifdef CONFIG_MALI_DEBUG
428 	/* Soft-stop will be disabled on a single context by default unless
429 	 * softstop_always is set */
430 	jsdd->softstop_always = false;
431 #endif				/* CONFIG_MALI_DEBUG */
432 	jsdd->nr_all_contexts_running = 0;
433 	jsdd->nr_user_contexts_running = 0;
434 	jsdd->nr_contexts_pullable = 0;
435 	atomic_set(&jsdd->nr_contexts_runnable, 0);
436 	/* No ctx allowed to submit */
437 	jsdd->runpool_irq.submit_allowed = 0u;
438 	memset(jsdd->runpool_irq.ctx_attr_ref_count, 0,
439 			sizeof(jsdd->runpool_irq.ctx_attr_ref_count));
440 	memset(jsdd->runpool_irq.slot_affinities, 0,
441 			sizeof(jsdd->runpool_irq.slot_affinities));
442 	memset(jsdd->runpool_irq.slot_affinity_refcount, 0,
443 			sizeof(jsdd->runpool_irq.slot_affinity_refcount));
444 	INIT_LIST_HEAD(&jsdd->suspended_soft_jobs_list);
445 
446 	/* Config attributes */
447 	jsdd->scheduling_period_ns = DEFAULT_JS_SCHEDULING_PERIOD_NS;
448 	jsdd->soft_stop_ticks = DEFAULT_JS_SOFT_STOP_TICKS;
449 	jsdd->soft_stop_ticks_cl = DEFAULT_JS_SOFT_STOP_TICKS_CL;
450 	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8408))
451 		jsdd->hard_stop_ticks_ss = DEFAULT_JS_HARD_STOP_TICKS_SS_8408;
452 	else
453 		jsdd->hard_stop_ticks_ss = DEFAULT_JS_HARD_STOP_TICKS_SS;
454 	jsdd->hard_stop_ticks_cl = DEFAULT_JS_HARD_STOP_TICKS_CL;
455 	jsdd->hard_stop_ticks_dumping = DEFAULT_JS_HARD_STOP_TICKS_DUMPING;
456 	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8408))
457 		jsdd->gpu_reset_ticks_ss = DEFAULT_JS_RESET_TICKS_SS_8408;
458 	else
459 		jsdd->gpu_reset_ticks_ss = DEFAULT_JS_RESET_TICKS_SS;
460 	jsdd->gpu_reset_ticks_cl = DEFAULT_JS_RESET_TICKS_CL;
461 	jsdd->gpu_reset_ticks_dumping = DEFAULT_JS_RESET_TICKS_DUMPING;
462 	jsdd->ctx_timeslice_ns = DEFAULT_JS_CTX_TIMESLICE_NS;
463 	atomic_set(&jsdd->soft_job_timeout_ms, DEFAULT_JS_SOFT_JOB_TIMEOUT);
464 
465 	dev_dbg(kbdev->dev, "JS Config Attribs: ");
466 	dev_dbg(kbdev->dev, "\tscheduling_period_ns:%u",
467 			jsdd->scheduling_period_ns);
468 	dev_dbg(kbdev->dev, "\tsoft_stop_ticks:%u",
469 			jsdd->soft_stop_ticks);
470 	dev_dbg(kbdev->dev, "\tsoft_stop_ticks_cl:%u",
471 			jsdd->soft_stop_ticks_cl);
472 	dev_dbg(kbdev->dev, "\thard_stop_ticks_ss:%u",
473 			jsdd->hard_stop_ticks_ss);
474 	dev_dbg(kbdev->dev, "\thard_stop_ticks_cl:%u",
475 			jsdd->hard_stop_ticks_cl);
476 	dev_dbg(kbdev->dev, "\thard_stop_ticks_dumping:%u",
477 			jsdd->hard_stop_ticks_dumping);
478 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_ss:%u",
479 			jsdd->gpu_reset_ticks_ss);
480 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_cl:%u",
481 			jsdd->gpu_reset_ticks_cl);
482 	dev_dbg(kbdev->dev, "\tgpu_reset_ticks_dumping:%u",
483 			jsdd->gpu_reset_ticks_dumping);
484 	dev_dbg(kbdev->dev, "\tctx_timeslice_ns:%u",
485 			jsdd->ctx_timeslice_ns);
486 	dev_dbg(kbdev->dev, "\tsoft_job_timeout:%i",
487 		atomic_read(&jsdd->soft_job_timeout_ms));
488 
489 	if (!(jsdd->soft_stop_ticks < jsdd->hard_stop_ticks_ss &&
490 			jsdd->hard_stop_ticks_ss < jsdd->gpu_reset_ticks_ss &&
491 			jsdd->soft_stop_ticks < jsdd->hard_stop_ticks_dumping &&
492 			jsdd->hard_stop_ticks_dumping <
493 			jsdd->gpu_reset_ticks_dumping)) {
494 		dev_err(kbdev->dev, "Job scheduler timeouts invalid; soft/hard/reset tick counts should be in increasing order\n");
495 		return -EINVAL;
496 	}
497 
498 #if KBASE_DISABLE_SCHEDULING_SOFT_STOPS
499 	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.",
500 			jsdd->soft_stop_ticks,
501 			jsdd->scheduling_period_ns);
502 #endif
503 #if KBASE_DISABLE_SCHEDULING_HARD_STOPS
504 	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.",
505 			jsdd->hard_stop_ticks_ss,
506 			jsdd->hard_stop_ticks_dumping,
507 			jsdd->scheduling_period_ns);
508 #endif
509 #if KBASE_DISABLE_SCHEDULING_SOFT_STOPS && KBASE_DISABLE_SCHEDULING_HARD_STOPS
510 	dev_dbg(kbdev->dev, "Note: The JS tick timer (if coded) will still be run, but do nothing.");
511 #endif
512 
513 	for (i = 0; i < kbdev->gpu_props.num_job_slots; ++i)
514 		jsdd->js_reqs[i] = core_reqs_from_jsn_features(
515 			kbdev->gpu_props.props.raw_props.js_features[i]);
516 
517 	/* On error, we could continue on: providing none of the below resources
518 	 * rely on the ones above */
519 
520 	mutex_init(&jsdd->runpool_mutex);
521 	mutex_init(&jsdd->queue_mutex);
522 	spin_lock_init(&kbdev->hwaccess_lock);
523 	sema_init(&jsdd->schedule_sem, 1);
524 
525 	for (i = 0; i < kbdev->gpu_props.num_job_slots; ++i) {
526 		INIT_LIST_HEAD(&jsdd->ctx_list_pullable[i]);
527 		INIT_LIST_HEAD(&jsdd->ctx_list_unpullable[i]);
528 	}
529 
530 	return 0;
531 }
532 
kbasep_js_devdata_halt(struct kbase_device *kbdev)533 void kbasep_js_devdata_halt(struct kbase_device *kbdev)
534 {
535 	CSTD_UNUSED(kbdev);
536 }
537 
kbasep_js_devdata_term(struct kbase_device *kbdev)538 void kbasep_js_devdata_term(struct kbase_device *kbdev)
539 {
540 	struct kbasep_js_device_data *js_devdata;
541 	s8 zero_ctx_attr_ref_count[KBASEP_JS_CTX_ATTR_COUNT] = { 0, };
542 
543 	KBASE_DEBUG_ASSERT(kbdev != NULL);
544 
545 	js_devdata = &kbdev->js_data;
546 
547 	/* The caller must de-register all contexts before calling this
548 	 */
549 	KBASE_DEBUG_ASSERT(js_devdata->nr_all_contexts_running == 0);
550 	KBASE_DEBUG_ASSERT(memcmp(
551 	        js_devdata->runpool_irq.ctx_attr_ref_count,
552 	        zero_ctx_attr_ref_count,
553 	        sizeof(zero_ctx_attr_ref_count)) == 0);
554 	CSTD_UNUSED(zero_ctx_attr_ref_count);
555 }
556 
kbasep_js_kctx_init(struct kbase_context * const kctx)557 int kbasep_js_kctx_init(struct kbase_context * const kctx)
558 {
559 	struct kbase_device *kbdev;
560 	struct kbasep_js_kctx_info *js_kctx_info;
561 	int i, j;
562 
563 	KBASE_DEBUG_ASSERT(kctx != NULL);
564 
565 	kbdev = kctx->kbdev;
566 	KBASE_DEBUG_ASSERT(kbdev != NULL);
567 
568 	for (i = 0; i < BASE_JM_MAX_NR_SLOTS; ++i)
569 		INIT_LIST_HEAD(&kctx->jctx.sched_info.ctx.ctx_list_entry[i]);
570 
571 	js_kctx_info = &kctx->jctx.sched_info;
572 
573 	js_kctx_info->ctx.nr_jobs = 0;
574 	kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
575 	kbase_ctx_flag_clear(kctx, KCTX_DYING);
576 	memset(js_kctx_info->ctx.ctx_attr_ref_count, 0,
577 			sizeof(js_kctx_info->ctx.ctx_attr_ref_count));
578 
579 	/* Initially, the context is disabled from submission until the create
580 	 * flags are set */
581 	kbase_ctx_flag_set(kctx, KCTX_SUBMIT_DISABLED);
582 
583 	/* On error, we could continue on: providing none of the below resources
584 	 * rely on the ones above */
585 	mutex_init(&js_kctx_info->ctx.jsctx_mutex);
586 
587 	init_waitqueue_head(&js_kctx_info->ctx.is_scheduled_wait);
588 
589 	for (i = 0; i < KBASE_JS_ATOM_SCHED_PRIO_COUNT; i++) {
590 		for (j = 0; j < BASE_JM_MAX_NR_SLOTS; j++) {
591 			INIT_LIST_HEAD(&kctx->jsctx_queue[i][j].x_dep_head);
592 			kctx->jsctx_queue[i][j].runnable_tree = RB_ROOT;
593 		}
594 	}
595 
596 	return 0;
597 }
598 
kbasep_js_kctx_term(struct kbase_context *kctx)599 void kbasep_js_kctx_term(struct kbase_context *kctx)
600 {
601 	struct kbase_device *kbdev;
602 	struct kbasep_js_kctx_info *js_kctx_info;
603 	int js;
604 	bool update_ctx_count = false;
605 
606 	KBASE_DEBUG_ASSERT(kctx != NULL);
607 
608 	kbdev = kctx->kbdev;
609 	KBASE_DEBUG_ASSERT(kbdev != NULL);
610 
611 	js_kctx_info = &kctx->jctx.sched_info;
612 
613 	/* The caller must de-register all jobs before calling this */
614 	KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
615 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs == 0);
616 
617 	mutex_lock(&kbdev->js_data.queue_mutex);
618 	mutex_lock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
619 
620 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++)
621 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
622 
623 	if (kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF)) {
624 		WARN_ON(atomic_read(&kbdev->js_data.nr_contexts_runnable) <= 0);
625 		atomic_dec(&kbdev->js_data.nr_contexts_runnable);
626 		update_ctx_count = true;
627 		kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
628 	}
629 
630 	mutex_unlock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
631 	mutex_unlock(&kbdev->js_data.queue_mutex);
632 
633 	if (update_ctx_count) {
634 		mutex_lock(&kbdev->js_data.runpool_mutex);
635 		kbase_backend_ctx_count_changed(kbdev);
636 		mutex_unlock(&kbdev->js_data.runpool_mutex);
637 	}
638 }
639 
640 /**
641  * kbase_js_ctx_list_add_pullable_nolock - Variant of
642  *                                         kbase_jd_ctx_list_add_pullable()
643  *                                         where the caller must hold
644  *                                         hwaccess_lock
645  * @kbdev:  Device pointer
646  * @kctx:   Context to add to queue
647  * @js:     Job slot to use
648  *
649  * Caller must hold hwaccess_lock
650  *
651  * Return: true if caller should call kbase_backend_ctx_count_changed()
652  */
kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)653 static bool kbase_js_ctx_list_add_pullable_nolock(struct kbase_device *kbdev,
654 						struct kbase_context *kctx,
655 						int js)
656 {
657 	bool ret = false;
658 
659 	lockdep_assert_held(&kbdev->hwaccess_lock);
660 
661 	if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
662 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
663 
664 	list_add_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
665 					&kbdev->js_data.ctx_list_pullable[js]);
666 
667 	if (!kctx->slots_pullable) {
668 		kbdev->js_data.nr_contexts_pullable++;
669 		ret = true;
670 		if (!atomic_read(&kctx->atoms_pulled)) {
671 			WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
672 			kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
673 			atomic_inc(&kbdev->js_data.nr_contexts_runnable);
674 		}
675 	}
676 	kctx->slots_pullable |= (1 << js);
677 
678 	return ret;
679 }
680 
681 /**
682  * kbase_js_ctx_list_add_pullable_head_nolock - Variant of
683  *                                              kbase_js_ctx_list_add_pullable_head()
684  *                                              where the caller must hold
685  *                                              hwaccess_lock
686  * @kbdev:  Device pointer
687  * @kctx:   Context to add to queue
688  * @js:     Job slot to use
689  *
690  * Caller must hold hwaccess_lock
691  *
692  * Return:  true if caller should call kbase_backend_ctx_count_changed()
693  */
kbase_js_ctx_list_add_pullable_head_nolock( struct kbase_device *kbdev, struct kbase_context *kctx, int js)694 static bool kbase_js_ctx_list_add_pullable_head_nolock(
695 		struct kbase_device *kbdev, struct kbase_context *kctx, int js)
696 {
697 	bool ret = false;
698 
699 	lockdep_assert_held(&kbdev->hwaccess_lock);
700 
701 	if (!list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
702 		list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
703 
704 	list_add(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
705 					&kbdev->js_data.ctx_list_pullable[js]);
706 
707 	if (!kctx->slots_pullable) {
708 		kbdev->js_data.nr_contexts_pullable++;
709 		ret = true;
710 		if (!atomic_read(&kctx->atoms_pulled)) {
711 			WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
712 			kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
713 			atomic_inc(&kbdev->js_data.nr_contexts_runnable);
714 		}
715 	}
716 	kctx->slots_pullable |= (1 << js);
717 
718 	return ret;
719 }
720 
721 /**
722  * kbase_js_ctx_list_add_pullable_head - Add context to the head of the
723  *                                       per-slot pullable context queue
724  * @kbdev:  Device pointer
725  * @kctx:   Context to add to queue
726  * @js:     Job slot to use
727  *
728  * If the context is on either the pullable or unpullable queues, then it is
729  * removed before being added to the head.
730  *
731  * This function should be used when a context has been scheduled, but no jobs
732  * can currently be pulled from it.
733  *
734  * Return:  true if caller should call kbase_backend_ctx_count_changed()
735  */
kbase_js_ctx_list_add_pullable_head(struct kbase_device *kbdev, struct kbase_context *kctx, int js)736 static bool kbase_js_ctx_list_add_pullable_head(struct kbase_device *kbdev,
737 						struct kbase_context *kctx,
738 						int js)
739 {
740 	bool ret;
741 	unsigned long flags;
742 
743 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
744 	ret = kbase_js_ctx_list_add_pullable_head_nolock(kbdev, kctx, js);
745 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
746 
747 	return ret;
748 }
749 
750 /**
751  * kbase_js_ctx_list_add_unpullable_nolock - Add context to the tail of the
752  *                                           per-slot unpullable context queue
753  * @kbdev:  Device pointer
754  * @kctx:   Context to add to queue
755  * @js:     Job slot to use
756  *
757  * The context must already be on the per-slot pullable queue. It will be
758  * removed from the pullable queue before being added to the unpullable queue.
759  *
760  * This function should be used when a context has been pulled from, and there
761  * are no jobs remaining on the specified slot.
762  *
763  * Caller must hold hwaccess_lock
764  *
765  * Return:  true if caller should call kbase_backend_ctx_count_changed()
766  */
kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)767 static bool kbase_js_ctx_list_add_unpullable_nolock(struct kbase_device *kbdev,
768 						struct kbase_context *kctx,
769 						int js)
770 {
771 	bool ret = false;
772 
773 	lockdep_assert_held(&kbdev->hwaccess_lock);
774 
775 	list_move_tail(&kctx->jctx.sched_info.ctx.ctx_list_entry[js],
776 				&kbdev->js_data.ctx_list_unpullable[js]);
777 
778 	if (kctx->slots_pullable == (1 << js)) {
779 		kbdev->js_data.nr_contexts_pullable--;
780 		ret = true;
781 		if (!atomic_read(&kctx->atoms_pulled)) {
782 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
783 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
784 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
785 		}
786 	}
787 	kctx->slots_pullable &= ~(1 << js);
788 
789 	return ret;
790 }
791 
792 /**
793  * kbase_js_ctx_list_remove_nolock - Remove context from the per-slot pullable
794  *                                   or unpullable context queues
795  * @kbdev:  Device pointer
796  * @kctx:   Context to remove from queue
797  * @js:     Job slot to use
798  *
799  * The context must already be on one of the queues.
800  *
801  * This function should be used when a context has no jobs on the GPU, and no
802  * jobs remaining for the specified slot.
803  *
804  * Caller must hold hwaccess_lock
805  *
806  * Return:  true if caller should call kbase_backend_ctx_count_changed()
807  */
kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev, struct kbase_context *kctx, int js)808 static bool kbase_js_ctx_list_remove_nolock(struct kbase_device *kbdev,
809 					struct kbase_context *kctx,
810 					int js)
811 {
812 	bool ret = false;
813 
814 	lockdep_assert_held(&kbdev->hwaccess_lock);
815 
816 	WARN_ON(list_empty(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]));
817 
818 	list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
819 
820 	if (kctx->slots_pullable == (1 << js)) {
821 		kbdev->js_data.nr_contexts_pullable--;
822 		ret = true;
823 		if (!atomic_read(&kctx->atoms_pulled)) {
824 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
825 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
826 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
827 		}
828 	}
829 	kctx->slots_pullable &= ~(1 << js);
830 
831 	return ret;
832 }
833 
834 /**
835  * kbase_js_ctx_list_pop_head_nolock - Variant of kbase_js_ctx_list_pop_head()
836  *                                     where the caller must hold
837  *                                     hwaccess_lock
838  * @kbdev:  Device pointer
839  * @js:     Job slot to use
840  *
841  * Caller must hold hwaccess_lock
842  *
843  * Return:  Context to use for specified slot.
844  *          NULL if no contexts present for specified slot
845  */
kbase_js_ctx_list_pop_head_nolock( struct kbase_device *kbdev, int js)846 static struct kbase_context *kbase_js_ctx_list_pop_head_nolock(
847 						struct kbase_device *kbdev,
848 						int js)
849 {
850 	struct kbase_context *kctx;
851 
852 	lockdep_assert_held(&kbdev->hwaccess_lock);
853 
854 	if (list_empty(&kbdev->js_data.ctx_list_pullable[js]))
855 		return NULL;
856 
857 	kctx = list_entry(kbdev->js_data.ctx_list_pullable[js].next,
858 					struct kbase_context,
859 					jctx.sched_info.ctx.ctx_list_entry[js]);
860 
861 	list_del_init(&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
862 
863 	return kctx;
864 }
865 
866 /**
867  * kbase_js_ctx_list_pop_head - Pop the head context off the per-slot pullable
868  *                              queue.
869  * @kbdev:  Device pointer
870  * @js:     Job slot to use
871  *
872  * Return:  Context to use for specified slot.
873  *          NULL if no contexts present for specified slot
874  */
kbase_js_ctx_list_pop_head( struct kbase_device *kbdev, int js)875 static struct kbase_context *kbase_js_ctx_list_pop_head(
876 		struct kbase_device *kbdev, int js)
877 {
878 	struct kbase_context *kctx;
879 	unsigned long flags;
880 
881 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
882 	kctx = kbase_js_ctx_list_pop_head_nolock(kbdev, js);
883 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
884 
885 	return kctx;
886 }
887 
888 /**
889  * kbase_js_ctx_pullable - Return if a context can be pulled from on the
890  *                         specified slot
891  * @kctx:          Context pointer
892  * @js:            Job slot to use
893  * @is_scheduled:  true if the context is currently scheduled
894  *
895  * Caller must hold hwaccess_lock
896  *
897  * Return:         true if context can be pulled from on specified slot
898  *                 false otherwise
899  */
kbase_js_ctx_pullable(struct kbase_context *kctx, int js, bool is_scheduled)900 static bool kbase_js_ctx_pullable(struct kbase_context *kctx, int js,
901 					bool is_scheduled)
902 {
903 	struct kbasep_js_device_data *js_devdata;
904 	struct kbase_jd_atom *katom;
905 
906 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
907 
908 	js_devdata = &kctx->kbdev->js_data;
909 
910 	if (is_scheduled) {
911 		if (!kbasep_js_is_submit_allowed(js_devdata, kctx))
912 			return false;
913 	}
914 	katom = jsctx_rb_peek(kctx, js);
915 	if (!katom)
916 		return false; /* No pullable atoms */
917 	if (kctx->blocked_js[js][katom->sched_priority])
918 		return false;
919 	if (atomic_read(&katom->blocked))
920 		return false; /* next atom blocked */
921 	if (katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) {
922 		if (katom->x_pre_dep->gpu_rb_state ==
923 					KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
924 					katom->x_pre_dep->will_fail_event_code)
925 			return false;
926 		if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
927 				kbase_backend_nr_atoms_on_slot(kctx->kbdev, js))
928 			return false;
929 	}
930 
931 	return true;
932 }
933 
kbase_js_dep_validate(struct kbase_context *kctx, struct kbase_jd_atom *katom)934 static bool kbase_js_dep_validate(struct kbase_context *kctx,
935 				struct kbase_jd_atom *katom)
936 {
937 	struct kbase_device *kbdev = kctx->kbdev;
938 	bool ret = true;
939 	bool has_dep = false, has_x_dep = false;
940 	int js = kbase_js_get_slot(kbdev, katom);
941 	int prio = katom->sched_priority;
942 	int i;
943 
944 	for (i = 0; i < 2; i++) {
945 		struct kbase_jd_atom *dep_atom = katom->dep[i].atom;
946 
947 		if (dep_atom) {
948 			int dep_js = kbase_js_get_slot(kbdev, dep_atom);
949 			int dep_prio = dep_atom->sched_priority;
950 
951 			/* Dependent atom must already have been submitted */
952 			if (!(dep_atom->atom_flags &
953 					KBASE_KATOM_FLAG_JSCTX_IN_TREE)) {
954 				ret = false;
955 				break;
956 			}
957 
958 			/* Dependencies with different priorities can't
959 			  be represented in the ringbuffer */
960 			if (prio != dep_prio) {
961 				ret = false;
962 				break;
963 			}
964 
965 			if (js == dep_js) {
966 				/* Only one same-slot dependency can be
967 				 * represented in the ringbuffer */
968 				if (has_dep) {
969 					ret = false;
970 					break;
971 				}
972 				/* Each dependee atom can only have one
973 				 * same-slot dependency */
974 				if (dep_atom->post_dep) {
975 					ret = false;
976 					break;
977 				}
978 				has_dep = true;
979 			} else {
980 				/* Only one cross-slot dependency can be
981 				 * represented in the ringbuffer */
982 				if (has_x_dep) {
983 					ret = false;
984 					break;
985 				}
986 				/* Each dependee atom can only have one
987 				 * cross-slot dependency */
988 				if (dep_atom->x_post_dep) {
989 					ret = false;
990 					break;
991 				}
992 				/* The dependee atom can not already be in the
993 				 * HW access ringbuffer */
994 				if (dep_atom->gpu_rb_state !=
995 					KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB) {
996 					ret = false;
997 					break;
998 				}
999 				/* The dependee atom can not already have
1000 				 * completed */
1001 				if (dep_atom->status !=
1002 						KBASE_JD_ATOM_STATE_IN_JS) {
1003 					ret = false;
1004 					break;
1005 				}
1006 				/* Cross-slot dependencies must not violate
1007 				 * PRLAM-8987 affinity restrictions */
1008 				if (kbase_hw_has_issue(kbdev,
1009 							BASE_HW_ISSUE_8987) &&
1010 						(js == 2 || dep_js == 2)) {
1011 					ret = false;
1012 					break;
1013 				}
1014 				has_x_dep = true;
1015 			}
1016 
1017 			/* Dependency can be represented in ringbuffers */
1018 		}
1019 	}
1020 
1021 	/* If dependencies can be represented by ringbuffer then clear them from
1022 	 * atom structure */
1023 	if (ret) {
1024 		for (i = 0; i < 2; i++) {
1025 			struct kbase_jd_atom *dep_atom = katom->dep[i].atom;
1026 
1027 			if (dep_atom) {
1028 				int dep_js = kbase_js_get_slot(kbdev, dep_atom);
1029 
1030 				if ((js != dep_js) &&
1031 					(dep_atom->status !=
1032 						KBASE_JD_ATOM_STATE_COMPLETED)
1033 					&& (dep_atom->status !=
1034 					KBASE_JD_ATOM_STATE_HW_COMPLETED)
1035 					&& (dep_atom->status !=
1036 						KBASE_JD_ATOM_STATE_UNUSED)) {
1037 
1038 					katom->atom_flags |=
1039 						KBASE_KATOM_FLAG_X_DEP_BLOCKED;
1040 					katom->x_pre_dep = dep_atom;
1041 					dep_atom->x_post_dep = katom;
1042 					if (kbase_jd_katom_dep_type(
1043 							&katom->dep[i]) ==
1044 							BASE_JD_DEP_TYPE_DATA)
1045 						katom->atom_flags |=
1046 						KBASE_KATOM_FLAG_FAIL_BLOCKER;
1047 				}
1048 				if ((kbase_jd_katom_dep_type(&katom->dep[i])
1049 						== BASE_JD_DEP_TYPE_DATA) &&
1050 						(js == dep_js)) {
1051 					katom->pre_dep = dep_atom;
1052 					dep_atom->post_dep = katom;
1053 				}
1054 
1055 				list_del(&katom->dep_item[i]);
1056 				kbase_jd_katom_dep_clear(&katom->dep[i]);
1057 			}
1058 		}
1059 	}
1060 
1061 	return ret;
1062 }
1063 
kbasep_js_add_job(struct kbase_context *kctx, struct kbase_jd_atom *atom)1064 bool kbasep_js_add_job(struct kbase_context *kctx,
1065 		struct kbase_jd_atom *atom)
1066 {
1067 	unsigned long flags;
1068 	struct kbasep_js_kctx_info *js_kctx_info;
1069 	struct kbase_device *kbdev;
1070 	struct kbasep_js_device_data *js_devdata;
1071 
1072 	bool enqueue_required = false;
1073 	bool timer_sync = false;
1074 
1075 	KBASE_DEBUG_ASSERT(kctx != NULL);
1076 	KBASE_DEBUG_ASSERT(atom != NULL);
1077 	lockdep_assert_held(&kctx->jctx.lock);
1078 
1079 	kbdev = kctx->kbdev;
1080 	js_devdata = &kbdev->js_data;
1081 	js_kctx_info = &kctx->jctx.sched_info;
1082 
1083 	mutex_lock(&js_devdata->queue_mutex);
1084 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1085 
1086 	/*
1087 	 * Begin Runpool transaction
1088 	 */
1089 	mutex_lock(&js_devdata->runpool_mutex);
1090 
1091 	/* Refcount ctx.nr_jobs */
1092 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs < U32_MAX);
1093 	++(js_kctx_info->ctx.nr_jobs);
1094 
1095 	/* Setup any scheduling information */
1096 	kbasep_js_clear_job_retry_submit(atom);
1097 
1098 	/* Lock for state available during IRQ */
1099 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1100 
1101 	if (!kbase_js_dep_validate(kctx, atom)) {
1102 		/* Dependencies could not be represented */
1103 		--(js_kctx_info->ctx.nr_jobs);
1104 
1105 		/* Setting atom status back to queued as it still has unresolved
1106 		 * dependencies */
1107 		atom->status = KBASE_JD_ATOM_STATE_QUEUED;
1108 
1109 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1110 		mutex_unlock(&js_devdata->runpool_mutex);
1111 
1112 		goto out_unlock;
1113 	}
1114 
1115 	KBASE_TLSTREAM_TL_ATTRIB_ATOM_STATE(atom, TL_ATOM_STATE_READY);
1116 	KBASE_TIMELINE_ATOM_READY(kctx, kbase_jd_atom_id(kctx, atom));
1117 
1118 	enqueue_required = kbase_js_dep_resolved_submit(kctx, atom);
1119 
1120 	KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_ADD_JOB, kctx, atom, atom->jc,
1121 				kbasep_js_trace_get_refcnt(kbdev, kctx));
1122 
1123 	/* Context Attribute Refcounting */
1124 	kbasep_js_ctx_attr_ctx_retain_atom(kbdev, kctx, atom);
1125 
1126 	if (enqueue_required) {
1127 		if (kbase_js_ctx_pullable(kctx, atom->slot_nr, false))
1128 			timer_sync = kbase_js_ctx_list_add_pullable_nolock(
1129 					kbdev, kctx, atom->slot_nr);
1130 		else
1131 			timer_sync = kbase_js_ctx_list_add_unpullable_nolock(
1132 					kbdev, kctx, atom->slot_nr);
1133 	}
1134 	/* If this context is active and the atom is the first on its slot,
1135 	 * kick the job manager to attempt to fast-start the atom */
1136 	if (enqueue_required && kctx == kbdev->hwaccess.active_kctx)
1137 		kbase_jm_try_kick(kbdev, 1 << atom->slot_nr);
1138 
1139 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1140 	if (timer_sync)
1141 		kbase_backend_ctx_count_changed(kbdev);
1142 	mutex_unlock(&js_devdata->runpool_mutex);
1143 	/* End runpool transaction */
1144 
1145 	if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED)) {
1146 		if (kbase_ctx_flag(kctx, KCTX_DYING)) {
1147 			/* A job got added while/after kbase_job_zap_context()
1148 			 * was called on a non-scheduled context (e.g. KDS
1149 			 * dependency resolved). Kill that job by killing the
1150 			 * context. */
1151 			kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx,
1152 					false);
1153 		} else if (js_kctx_info->ctx.nr_jobs == 1) {
1154 			/* Handle Refcount going from 0 to 1: schedule the
1155 			 * context on the Queue */
1156 			KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1157 			dev_dbg(kbdev->dev, "JS: Enqueue Context %p", kctx);
1158 
1159 			/* Queue was updated - caller must try to
1160 			 * schedule the head context */
1161 			WARN_ON(!enqueue_required);
1162 		}
1163 	}
1164 out_unlock:
1165 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1166 
1167 	mutex_unlock(&js_devdata->queue_mutex);
1168 
1169 	return enqueue_required;
1170 }
1171 
kbasep_js_remove_job(struct kbase_device *kbdev, struct kbase_context *kctx, struct kbase_jd_atom *atom)1172 void kbasep_js_remove_job(struct kbase_device *kbdev,
1173 		struct kbase_context *kctx, struct kbase_jd_atom *atom)
1174 {
1175 	struct kbasep_js_kctx_info *js_kctx_info;
1176 	struct kbasep_js_device_data *js_devdata;
1177 
1178 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1179 	KBASE_DEBUG_ASSERT(kctx != NULL);
1180 	KBASE_DEBUG_ASSERT(atom != NULL);
1181 
1182 	js_devdata = &kbdev->js_data;
1183 	js_kctx_info = &kctx->jctx.sched_info;
1184 
1185 	KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_REMOVE_JOB, kctx, atom, atom->jc,
1186 			kbasep_js_trace_get_refcnt(kbdev, kctx));
1187 
1188 	/* De-refcount ctx.nr_jobs */
1189 	KBASE_DEBUG_ASSERT(js_kctx_info->ctx.nr_jobs > 0);
1190 	--(js_kctx_info->ctx.nr_jobs);
1191 }
1192 
kbasep_js_remove_cancelled_job(struct kbase_device *kbdev, struct kbase_context *kctx, struct kbase_jd_atom *katom)1193 bool kbasep_js_remove_cancelled_job(struct kbase_device *kbdev,
1194 		struct kbase_context *kctx, struct kbase_jd_atom *katom)
1195 {
1196 	unsigned long flags;
1197 	struct kbasep_js_atom_retained_state katom_retained_state;
1198 	struct kbasep_js_device_data *js_devdata;
1199 	bool attr_state_changed;
1200 
1201 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1202 	KBASE_DEBUG_ASSERT(kctx != NULL);
1203 	KBASE_DEBUG_ASSERT(katom != NULL);
1204 
1205 	js_devdata = &kbdev->js_data;
1206 
1207 	kbasep_js_atom_retained_state_copy(&katom_retained_state, katom);
1208 	kbasep_js_remove_job(kbdev, kctx, katom);
1209 
1210 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1211 
1212 	/* The atom has 'finished' (will not be re-run), so no need to call
1213 	 * kbasep_js_has_atom_finished().
1214 	 *
1215 	 * This is because it returns false for soft-stopped atoms, but we
1216 	 * want to override that, because we're cancelling an atom regardless of
1217 	 * whether it was soft-stopped or not */
1218 	attr_state_changed = kbasep_js_ctx_attr_ctx_release_atom(kbdev, kctx,
1219 			&katom_retained_state);
1220 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1221 
1222 	return attr_state_changed;
1223 }
1224 
kbasep_js_runpool_retain_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1225 bool kbasep_js_runpool_retain_ctx(struct kbase_device *kbdev,
1226 		struct kbase_context *kctx)
1227 {
1228 	unsigned long flags;
1229 	struct kbasep_js_device_data *js_devdata;
1230 	bool result;
1231 
1232 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1233 	js_devdata = &kbdev->js_data;
1234 
1235 	mutex_lock(&kbdev->mmu_hw_mutex);
1236 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1237 	result = kbasep_js_runpool_retain_ctx_nolock(kbdev, kctx);
1238 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1239 	mutex_unlock(&kbdev->mmu_hw_mutex);
1240 
1241 	return result;
1242 }
1243 
kbasep_js_runpool_lookup_ctx(struct kbase_device *kbdev, int as_nr)1244 struct kbase_context *kbasep_js_runpool_lookup_ctx(struct kbase_device *kbdev,
1245 		int as_nr)
1246 {
1247 	int ret = 0;
1248 	unsigned long flags;
1249 	struct kbasep_js_device_data *js_devdata;
1250 	struct kbase_context *found_kctx = NULL;
1251 
1252 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1253 	KBASE_DEBUG_ASSERT(0 <= as_nr && as_nr < BASE_MAX_NR_AS);
1254 	js_devdata = &kbdev->js_data;
1255 
1256 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1257 
1258 	found_kctx = kbdev->as_to_kctx[as_nr];
1259 
1260 	if (found_kctx != NULL) {
1261 		ret = kbase_ctx_sched_retain_ctx_refcount(found_kctx);
1262 		if (ret != 0) {
1263 			E("fail to retain ctx_refcount, ret : %d.", ret);
1264 			found_kctx = NULL;
1265 		}
1266 	}
1267 
1268 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1269 
1270 	return found_kctx;
1271 }
1272 
1273 /**
1274  * kbasep_js_release_result - Try running more jobs after releasing a context
1275  *                            and/or atom
1276  *
1277  * @kbdev:                   The kbase_device to operate on
1278  * @kctx:                    The kbase_context to operate on
1279  * @katom_retained_state:    Retained state from the atom
1280  * @runpool_ctx_attr_change: True if the runpool context attributes have changed
1281  *
1282  * This collates a set of actions that must happen whilst hwaccess_lock is held.
1283  *
1284  * This includes running more jobs when:
1285  * - The previously released kctx caused a ctx attribute change,
1286  * - The released atom caused a ctx attribute change,
1287  * - Slots were previously blocked due to affinity restrictions,
1288  * - Submission during IRQ handling failed.
1289  *
1290  * Return: %KBASEP_JS_RELEASE_RESULT_SCHED_ALL if context attributes were
1291  *         changed. The caller should try scheduling all contexts
1292  */
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)1293 static kbasep_js_release_result kbasep_js_run_jobs_after_ctx_and_atom_release(
1294 		struct kbase_device *kbdev,
1295 		struct kbase_context *kctx,
1296 		struct kbasep_js_atom_retained_state *katom_retained_state,
1297 		bool runpool_ctx_attr_change)
1298 {
1299 	struct kbasep_js_device_data *js_devdata;
1300 	kbasep_js_release_result result = 0;
1301 
1302 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1303 	KBASE_DEBUG_ASSERT(kctx != NULL);
1304 	KBASE_DEBUG_ASSERT(katom_retained_state != NULL);
1305 	js_devdata = &kbdev->js_data;
1306 
1307 	lockdep_assert_held(&kctx->jctx.sched_info.ctx.jsctx_mutex);
1308 	lockdep_assert_held(&js_devdata->runpool_mutex);
1309 	lockdep_assert_held(&kbdev->hwaccess_lock);
1310 
1311 	if (js_devdata->nr_user_contexts_running != 0) {
1312 		bool retry_submit = false;
1313 		int retry_jobslot = 0;
1314 
1315 		if (katom_retained_state)
1316 			retry_submit = kbasep_js_get_atom_retry_submit_slot(
1317 					katom_retained_state, &retry_jobslot);
1318 
1319 		if (runpool_ctx_attr_change || retry_submit) {
1320 			/* A change in runpool ctx attributes might mean we can
1321 			 * run more jobs than before  */
1322 			result = KBASEP_JS_RELEASE_RESULT_SCHED_ALL;
1323 
1324 			KBASE_TRACE_ADD_SLOT(kbdev, JD_DONE_TRY_RUN_NEXT_JOB,
1325 						kctx, NULL, 0u, retry_jobslot);
1326 		}
1327 	}
1328 	return result;
1329 }
1330 
1331 /*
1332  * Internal function to release the reference on a ctx and an atom's "retained
1333  * state", only taking the runpool and as transaction mutexes
1334  *
1335  * This also starts more jobs running in the case of an ctx-attribute state
1336  * change
1337  *
1338  * This does none of the followup actions for scheduling:
1339  * - It does not schedule in a new context
1340  * - It does not requeue or handle dying contexts
1341  *
1342  * For those tasks, just call kbasep_js_runpool_release_ctx() instead
1343  *
1344  * Requires:
1345  * - Context is scheduled in, and kctx->as_nr matches kctx_as_nr
1346  * - Context has a non-zero refcount
1347  * - Caller holds js_kctx_info->ctx.jsctx_mutex
1348  * - Caller holds js_devdata->runpool_mutex
1349  */
kbasep_js_runpool_release_ctx_internal( struct kbase_device *kbdev, struct kbase_context *kctx, struct kbasep_js_atom_retained_state *katom_retained_state)1350 static kbasep_js_release_result kbasep_js_runpool_release_ctx_internal(
1351 		struct kbase_device *kbdev,
1352 		struct kbase_context *kctx,
1353 		struct kbasep_js_atom_retained_state *katom_retained_state)
1354 {
1355 	unsigned long flags;
1356 	struct kbasep_js_device_data *js_devdata;
1357 	struct kbasep_js_kctx_info *js_kctx_info;
1358 
1359 	kbasep_js_release_result release_result = 0u;
1360 	bool runpool_ctx_attr_change = false;
1361 	int kctx_as_nr;
1362 	struct kbase_as *current_as;
1363 	int new_ref_count;
1364 
1365 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1366 	KBASE_DEBUG_ASSERT(kctx != NULL);
1367 	js_kctx_info = &kctx->jctx.sched_info;
1368 	js_devdata = &kbdev->js_data;
1369 
1370 	/* Ensure context really is scheduled in */
1371 	KBASE_DEBUG_ASSERT(kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1372 
1373 	kctx_as_nr = kctx->as_nr;
1374 	KBASE_DEBUG_ASSERT(kctx_as_nr != KBASEP_AS_NR_INVALID);
1375 	KBASE_DEBUG_ASSERT(atomic_read(&kctx->refcount) > 0);
1376 
1377 	/*
1378 	 * Transaction begins on AS and runpool_irq
1379 	 *
1380 	 * Assert about out calling contract
1381 	 */
1382 	current_as = &kbdev->as[kctx_as_nr];
1383 	mutex_lock(&kbdev->pm.lock);
1384 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1385 
1386 	KBASE_DEBUG_ASSERT(kctx_as_nr == kctx->as_nr);
1387 	KBASE_DEBUG_ASSERT(atomic_read(&kctx->refcount) > 0);
1388 
1389 	/* Update refcount */
1390 	kbase_ctx_sched_release_ctx(kctx);
1391 	new_ref_count = atomic_read(&kctx->refcount);
1392 
1393 	/* Release the atom if it finished (i.e. wasn't soft-stopped) */
1394 	if (kbasep_js_has_atom_finished(katom_retained_state))
1395 		runpool_ctx_attr_change |= kbasep_js_ctx_attr_ctx_release_atom(
1396 				kbdev, kctx, katom_retained_state);
1397 
1398 	KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_RELEASE_CTX, kctx, NULL, 0u,
1399 			new_ref_count);
1400 
1401 	if (new_ref_count == 2 && kbase_ctx_flag(kctx, KCTX_PRIVILEGED) &&
1402 			!kbase_pm_is_suspending(kbdev)) {
1403 		/* Context is kept scheduled into an address space even when
1404 		 * there are no jobs, in this case we have to handle the
1405 		 * situation where all jobs have been evicted from the GPU and
1406 		 * submission is disabled.
1407 		 *
1408 		 * At this point we re-enable submission to allow further jobs
1409 		 * to be executed
1410 		 */
1411 		kbasep_js_set_submit_allowed(js_devdata, kctx);
1412 	}
1413 
1414 	/* Make a set of checks to see if the context should be scheduled out.
1415 	 * Note that there'll always be at least 1 reference to the context
1416 	 * which was previously acquired by kbasep_js_schedule_ctx(). */
1417 	if (new_ref_count == 1 &&
1418 		(!kbasep_js_is_submit_allowed(js_devdata, kctx) ||
1419 							kbdev->pm.suspending)) {
1420 		int num_slots = kbdev->gpu_props.num_job_slots;
1421 		int slot;
1422 
1423 		/* Last reference, and we've been told to remove this context
1424 		 * from the Run Pool */
1425 		dev_dbg(kbdev->dev, "JS: RunPool Remove Context %p because refcount=%d, jobs=%d, allowed=%d",
1426 				kctx, new_ref_count, js_kctx_info->ctx.nr_jobs,
1427 				kbasep_js_is_submit_allowed(js_devdata, kctx));
1428 
1429 #if defined(CONFIG_MALI_GATOR_SUPPORT)
1430 		kbase_trace_mali_mmu_as_released(kctx->as_nr);
1431 #endif
1432 		KBASE_TLSTREAM_TL_NRET_AS_CTX(&kbdev->as[kctx->as_nr], kctx);
1433 
1434 		kbase_backend_release_ctx_irq(kbdev, kctx);
1435 
1436 		if (kbdev->hwaccess.active_kctx == kctx)
1437 			kbdev->hwaccess.active_kctx = NULL;
1438 
1439 		/* Ctx Attribute handling
1440 		 *
1441 		 * Releasing atoms attributes must either happen before this, or
1442 		 * after the KCTX_SHEDULED flag is changed, otherwise we
1443 		 * double-decount the attributes
1444 		 */
1445 		runpool_ctx_attr_change |=
1446 			kbasep_js_ctx_attr_runpool_release_ctx(kbdev, kctx);
1447 
1448 		/* Releasing the context and katom retained state can allow
1449 		 * more jobs to run */
1450 		release_result |=
1451 			kbasep_js_run_jobs_after_ctx_and_atom_release(kbdev,
1452 						kctx, katom_retained_state,
1453 						runpool_ctx_attr_change);
1454 
1455 		/*
1456 		 * Transaction ends on AS and runpool_irq:
1457 		 *
1458 		 * By this point, the AS-related data is now clear and ready
1459 		 * for re-use.
1460 		 *
1461 		 * Since releases only occur once for each previous successful
1462 		 * retain, and no more retains are allowed on this context, no
1463 		 * other thread will be operating in this
1464 		 * code whilst we are
1465 		 */
1466 
1467 		/* Recalculate pullable status for all slots */
1468 		for (slot = 0; slot < num_slots; slot++) {
1469 			if (kbase_js_ctx_pullable(kctx, slot, false))
1470 				kbase_js_ctx_list_add_pullable_nolock(kbdev,
1471 						kctx, slot);
1472 		}
1473 
1474 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1475 
1476 		kbase_backend_release_ctx_noirq(kbdev, kctx);
1477 
1478 		mutex_unlock(&kbdev->pm.lock);
1479 
1480 		/* Note: Don't reuse kctx_as_nr now */
1481 
1482 		/* Synchronize with any timers */
1483 		kbase_backend_ctx_count_changed(kbdev);
1484 
1485 		/* update book-keeping info */
1486 		kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
1487 		/* Signal any waiter that the context is not scheduled, so is
1488 		 * safe for termination - once the jsctx_mutex is also dropped,
1489 		 * and jobs have finished. */
1490 		wake_up(&js_kctx_info->ctx.is_scheduled_wait);
1491 
1492 		/* Queue an action to occur after we've dropped the lock */
1493 		release_result |= KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED |
1494 			KBASEP_JS_RELEASE_RESULT_SCHED_ALL;
1495 	} else {
1496 		kbasep_js_run_jobs_after_ctx_and_atom_release(kbdev, kctx,
1497 				katom_retained_state, runpool_ctx_attr_change);
1498 
1499 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1500 		mutex_unlock(&kbdev->pm.lock);
1501 	}
1502 
1503 	return release_result;
1504 }
1505 
kbasep_js_runpool_release_ctx_nolock(struct kbase_device *kbdev, struct kbase_context *kctx)1506 void kbasep_js_runpool_release_ctx_nolock(struct kbase_device *kbdev,
1507 						struct kbase_context *kctx)
1508 {
1509 	struct kbasep_js_atom_retained_state katom_retained_state;
1510 
1511 	/* Setup a dummy katom_retained_state */
1512 	kbasep_js_atom_retained_state_init_invalid(&katom_retained_state);
1513 
1514 	kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
1515 							&katom_retained_state);
1516 }
1517 
kbasep_js_runpool_requeue_or_kill_ctx(struct kbase_device *kbdev, struct kbase_context *kctx, bool has_pm_ref)1518 void kbasep_js_runpool_requeue_or_kill_ctx(struct kbase_device *kbdev,
1519 		struct kbase_context *kctx, bool has_pm_ref)
1520 {
1521 	struct kbasep_js_device_data *js_devdata;
1522 
1523 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1524 	KBASE_DEBUG_ASSERT(kctx != NULL);
1525 	js_devdata = &kbdev->js_data;
1526 
1527 	/* This is called if and only if you've you've detached the context from
1528 	 * the Runpool Queue, and not added it back to the Runpool
1529 	 */
1530 	KBASE_DEBUG_ASSERT(!kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1531 
1532 	if (kbase_ctx_flag(kctx, KCTX_DYING)) {
1533 		/* Dying: don't requeue, but kill all jobs on the context. This
1534 		 * happens asynchronously */
1535 		dev_dbg(kbdev->dev,
1536 			"JS: ** Killing Context %p on RunPool Remove **", kctx);
1537 		kbase_js_foreach_ctx_job(kctx, &kbase_jd_cancel);
1538 	}
1539 }
1540 
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)1541 void kbasep_js_runpool_release_ctx_and_katom_retained_state(
1542 		struct kbase_device *kbdev, struct kbase_context *kctx,
1543 		struct kbasep_js_atom_retained_state *katom_retained_state)
1544 {
1545 	struct kbasep_js_device_data *js_devdata;
1546 	struct kbasep_js_kctx_info *js_kctx_info;
1547 	kbasep_js_release_result release_result;
1548 
1549 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1550 	KBASE_DEBUG_ASSERT(kctx != NULL);
1551 	js_kctx_info = &kctx->jctx.sched_info;
1552 	js_devdata = &kbdev->js_data;
1553 
1554 	mutex_lock(&js_devdata->queue_mutex);
1555 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1556 	mutex_lock(&js_devdata->runpool_mutex);
1557 
1558 	release_result = kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
1559 			katom_retained_state);
1560 
1561 	/* Drop the runpool mutex to allow requeing kctx */
1562 	mutex_unlock(&js_devdata->runpool_mutex);
1563 
1564 	if ((release_result & KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED) != 0u)
1565 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, true);
1566 
1567 	/* Drop the jsctx_mutex to allow scheduling in a new context */
1568 
1569 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1570 	mutex_unlock(&js_devdata->queue_mutex);
1571 
1572 	if (release_result & KBASEP_JS_RELEASE_RESULT_SCHED_ALL)
1573 		kbase_js_sched_all(kbdev);
1574 }
1575 
kbasep_js_runpool_release_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1576 void kbasep_js_runpool_release_ctx(struct kbase_device *kbdev,
1577 		struct kbase_context *kctx)
1578 {
1579 	struct kbasep_js_atom_retained_state katom_retained_state;
1580 
1581 	kbasep_js_atom_retained_state_init_invalid(&katom_retained_state);
1582 
1583 	kbasep_js_runpool_release_ctx_and_katom_retained_state(kbdev, kctx,
1584 			&katom_retained_state);
1585 }
1586 
1587 /* Variant of kbasep_js_runpool_release_ctx() that doesn't call into
1588  * kbase_js_sched_all() */
kbasep_js_runpool_release_ctx_no_schedule( struct kbase_device *kbdev, struct kbase_context *kctx)1589 static void kbasep_js_runpool_release_ctx_no_schedule(
1590 		struct kbase_device *kbdev, struct kbase_context *kctx)
1591 {
1592 	struct kbasep_js_device_data *js_devdata;
1593 	struct kbasep_js_kctx_info *js_kctx_info;
1594 	kbasep_js_release_result release_result;
1595 	struct kbasep_js_atom_retained_state katom_retained_state_struct;
1596 	struct kbasep_js_atom_retained_state *katom_retained_state =
1597 		&katom_retained_state_struct;
1598 
1599 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1600 	KBASE_DEBUG_ASSERT(kctx != NULL);
1601 	js_kctx_info = &kctx->jctx.sched_info;
1602 	js_devdata = &kbdev->js_data;
1603 	kbasep_js_atom_retained_state_init_invalid(katom_retained_state);
1604 
1605 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1606 	mutex_lock(&js_devdata->runpool_mutex);
1607 
1608 	release_result = kbasep_js_runpool_release_ctx_internal(kbdev, kctx,
1609 			katom_retained_state);
1610 
1611 	/* Drop the runpool mutex to allow requeing kctx */
1612 	mutex_unlock(&js_devdata->runpool_mutex);
1613 	if ((release_result & KBASEP_JS_RELEASE_RESULT_WAS_DESCHEDULED) != 0u)
1614 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, true);
1615 
1616 	/* Drop the jsctx_mutex to allow scheduling in a new context */
1617 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1618 
1619 	/* NOTE: could return release_result if the caller would like to know
1620 	 * whether it should schedule a new context, but currently no callers do
1621 	 */
1622 }
1623 
kbase_js_set_timeouts(struct kbase_device *kbdev)1624 void kbase_js_set_timeouts(struct kbase_device *kbdev)
1625 {
1626 	lockdep_assert_held(&kbdev->hwaccess_lock);
1627 
1628 	kbase_backend_timeouts_changed(kbdev);
1629 }
1630 
kbasep_js_schedule_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1631 static bool kbasep_js_schedule_ctx(struct kbase_device *kbdev,
1632 					struct kbase_context *kctx)
1633 {
1634 	struct kbasep_js_device_data *js_devdata;
1635 	struct kbasep_js_kctx_info *js_kctx_info;
1636 	struct kbase_as *new_address_space = NULL;
1637 	unsigned long flags;
1638 	bool kctx_suspended = false;
1639 	int as_nr;
1640 
1641 	js_devdata = &kbdev->js_data;
1642 	js_kctx_info = &kctx->jctx.sched_info;
1643 
1644 	/* Pick available address space for this context */
1645 	mutex_lock(&kbdev->mmu_hw_mutex);
1646 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1647 	as_nr = kbase_ctx_sched_retain_ctx(kctx);
1648 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1649 	mutex_unlock(&kbdev->mmu_hw_mutex);
1650 	if (as_nr == KBASEP_AS_NR_INVALID) {
1651 		as_nr = kbase_backend_find_and_release_free_address_space(
1652 				kbdev, kctx);
1653 		if (as_nr != KBASEP_AS_NR_INVALID) {
1654 			/* Attempt to retain the context again, this should
1655 			 * succeed */
1656 			mutex_lock(&kbdev->mmu_hw_mutex);
1657 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1658 			as_nr = kbase_ctx_sched_retain_ctx(kctx);
1659 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1660 			mutex_unlock(&kbdev->mmu_hw_mutex);
1661 
1662 			WARN_ON(as_nr == KBASEP_AS_NR_INVALID);
1663 		}
1664 	}
1665 	if (as_nr == KBASEP_AS_NR_INVALID)
1666 		return false; /* No address spaces currently available */
1667 
1668 	new_address_space = &kbdev->as[as_nr];
1669 
1670 	/*
1671 	 * Atomic transaction on the Context and Run Pool begins
1672 	 */
1673 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1674 	mutex_lock(&js_devdata->runpool_mutex);
1675 	mutex_lock(&kbdev->mmu_hw_mutex);
1676 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1677 
1678 	/* Check to see if context is dying due to kbase_job_zap_context() */
1679 	if (kbase_ctx_flag(kctx, KCTX_DYING)) {
1680 		/* Roll back the transaction so far and return */
1681 		kbase_ctx_sched_release_ctx(kctx);
1682 
1683 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1684 		mutex_unlock(&kbdev->mmu_hw_mutex);
1685 		mutex_unlock(&js_devdata->runpool_mutex);
1686 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1687 
1688 		return false;
1689 	}
1690 
1691 	KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_TRY_SCHEDULE_HEAD_CTX, kctx, NULL,
1692 				0u,
1693 				kbasep_js_trace_get_refcnt(kbdev, kctx));
1694 
1695 	kbase_ctx_flag_set(kctx, KCTX_SCHEDULED);
1696 
1697 	/* Assign context to previously chosen address space */
1698 	if (!kbase_backend_use_ctx(kbdev, kctx, as_nr)) {
1699 		/* Roll back the transaction so far and return */
1700 		kbase_ctx_sched_release_ctx(kctx);
1701 		kbase_ctx_flag_clear(kctx, KCTX_SCHEDULED);
1702 
1703 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1704 		mutex_unlock(&kbdev->mmu_hw_mutex);
1705 		mutex_unlock(&js_devdata->runpool_mutex);
1706 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1707 
1708 		return false;
1709 	}
1710 
1711 	kbdev->hwaccess.active_kctx = kctx;
1712 
1713 #if defined(CONFIG_MALI_GATOR_SUPPORT)
1714 	kbase_trace_mali_mmu_as_in_use(kctx->as_nr);
1715 #endif
1716 	KBASE_TLSTREAM_TL_RET_AS_CTX(&kbdev->as[kctx->as_nr], kctx);
1717 
1718 	/* Cause any future waiter-on-termination to wait until the context is
1719 	 * descheduled */
1720 	wake_up(&js_kctx_info->ctx.is_scheduled_wait);
1721 
1722 	/* Re-check for suspending: a suspend could've occurred, and all the
1723 	 * contexts could've been removed from the runpool before we took this
1724 	 * lock. In this case, we don't want to allow this context to run jobs,
1725 	 * we just want it out immediately.
1726 	 *
1727 	 * The DMB required to read the suspend flag was issued recently as part
1728 	 * of the hwaccess_lock locking. If a suspend occurs *after* that lock
1729 	 * was taken (i.e. this condition doesn't execute), then the
1730 	 * kbasep_js_suspend() code will cleanup this context instead (by virtue
1731 	 * of it being called strictly after the suspend flag is set, and will
1732 	 * wait for this lock to drop) */
1733 	if (kbase_pm_is_suspending(kbdev)) {
1734 		/* Cause it to leave at some later point */
1735 		bool retained;
1736 
1737 		retained = kbasep_js_runpool_retain_ctx_nolock(kbdev, kctx);
1738 		KBASE_DEBUG_ASSERT(retained);
1739 
1740 		kbasep_js_clear_submit_allowed(js_devdata, kctx);
1741 		kctx_suspended = true;
1742 	}
1743 
1744 	/* Transaction complete */
1745 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1746 	mutex_unlock(&kbdev->mmu_hw_mutex);
1747 
1748 	/* Synchronize with any timers */
1749 	kbase_backend_ctx_count_changed(kbdev);
1750 
1751 	mutex_unlock(&js_devdata->runpool_mutex);
1752 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1753 	/* Note: after this point, the context could potentially get scheduled
1754 	 * out immediately */
1755 
1756 	if (kctx_suspended) {
1757 		/* Finishing forcing out the context due to a suspend. Use a
1758 		 * variant of kbasep_js_runpool_release_ctx() that doesn't
1759 		 * schedule a new context, to prevent a risk of recursion back
1760 		 * into this function */
1761 		kbasep_js_runpool_release_ctx_no_schedule(kbdev, kctx);
1762 		return false;
1763 	}
1764 	return true;
1765 }
1766 
kbase_js_use_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1767 static bool kbase_js_use_ctx(struct kbase_device *kbdev,
1768 				struct kbase_context *kctx)
1769 {
1770 	unsigned long flags;
1771 
1772 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1773 
1774 	if (kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
1775 			kbase_backend_use_ctx_sched(kbdev, kctx)) {
1776 		/* Context already has ASID - mark as active */
1777 		kbdev->hwaccess.active_kctx = kctx;
1778 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1779 		return true; /* Context already scheduled */
1780 	}
1781 
1782 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1783 
1784 	return kbasep_js_schedule_ctx(kbdev, kctx);
1785 }
1786 
kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1787 void kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev,
1788 		struct kbase_context *kctx)
1789 {
1790 	struct kbasep_js_kctx_info *js_kctx_info;
1791 	struct kbasep_js_device_data *js_devdata;
1792 	bool is_scheduled;
1793 
1794 	KBASE_DEBUG_ASSERT(kbdev != NULL);
1795 	KBASE_DEBUG_ASSERT(kctx != NULL);
1796 
1797 	js_devdata = &kbdev->js_data;
1798 	js_kctx_info = &kctx->jctx.sched_info;
1799 
1800 	/* This must never be attempted whilst suspending - i.e. it should only
1801 	 * happen in response to a syscall from a user-space thread */
1802 	BUG_ON(kbase_pm_is_suspending(kbdev));
1803 
1804 	mutex_lock(&js_devdata->queue_mutex);
1805 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1806 
1807 	/* Mark the context as privileged */
1808 	kbase_ctx_flag_set(kctx, KCTX_PRIVILEGED);
1809 
1810 	is_scheduled = kbase_ctx_flag(kctx, KCTX_SCHEDULED);
1811 	if (!is_scheduled) {
1812 		/* Add the context to the pullable list */
1813 		if (kbase_js_ctx_list_add_pullable_head(kbdev, kctx, 0))
1814 			kbase_js_sync_timers(kbdev);
1815 
1816 		/* Fast-starting requires the jsctx_mutex to be dropped,
1817 		 * because it works on multiple ctxs */
1818 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1819 		mutex_unlock(&js_devdata->queue_mutex);
1820 
1821 		/* Try to schedule the context in */
1822 		kbase_js_sched_all(kbdev);
1823 
1824 		/* Wait for the context to be scheduled in */
1825 		wait_event(kctx->jctx.sched_info.ctx.is_scheduled_wait,
1826 			   kbase_ctx_flag(kctx, KCTX_SCHEDULED));
1827 	} else {
1828 		/* Already scheduled in - We need to retain it to keep the
1829 		 * corresponding address space */
1830 		kbasep_js_runpool_retain_ctx(kbdev, kctx);
1831 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1832 		mutex_unlock(&js_devdata->queue_mutex);
1833 	}
1834 }
1835 KBASE_EXPORT_TEST_API(kbasep_js_schedule_privileged_ctx);
1836 
kbasep_js_release_privileged_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)1837 void kbasep_js_release_privileged_ctx(struct kbase_device *kbdev,
1838 		struct kbase_context *kctx)
1839 {
1840 	struct kbasep_js_kctx_info *js_kctx_info;
1841 
1842 	KBASE_DEBUG_ASSERT(kctx != NULL);
1843 	js_kctx_info = &kctx->jctx.sched_info;
1844 
1845 	/* We don't need to use the address space anymore */
1846 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1847 	kbase_ctx_flag_clear(kctx, KCTX_PRIVILEGED);
1848 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1849 
1850 	/* Release the context - it will be scheduled out */
1851 	kbasep_js_runpool_release_ctx(kbdev, kctx);
1852 
1853 	kbase_js_sched_all(kbdev);
1854 }
1855 KBASE_EXPORT_TEST_API(kbasep_js_release_privileged_ctx);
1856 
kbasep_js_suspend(struct kbase_device *kbdev)1857 void kbasep_js_suspend(struct kbase_device *kbdev)
1858 {
1859 	unsigned long flags;
1860 	struct kbasep_js_device_data *js_devdata;
1861 	int i;
1862 	u16 retained = 0u;
1863 	int nr_privileged_ctx = 0;
1864 
1865 	KBASE_DEBUG_ASSERT(kbdev);
1866 	KBASE_DEBUG_ASSERT(kbase_pm_is_suspending(kbdev));
1867 	js_devdata = &kbdev->js_data;
1868 
1869 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1870 
1871 	/* Prevent all contexts from submitting */
1872 	js_devdata->runpool_irq.submit_allowed = 0;
1873 
1874 	/* Retain each of the contexts, so we can cause it to leave even if it
1875 	 * had no refcount to begin with */
1876 	for (i = BASE_MAX_NR_AS - 1; i >= 0; --i) {
1877 		struct kbase_context *kctx = kbdev->as_to_kctx[i];
1878 
1879 		retained = retained << 1;
1880 
1881 		if (kctx) {
1882 			kbase_ctx_sched_retain_ctx_refcount(kctx);
1883 			retained |= 1u;
1884 			/* We can only cope with up to 1 privileged context -
1885 			 * the instrumented context. It'll be suspended by
1886 			 * disabling instrumentation */
1887 			if (kbase_ctx_flag(kctx, KCTX_PRIVILEGED)) {
1888 				++nr_privileged_ctx;
1889 				WARN_ON(nr_privileged_ctx != 1);
1890 			}
1891 		}
1892 	}
1893 	CSTD_UNUSED(nr_privileged_ctx);
1894 
1895 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1896 
1897 	/* De-ref the previous retain to ensure each context gets pulled out
1898 	 * sometime later. */
1899 	for (i = 0;
1900 		 i < BASE_MAX_NR_AS;
1901 		 ++i, retained = retained >> 1) {
1902 		struct kbase_context *kctx = kbdev->as_to_kctx[i];
1903 
1904 		if (retained & 1u)
1905 			kbasep_js_runpool_release_ctx(kbdev, kctx);
1906 	}
1907 
1908 	/* Caller must wait for all Power Manager active references to be
1909 	 * dropped */
1910 }
1911 
kbasep_js_resume(struct kbase_device *kbdev)1912 void kbasep_js_resume(struct kbase_device *kbdev)
1913 {
1914 	struct kbasep_js_device_data *js_devdata;
1915 	int js;
1916 
1917 	KBASE_DEBUG_ASSERT(kbdev);
1918 	js_devdata = &kbdev->js_data;
1919 	KBASE_DEBUG_ASSERT(!kbase_pm_is_suspending(kbdev));
1920 
1921 	mutex_lock(&js_devdata->queue_mutex);
1922 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
1923 		struct kbase_context *kctx, *n;
1924 
1925 		list_for_each_entry_safe(kctx, n,
1926 				&kbdev->js_data.ctx_list_unpullable[js],
1927 				jctx.sched_info.ctx.ctx_list_entry[js]) {
1928 			struct kbasep_js_kctx_info *js_kctx_info;
1929 			unsigned long flags;
1930 			bool timer_sync = false;
1931 
1932 			js_kctx_info = &kctx->jctx.sched_info;
1933 
1934 			mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
1935 			mutex_lock(&js_devdata->runpool_mutex);
1936 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
1937 
1938 			if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
1939 				kbase_js_ctx_pullable(kctx, js, false))
1940 				timer_sync =
1941 					kbase_js_ctx_list_add_pullable_nolock(
1942 							kbdev, kctx, js);
1943 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
1944 			if (timer_sync)
1945 				kbase_backend_ctx_count_changed(kbdev);
1946 			mutex_unlock(&js_devdata->runpool_mutex);
1947 			mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
1948 		}
1949 	}
1950 	mutex_unlock(&js_devdata->queue_mutex);
1951 
1952 	/* Restart atom processing */
1953 	kbase_js_sched_all(kbdev);
1954 
1955 	/* JS Resume complete */
1956 }
1957 
kbase_js_is_atom_valid(struct kbase_device *kbdev, struct kbase_jd_atom *katom)1958 bool kbase_js_is_atom_valid(struct kbase_device *kbdev,
1959 				struct kbase_jd_atom *katom)
1960 {
1961 	if ((katom->core_req & BASE_JD_REQ_FS) &&
1962 	    (katom->core_req & (BASE_JD_REQ_CS | BASE_JD_REQ_ONLY_COMPUTE |
1963 								BASE_JD_REQ_T)))
1964 		return false;
1965 
1966 	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8987) &&
1967 	    (katom->core_req & BASE_JD_REQ_ONLY_COMPUTE) &&
1968 	    (katom->core_req & (BASE_JD_REQ_CS | BASE_JD_REQ_T)))
1969 		return false;
1970 
1971 	return true;
1972 }
1973 
kbase_js_get_slot(struct kbase_device *kbdev, struct kbase_jd_atom *katom)1974 static int kbase_js_get_slot(struct kbase_device *kbdev,
1975 				struct kbase_jd_atom *katom)
1976 {
1977 	if (katom->core_req & BASE_JD_REQ_FS)
1978 		return 0;
1979 
1980 	if (katom->core_req & BASE_JD_REQ_ONLY_COMPUTE) {
1981 		if (katom->device_nr == 1 &&
1982 				kbdev->gpu_props.num_core_groups == 2)
1983 			return 2;
1984 		if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8987))
1985 			return 2;
1986 	}
1987 
1988 	return 1;
1989 }
1990 
kbase_js_dep_resolved_submit(struct kbase_context *kctx, struct kbase_jd_atom *katom)1991 bool kbase_js_dep_resolved_submit(struct kbase_context *kctx,
1992 					struct kbase_jd_atom *katom)
1993 {
1994 	bool enqueue_required;
1995 
1996 	katom->slot_nr = kbase_js_get_slot(kctx->kbdev, katom);
1997 
1998 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
1999 	lockdep_assert_held(&kctx->jctx.lock);
2000 
2001 	/* If slot will transition from unpullable to pullable then add to
2002 	 * pullable list */
2003 	if (jsctx_rb_none_to_pull(kctx, katom->slot_nr)) {
2004 		enqueue_required = true;
2005 	} else {
2006 		enqueue_required = false;
2007 	}
2008 	if ((katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) ||
2009 			(katom->pre_dep && (katom->pre_dep->atom_flags &
2010 			KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST))) {
2011 		int prio = katom->sched_priority;
2012 		int js = katom->slot_nr;
2013 		struct jsctx_queue *queue = &kctx->jsctx_queue[prio][js];
2014 
2015 		list_add_tail(&katom->queue, &queue->x_dep_head);
2016 		katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
2017 		enqueue_required = false;
2018 	} else {
2019 		/* Check if there are lower priority jobs to soft stop */
2020 		kbase_job_slot_ctx_priority_check_locked(kctx, katom);
2021 
2022 		/* Add atom to ring buffer. */
2023 		jsctx_tree_add(kctx, katom);
2024 		katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_TREE;
2025 	}
2026 
2027 	return enqueue_required;
2028 }
2029 
2030 /**
2031  * kbase_js_move_to_tree - Move atom (and any dependent atoms) to the
2032  *                         runnable_tree, ready for execution
2033  * @katom: Atom to submit
2034  *
2035  * It is assumed that @katom does not have KBASE_KATOM_FLAG_X_DEP_BLOCKED set,
2036  * but is still present in the x_dep list. If @katom has a same-slot dependent
2037  * atom then that atom (and any dependents) will also be moved.
2038  */
kbase_js_move_to_tree(struct kbase_jd_atom *katom)2039 static void kbase_js_move_to_tree(struct kbase_jd_atom *katom)
2040 {
2041 	lockdep_assert_held(&katom->kctx->kbdev->hwaccess_lock);
2042 
2043 	while (katom) {
2044 		WARN_ON(!(katom->atom_flags &
2045 				KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST));
2046 
2047 		if (!(katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED)) {
2048 			list_del(&katom->queue);
2049 			katom->atom_flags &=
2050 					~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
2051 			jsctx_tree_add(katom->kctx, katom);
2052 			katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_TREE;
2053 		} else {
2054 			break;
2055 		}
2056 
2057 		katom = katom->post_dep;
2058 	}
2059 }
2060 
2061 
2062 /**
2063  * kbase_js_evict_deps - Evict dependencies of a failed atom.
2064  * @kctx:       Context pointer
2065  * @katom:      Pointer to the atom that has failed.
2066  * @js:         The job slot the katom was run on.
2067  * @prio:       Priority of the katom.
2068  *
2069  * Remove all post dependencies of an atom from the context ringbuffers.
2070  *
2071  * The original atom's event_code will be propogated to all dependent atoms.
2072  *
2073  * Context: Caller must hold the HW access lock
2074  */
kbase_js_evict_deps(struct kbase_context *kctx, struct kbase_jd_atom *katom, int js, int prio)2075 static void kbase_js_evict_deps(struct kbase_context *kctx,
2076 				struct kbase_jd_atom *katom, int js, int prio)
2077 {
2078 	struct kbase_jd_atom *x_dep = katom->x_post_dep;
2079 	struct kbase_jd_atom *next_katom = katom->post_dep;
2080 
2081 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2082 
2083 	if (next_katom) {
2084 		KBASE_DEBUG_ASSERT(next_katom->status !=
2085 				KBASE_JD_ATOM_STATE_HW_COMPLETED);
2086 		next_katom->will_fail_event_code = katom->event_code;
2087 
2088 	}
2089 
2090 	/* Has cross slot depenency. */
2091 	if (x_dep && (x_dep->atom_flags & (KBASE_KATOM_FLAG_JSCTX_IN_TREE |
2092 				KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST))) {
2093 		/* Remove dependency.*/
2094 		x_dep->atom_flags &= ~KBASE_KATOM_FLAG_X_DEP_BLOCKED;
2095 
2096 		/* Fail if it had a data dependency. */
2097 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) {
2098 			x_dep->will_fail_event_code = katom->event_code;
2099 		}
2100 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST)
2101 			kbase_js_move_to_tree(x_dep);
2102 	}
2103 }
2104 
kbase_js_pull(struct kbase_context *kctx, int js)2105 struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, int js)
2106 {
2107 	struct kbase_jd_atom *katom;
2108 	struct kbasep_js_device_data *js_devdata;
2109 	struct kbase_device *kbdev;
2110 	int pulled;
2111 
2112 	KBASE_DEBUG_ASSERT(kctx);
2113 
2114 	kbdev = kctx->kbdev;
2115 
2116 	js_devdata = &kbdev->js_data;
2117 	lockdep_assert_held(&kbdev->hwaccess_lock);
2118 
2119 	if (!kbasep_js_is_submit_allowed(js_devdata, kctx))
2120 		return NULL;
2121 	if (kbase_pm_is_suspending(kbdev))
2122 		return NULL;
2123 
2124 	katom = jsctx_rb_peek(kctx, js);
2125 	if (!katom)
2126 		return NULL;
2127 	if (kctx->blocked_js[js][katom->sched_priority])
2128 		return NULL;
2129 	if (atomic_read(&katom->blocked))
2130 		return NULL;
2131 
2132 	/* Due to ordering restrictions when unpulling atoms on failure, we do
2133 	 * not allow multiple runs of fail-dep atoms from the same context to be
2134 	 * present on the same slot */
2135 	if (katom->pre_dep && atomic_read(&kctx->atoms_pulled_slot[js])) {
2136 		struct kbase_jd_atom *prev_atom =
2137 				kbase_backend_inspect_tail(kbdev, js);
2138 
2139 		if (prev_atom && prev_atom->kctx != kctx)
2140 			return NULL;
2141 	}
2142 
2143 	if (katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) {
2144 		if (katom->x_pre_dep->gpu_rb_state ==
2145 					KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
2146 					katom->x_pre_dep->will_fail_event_code)
2147 			return NULL;
2148 		if ((katom->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER) &&
2149 				kbase_backend_nr_atoms_on_slot(kbdev, js))
2150 			return NULL;
2151 	}
2152 
2153 	kbase_ctx_flag_set(kctx, KCTX_PULLED);
2154 
2155 	pulled = atomic_inc_return(&kctx->atoms_pulled);
2156 	if (pulled == 1 && !kctx->slots_pullable) {
2157 		WARN_ON(kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
2158 		kbase_ctx_flag_set(kctx, KCTX_RUNNABLE_REF);
2159 		atomic_inc(&kbdev->js_data.nr_contexts_runnable);
2160 	}
2161 	atomic_inc(&kctx->atoms_pulled_slot[katom->slot_nr]);
2162 	kctx->atoms_pulled_slot_pri[katom->slot_nr][katom->sched_priority]++;
2163 	jsctx_rb_pull(kctx, katom);
2164 
2165 	kbasep_js_runpool_retain_ctx_nolock(kbdev, kctx);
2166 
2167 	katom->atom_flags |= KBASE_KATOM_FLAG_HOLDING_CTX_REF;
2168 
2169 	katom->ticks = 0;
2170 
2171 	return katom;
2172 }
2173 
2174 
js_return_worker(struct work_struct *data)2175 static void js_return_worker(struct work_struct *data)
2176 {
2177 	struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom,
2178 									work);
2179 	struct kbase_context *kctx = katom->kctx;
2180 	struct kbase_device *kbdev = kctx->kbdev;
2181 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
2182 	struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
2183 	struct kbasep_js_atom_retained_state retained_state;
2184 	int js = katom->slot_nr;
2185 	int prio = katom->sched_priority;
2186 	bool timer_sync = false;
2187 	bool context_idle = false;
2188 	unsigned long flags;
2189 	base_jd_core_req core_req = katom->core_req;
2190 	u64 affinity = katom->affinity;
2191 	enum kbase_atom_coreref_state coreref_state = katom->coreref_state;
2192 
2193 	KBASE_TLSTREAM_TL_EVENT_ATOM_SOFTSTOP_EX(katom);
2194 
2195 	kbase_backend_complete_wq(kbdev, katom);
2196 
2197 	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8316))
2198 		kbase_as_poking_timer_release_atom(kbdev, kctx, katom);
2199 
2200 	kbasep_js_atom_retained_state_copy(&retained_state, katom);
2201 
2202 	mutex_lock(&js_devdata->queue_mutex);
2203 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2204 
2205 	atomic_dec(&kctx->atoms_pulled);
2206 	atomic_dec(&kctx->atoms_pulled_slot[js]);
2207 
2208 	atomic_dec(&katom->blocked);
2209 
2210 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2211 
2212 	kctx->atoms_pulled_slot_pri[js][katom->sched_priority]--;
2213 
2214 	if (!atomic_read(&kctx->atoms_pulled_slot[js]) &&
2215 			jsctx_rb_none_to_pull(kctx, js))
2216 		timer_sync |= kbase_js_ctx_list_remove_nolock(kbdev, kctx, js);
2217 
2218 	/* If this slot has been blocked due to soft-stopped atoms, and all
2219 	 * atoms have now been processed, then unblock the slot */
2220 	if (!kctx->atoms_pulled_slot_pri[js][prio] &&
2221 			kctx->blocked_js[js][prio]) {
2222 		kctx->blocked_js[js][prio] = false;
2223 
2224 		/* Only mark the slot as pullable if the context is not idle -
2225 		 * that case is handled below */
2226 		if (atomic_read(&kctx->atoms_pulled) &&
2227 				kbase_js_ctx_pullable(kctx, js, true))
2228 			timer_sync |= kbase_js_ctx_list_add_pullable_nolock(
2229 					kbdev, kctx, js);
2230 	}
2231 
2232 	if (!atomic_read(&kctx->atoms_pulled)) {
2233 		if (!kctx->slots_pullable) {
2234 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
2235 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
2236 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
2237 			timer_sync = true;
2238 		}
2239 
2240 		if (kctx->as_nr != KBASEP_AS_NR_INVALID &&
2241 				!kbase_ctx_flag(kctx, KCTX_DYING)) {
2242 			int num_slots = kbdev->gpu_props.num_job_slots;
2243 			int slot;
2244 
2245 			if (!kbasep_js_is_submit_allowed(js_devdata, kctx))
2246 				kbasep_js_set_submit_allowed(js_devdata, kctx);
2247 
2248 			for (slot = 0; slot < num_slots; slot++) {
2249 				if (kbase_js_ctx_pullable(kctx, slot, true))
2250 					timer_sync |=
2251 					kbase_js_ctx_list_add_pullable_nolock(
2252 							kbdev, kctx, slot);
2253 			}
2254 		}
2255 
2256 		kbase_jm_idle_ctx(kbdev, kctx);
2257 
2258 		context_idle = true;
2259 	}
2260 
2261 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2262 
2263 	if (context_idle) {
2264 		WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
2265 		kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
2266 		kbase_pm_context_idle(kbdev);
2267 	}
2268 
2269 	if (timer_sync)
2270 		kbase_js_sync_timers(kbdev);
2271 
2272 	mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2273 	mutex_unlock(&js_devdata->queue_mutex);
2274 
2275 	katom->atom_flags &= ~KBASE_KATOM_FLAG_HOLDING_CTX_REF;
2276 	kbasep_js_runpool_release_ctx_and_katom_retained_state(kbdev, kctx,
2277 							&retained_state);
2278 
2279 	kbase_js_sched_all(kbdev);
2280 
2281 	kbase_backend_complete_wq_post_sched(kbdev, core_req, affinity,
2282 			coreref_state);
2283 }
2284 
kbase_js_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)2285 void kbase_js_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
2286 {
2287 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2288 
2289 	jsctx_rb_unpull(kctx, katom);
2290 
2291 	WARN_ON(work_pending(&katom->work));
2292 
2293 	/* Block re-submission until workqueue has run */
2294 	atomic_inc(&katom->blocked);
2295 
2296 	kbase_job_check_leave_disjoint(kctx->kbdev, katom);
2297 
2298 	KBASE_DEBUG_ASSERT(0 == object_is_on_stack(&katom->work));
2299 	INIT_WORK(&katom->work, js_return_worker);
2300 	queue_work(kctx->jctx.job_done_wq, &katom->work);
2301 }
2302 
kbase_js_complete_atom_wq(struct kbase_context *kctx, struct kbase_jd_atom *katom)2303 bool kbase_js_complete_atom_wq(struct kbase_context *kctx,
2304 						struct kbase_jd_atom *katom)
2305 {
2306 	struct kbasep_js_kctx_info *js_kctx_info;
2307 	struct kbasep_js_device_data *js_devdata;
2308 	struct kbase_device *kbdev;
2309 	unsigned long flags;
2310 	bool timer_sync = false;
2311 	int atom_slot;
2312 	bool context_idle = false;
2313 	int prio = katom->sched_priority;
2314 
2315 	kbdev = kctx->kbdev;
2316 	atom_slot = katom->slot_nr;
2317 
2318 	js_kctx_info = &kctx->jctx.sched_info;
2319 	js_devdata = &kbdev->js_data;
2320 
2321 	lockdep_assert_held(&js_kctx_info->ctx.jsctx_mutex);
2322 
2323 	mutex_lock(&js_devdata->runpool_mutex);
2324 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2325 
2326 	if (katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE) {
2327 		context_idle = !atomic_dec_return(&kctx->atoms_pulled);
2328 		atomic_dec(&kctx->atoms_pulled_slot[atom_slot]);
2329 		kctx->atoms_pulled_slot_pri[atom_slot][prio]--;
2330 
2331 		if (!atomic_read(&kctx->atoms_pulled) &&
2332 				!kctx->slots_pullable) {
2333 			WARN_ON(!kbase_ctx_flag(kctx, KCTX_RUNNABLE_REF));
2334 			kbase_ctx_flag_clear(kctx, KCTX_RUNNABLE_REF);
2335 			atomic_dec(&kbdev->js_data.nr_contexts_runnable);
2336 			timer_sync = true;
2337 		}
2338 
2339 		/* If this slot has been blocked due to soft-stopped atoms, and
2340 		 * all atoms have now been processed, then unblock the slot */
2341 		if (!kctx->atoms_pulled_slot_pri[atom_slot][prio]
2342 				&& kctx->blocked_js[atom_slot][prio]) {
2343 			kctx->blocked_js[atom_slot][prio] = false;
2344 			if (kbase_js_ctx_pullable(kctx, atom_slot, true))
2345 				timer_sync |=
2346 					kbase_js_ctx_list_add_pullable_nolock(
2347 						kbdev, kctx, atom_slot);
2348 		}
2349 	}
2350 	WARN_ON(!(katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE));
2351 
2352 	if (!atomic_read(&kctx->atoms_pulled_slot[atom_slot]) &&
2353 			jsctx_rb_none_to_pull(kctx, atom_slot)) {
2354 		if (!list_empty(
2355 			&kctx->jctx.sched_info.ctx.ctx_list_entry[atom_slot]))
2356 			timer_sync |= kbase_js_ctx_list_remove_nolock(
2357 					kctx->kbdev, kctx, atom_slot);
2358 	}
2359 
2360 	/*
2361 	 * If submission is disabled on this context (most likely due to an
2362 	 * atom failure) and there are now no atoms left in the system then
2363 	 * re-enable submission so that context can be scheduled again.
2364 	 */
2365 	if (!kbasep_js_is_submit_allowed(js_devdata, kctx) &&
2366 					!atomic_read(&kctx->atoms_pulled) &&
2367 					!kbase_ctx_flag(kctx, KCTX_DYING)) {
2368 		int js;
2369 
2370 		kbasep_js_set_submit_allowed(js_devdata, kctx);
2371 
2372 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
2373 			if (kbase_js_ctx_pullable(kctx, js, true))
2374 				timer_sync |=
2375 					kbase_js_ctx_list_add_pullable_nolock(
2376 							kbdev, kctx, js);
2377 		}
2378 	} else if (katom->x_post_dep &&
2379 			kbasep_js_is_submit_allowed(js_devdata, kctx)) {
2380 		int js;
2381 
2382 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
2383 			if (kbase_js_ctx_pullable(kctx, js, true))
2384 				timer_sync |=
2385 					kbase_js_ctx_list_add_pullable_nolock(
2386 							kbdev, kctx, js);
2387 		}
2388 	}
2389 
2390 	/* Mark context as inactive. The pm reference will be dropped later in
2391 	 * jd_done_worker().
2392 	 */
2393 	if (context_idle)
2394 		kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
2395 
2396 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2397 	if (timer_sync)
2398 		kbase_backend_ctx_count_changed(kbdev);
2399 	mutex_unlock(&js_devdata->runpool_mutex);
2400 
2401 	return context_idle;
2402 }
2403 
kbase_js_complete_atom(struct kbase_jd_atom *katom, ktime_t *end_timestamp)2404 struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom,
2405 		ktime_t *end_timestamp)
2406 {
2407 	u64 microseconds_spent = 0;
2408 	struct kbase_device *kbdev;
2409 	struct kbase_context *kctx = katom->kctx;
2410 	struct kbase_jd_atom *x_dep = katom->x_post_dep;
2411 
2412 	kbdev = kctx->kbdev;
2413 
2414 
2415 	lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
2416 
2417 	if (katom->will_fail_event_code)
2418 		katom->event_code = katom->will_fail_event_code;
2419 
2420 	katom->status = KBASE_JD_ATOM_STATE_HW_COMPLETED;
2421 
2422 	if (katom->event_code != BASE_JD_EVENT_DONE) {
2423 		kbase_js_evict_deps(kctx, katom, katom->slot_nr,
2424 				katom->sched_priority);
2425 	}
2426 
2427 #if defined(CONFIG_MALI_GATOR_SUPPORT)
2428 	kbase_trace_mali_job_slots_event(GATOR_MAKE_EVENT(GATOR_JOB_SLOT_STOP,
2429 				katom->slot_nr), NULL, 0);
2430 #endif
2431 
2432 	/* Calculate the job's time used */
2433 	if (end_timestamp != NULL) {
2434 		/* Only calculating it for jobs that really run on the HW (e.g.
2435 		 * removed from next jobs never actually ran, so really did take
2436 		 * zero time) */
2437 		ktime_t tick_diff = ktime_sub(*end_timestamp,
2438 							katom->start_timestamp);
2439 
2440 		microseconds_spent = ktime_to_ns(tick_diff);
2441 
2442 		do_div(microseconds_spent, 1000);
2443 
2444 		/* Round up time spent to the minimum timer resolution */
2445 		if (microseconds_spent < KBASEP_JS_TICK_RESOLUTION_US)
2446 			microseconds_spent = KBASEP_JS_TICK_RESOLUTION_US;
2447 	}
2448 
2449 
2450 	kbase_jd_done(katom, katom->slot_nr, end_timestamp, 0);
2451 
2452 	/* Unblock cross dependency if present */
2453 	if (x_dep && (katom->event_code == BASE_JD_EVENT_DONE ||
2454 			!(x_dep->atom_flags & KBASE_KATOM_FLAG_FAIL_BLOCKER)) &&
2455 			(x_dep->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED)) {
2456 		bool was_pullable = kbase_js_ctx_pullable(kctx, x_dep->slot_nr,
2457 				false);
2458 		x_dep->atom_flags &= ~KBASE_KATOM_FLAG_X_DEP_BLOCKED;
2459 		kbase_js_move_to_tree(x_dep);
2460 		if (!was_pullable && kbase_js_ctx_pullable(kctx, x_dep->slot_nr,
2461 				false))
2462 			kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx,
2463 					x_dep->slot_nr);
2464 
2465 		if (x_dep->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE)
2466 			return x_dep;
2467 	}
2468 
2469 	return NULL;
2470 }
2471 
kbase_js_sched(struct kbase_device *kbdev, int js_mask)2472 void kbase_js_sched(struct kbase_device *kbdev, int js_mask)
2473 {
2474 	struct kbasep_js_device_data *js_devdata;
2475 	struct kbase_context *last_active;
2476 	bool timer_sync = false;
2477 	bool ctx_waiting = false;
2478 
2479 	js_devdata = &kbdev->js_data;
2480 
2481 	down(&js_devdata->schedule_sem);
2482 	mutex_lock(&js_devdata->queue_mutex);
2483 
2484 	last_active = kbdev->hwaccess.active_kctx;
2485 
2486 	while (js_mask) {
2487 		int js;
2488 
2489 		js = ffs(js_mask) - 1;
2490 
2491 		while (1) {
2492 			struct kbase_context *kctx;
2493 			unsigned long flags;
2494 			bool context_idle = false;
2495 
2496 			kctx = kbase_js_ctx_list_pop_head(kbdev, js);
2497 
2498 			if (!kctx) {
2499 				js_mask &= ~(1 << js);
2500 				break; /* No contexts on pullable list */
2501 			}
2502 
2503 			if (!kbase_ctx_flag(kctx, KCTX_ACTIVE)) {
2504 				context_idle = true;
2505 
2506 				if (kbase_pm_context_active_handle_suspend(
2507 									kbdev,
2508 				      KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
2509 					/* Suspend pending - return context to
2510 					 * queue and stop scheduling */
2511 					mutex_lock(
2512 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
2513 					if (kbase_js_ctx_list_add_pullable_head(
2514 						kctx->kbdev, kctx, js))
2515 						kbase_js_sync_timers(kbdev);
2516 					mutex_unlock(
2517 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
2518 					mutex_unlock(&js_devdata->queue_mutex);
2519 					up(&js_devdata->schedule_sem);
2520 					return;
2521 				}
2522 				kbase_ctx_flag_set(kctx, KCTX_ACTIVE);
2523 			}
2524 
2525 			if (!kbase_js_use_ctx(kbdev, kctx)) {
2526 				mutex_lock(
2527 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
2528 				/* Context can not be used at this time */
2529 				spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2530 				if (kbase_js_ctx_pullable(kctx, js, false)
2531 				    || kbase_ctx_flag(kctx, KCTX_PRIVILEGED))
2532 					timer_sync |=
2533 					kbase_js_ctx_list_add_pullable_head_nolock(
2534 							kctx->kbdev, kctx, js);
2535 				else
2536 					timer_sync |=
2537 					kbase_js_ctx_list_add_unpullable_nolock(
2538 							kctx->kbdev, kctx, js);
2539 				spin_unlock_irqrestore(&kbdev->hwaccess_lock,
2540 						flags);
2541 				mutex_unlock(
2542 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
2543 				if (context_idle) {
2544 					WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
2545 					kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
2546 					kbase_pm_context_idle(kbdev);
2547 				}
2548 
2549 				/* No more jobs can be submitted on this slot */
2550 				js_mask &= ~(1 << js);
2551 				break;
2552 			}
2553 			mutex_lock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
2554 			spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2555 
2556 			kbase_ctx_flag_clear(kctx, KCTX_PULLED);
2557 
2558 			if (!kbase_jm_kick(kbdev, 1 << js))
2559 				/* No more jobs can be submitted on this slot */
2560 				js_mask &= ~(1 << js);
2561 
2562 			if (!kbase_ctx_flag(kctx, KCTX_PULLED)) {
2563 				bool pullable = kbase_js_ctx_pullable(kctx, js,
2564 						true);
2565 
2566 				/* Failed to pull jobs - push to head of list.
2567 				 * Unless this context is already 'active', in
2568 				 * which case it's effectively already scheduled
2569 				 * so push it to the back of the list. */
2570 				if (pullable && kctx == last_active)
2571 					timer_sync |=
2572 					kbase_js_ctx_list_add_pullable_nolock(
2573 							kctx->kbdev,
2574 							kctx, js);
2575 				else if (pullable)
2576 					timer_sync |=
2577 					kbase_js_ctx_list_add_pullable_head_nolock(
2578 							kctx->kbdev,
2579 							kctx, js);
2580 				else
2581 					timer_sync |=
2582 					kbase_js_ctx_list_add_unpullable_nolock(
2583 								kctx->kbdev,
2584 								kctx, js);
2585 
2586 				/* If this context is not the active context,
2587 				 * but the active context is pullable on this
2588 				 * slot, then we need to remove the active
2589 				 * marker to prevent it from submitting atoms in
2590 				 * the IRQ handler, which would prevent this
2591 				 * context from making progress. */
2592 				if (last_active && kctx != last_active &&
2593 						kbase_js_ctx_pullable(
2594 						last_active, js, true))
2595 					ctx_waiting = true;
2596 
2597 				if (context_idle) {
2598 					kbase_jm_idle_ctx(kbdev, kctx);
2599 					spin_unlock_irqrestore(
2600 							&kbdev->hwaccess_lock,
2601 							flags);
2602 					WARN_ON(!kbase_ctx_flag(kctx, KCTX_ACTIVE));
2603 					kbase_ctx_flag_clear(kctx, KCTX_ACTIVE);
2604 					kbase_pm_context_idle(kbdev);
2605 				} else {
2606 					spin_unlock_irqrestore(
2607 							&kbdev->hwaccess_lock,
2608 							flags);
2609 				}
2610 				mutex_unlock(
2611 					&kctx->jctx.sched_info.ctx.jsctx_mutex);
2612 
2613 				js_mask &= ~(1 << js);
2614 				break; /* Could not run atoms on this slot */
2615 			}
2616 
2617 			/* Push to back of list */
2618 			if (kbase_js_ctx_pullable(kctx, js, true))
2619 				timer_sync |=
2620 					kbase_js_ctx_list_add_pullable_nolock(
2621 							kctx->kbdev, kctx, js);
2622 			else
2623 				timer_sync |=
2624 					kbase_js_ctx_list_add_unpullable_nolock(
2625 							kctx->kbdev, kctx, js);
2626 
2627 			spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2628 			mutex_unlock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
2629 		}
2630 	}
2631 
2632 	if (timer_sync)
2633 		kbase_js_sync_timers(kbdev);
2634 
2635 	if (kbdev->hwaccess.active_kctx == last_active && ctx_waiting)
2636 		kbdev->hwaccess.active_kctx = NULL;
2637 
2638 	mutex_unlock(&js_devdata->queue_mutex);
2639 	up(&js_devdata->schedule_sem);
2640 }
2641 
kbase_js_zap_context(struct kbase_context *kctx)2642 void kbase_js_zap_context(struct kbase_context *kctx)
2643 {
2644 	struct kbase_device *kbdev = kctx->kbdev;
2645 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
2646 	struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
2647 	int js;
2648 
2649 	/*
2650 	 * Critical assumption: No more submission is possible outside of the
2651 	 * workqueue. This is because the OS *must* prevent U/K calls (IOCTLs)
2652 	 * whilst the struct kbase_context is terminating.
2653 	 */
2654 
2655 	/* First, atomically do the following:
2656 	 * - mark the context as dying
2657 	 * - try to evict it from the queue */
2658 	mutex_lock(&kctx->jctx.lock);
2659 	mutex_lock(&js_devdata->queue_mutex);
2660 	mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
2661 	kbase_ctx_flag_set(kctx, KCTX_DYING);
2662 
2663 	dev_dbg(kbdev->dev, "Zap: Try Evict Ctx %p", kctx);
2664 
2665 	/*
2666 	 * At this point we know:
2667 	 * - If eviction succeeded, it was in the queue, but now no
2668 	 *   longer is
2669 	 *  - We must cancel the jobs here. No Power Manager active reference to
2670 	 *    release.
2671 	 *  - This happens asynchronously - kbase_jd_zap_context() will wait for
2672 	 *    those jobs to be killed.
2673 	 * - If eviction failed, then it wasn't in the queue. It is one
2674 	 *   of the following:
2675 	 *  - a. it didn't have any jobs, and so is not in the Queue or
2676 	 *       the Run Pool (not scheduled)
2677 	 *   - Hence, no more work required to cancel jobs. No Power Manager
2678 	 *     active reference to release.
2679 	 *  - b. it was in the middle of a scheduling transaction (and thus must
2680 	 *       have at least 1 job). This can happen from a syscall or a
2681 	 *       kernel thread. We still hold the jsctx_mutex, and so the thread
2682 	 *       must be waiting inside kbasep_js_try_schedule_head_ctx(),
2683 	 *       before checking whether the runpool is full. That thread will
2684 	 *       continue after we drop the mutex, and will notice the context
2685 	 *       is dying. It will rollback the transaction, killing all jobs at
2686 	 *       the same time. kbase_jd_zap_context() will wait for those jobs
2687 	 *       to be killed.
2688 	 *   - Hence, no more work required to cancel jobs, or to release the
2689 	 *     Power Manager active reference.
2690 	 *  - c. it is scheduled, and may or may not be running jobs
2691 	 * - We must cause it to leave the runpool by stopping it from
2692 	 * submitting any more jobs. When it finally does leave,
2693 	 * kbasep_js_runpool_requeue_or_kill_ctx() will kill all remaining jobs
2694 	 * (because it is dying), release the Power Manager active reference,
2695 	 * and will not requeue the context in the queue.
2696 	 * kbase_jd_zap_context() will wait for those jobs to be killed.
2697 	 *  - Hence, work required just to make it leave the runpool. Cancelling
2698 	 *    jobs and releasing the Power manager active reference will be
2699 	 *    handled when it leaves the runpool.
2700 	 */
2701 	if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED)) {
2702 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
2703 			if (!list_empty(
2704 				&kctx->jctx.sched_info.ctx.ctx_list_entry[js]))
2705 				list_del_init(
2706 				&kctx->jctx.sched_info.ctx.ctx_list_entry[js]);
2707 		}
2708 
2709 		/* The following events require us to kill off remaining jobs
2710 		 * and update PM book-keeping:
2711 		 * - we evicted it correctly (it must have jobs to be in the
2712 		 *   Queue)
2713 		 *
2714 		 * These events need no action, but take this path anyway:
2715 		 * - Case a: it didn't have any jobs, and was never in the Queue
2716 		 * - Case b: scheduling transaction will be partially rolled-
2717 		 *           back (this already cancels the jobs)
2718 		 */
2719 
2720 		KBASE_TRACE_ADD(kbdev, JM_ZAP_NON_SCHEDULED, kctx, NULL, 0u,
2721 						kbase_ctx_flag(kctx, KCTX_SCHEDULED));
2722 
2723 		dev_dbg(kbdev->dev, "Zap: Ctx %p scheduled=0", kctx);
2724 
2725 		/* Only cancel jobs when we evicted from the
2726 		 * queue. No Power Manager active reference was held.
2727 		 *
2728 		 * Having is_dying set ensures that this kills, and
2729 		 * doesn't requeue */
2730 		kbasep_js_runpool_requeue_or_kill_ctx(kbdev, kctx, false);
2731 
2732 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2733 		mutex_unlock(&js_devdata->queue_mutex);
2734 		mutex_unlock(&kctx->jctx.lock);
2735 	} else {
2736 		unsigned long flags;
2737 		bool was_retained;
2738 
2739 		/* Case c: didn't evict, but it is scheduled - it's in the Run
2740 		 * Pool */
2741 		KBASE_TRACE_ADD(kbdev, JM_ZAP_SCHEDULED, kctx, NULL, 0u,
2742 						kbase_ctx_flag(kctx, KCTX_SCHEDULED));
2743 		dev_dbg(kbdev->dev, "Zap: Ctx %p is in RunPool", kctx);
2744 
2745 		/* Disable the ctx from submitting any more jobs */
2746 		spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2747 
2748 		kbasep_js_clear_submit_allowed(js_devdata, kctx);
2749 
2750 		/* Retain and (later) release the context whilst it is is now
2751 		 * disallowed from submitting jobs - ensures that someone
2752 		 * somewhere will be removing the context later on */
2753 		was_retained = kbasep_js_runpool_retain_ctx_nolock(kbdev, kctx);
2754 
2755 		/* Since it's scheduled and we have the jsctx_mutex, it must be
2756 		 * retained successfully */
2757 		KBASE_DEBUG_ASSERT(was_retained);
2758 
2759 		dev_dbg(kbdev->dev, "Zap: Ctx %p Kill Any Running jobs", kctx);
2760 
2761 		/* Cancel any remaining running jobs for this kctx - if any.
2762 		 * Submit is disallowed which takes effect immediately, so no
2763 		 * more new jobs will appear after we do this. */
2764 		for (js = 0; js < kbdev->gpu_props.num_job_slots; js++)
2765 			kbase_job_slot_hardstop(kctx, js, NULL);
2766 
2767 		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2768 		mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
2769 		mutex_unlock(&js_devdata->queue_mutex);
2770 		mutex_unlock(&kctx->jctx.lock);
2771 
2772 		dev_dbg(kbdev->dev, "Zap: Ctx %p Release (may or may not schedule out immediately)",
2773 									kctx);
2774 
2775 		kbasep_js_runpool_release_ctx(kbdev, kctx);
2776 	}
2777 
2778 	KBASE_TRACE_ADD(kbdev, JM_ZAP_DONE, kctx, NULL, 0u, 0u);
2779 
2780 	/* After this, you must wait on both the
2781 	 * kbase_jd_context::zero_jobs_wait and the
2782 	 * kbasep_js_kctx_info::ctx::is_scheduled_waitq - to wait for the jobs
2783 	 * to be destroyed, and the context to be de-scheduled (if it was on the
2784 	 * runpool).
2785 	 *
2786 	 * kbase_jd_zap_context() will do this. */
2787 }
2788 
trace_get_refcnt(struct kbase_device *kbdev, struct kbase_context *kctx)2789 static inline int trace_get_refcnt(struct kbase_device *kbdev,
2790 					struct kbase_context *kctx)
2791 {
2792 	return atomic_read(&kctx->refcount);
2793 }
2794 
2795 /**
2796  * kbase_js_foreach_ctx_job(): - Call a function on all jobs in context
2797  * @kctx:     Pointer to context.
2798  * @callback: Pointer to function to call for each job.
2799  *
2800  * Call a function on all jobs belonging to a non-queued, non-running
2801  * context, and detach the jobs from the context as it goes.
2802  *
2803  * Due to the locks that might be held at the time of the call, the callback
2804  * may need to defer work on a workqueue to complete its actions (e.g. when
2805  * cancelling jobs)
2806  *
2807  * Atoms will be removed from the queue, so this must only be called when
2808  * cancelling jobs (which occurs as part of context destruction).
2809  *
2810  * The locking conditions on the caller are as follows:
2811  * - it will be holding kbasep_js_kctx_info::ctx::jsctx_mutex.
2812  */
kbase_js_foreach_ctx_job(struct kbase_context *kctx, kbasep_js_ctx_job_cb callback)2813 static void kbase_js_foreach_ctx_job(struct kbase_context *kctx,
2814 		kbasep_js_ctx_job_cb callback)
2815 {
2816 	struct kbase_device *kbdev;
2817 	struct kbasep_js_device_data *js_devdata;
2818 	unsigned long flags;
2819 	u32 js;
2820 
2821 	kbdev = kctx->kbdev;
2822 	js_devdata = &kbdev->js_data;
2823 
2824 	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
2825 
2826 	KBASE_TRACE_ADD_REFCOUNT(kbdev, JS_POLICY_FOREACH_CTX_JOBS, kctx, NULL,
2827 					0u, trace_get_refcnt(kbdev, kctx));
2828 
2829 	/* Invoke callback on jobs on each slot in turn */
2830 	for (js = 0; js < kbdev->gpu_props.num_job_slots; js++)
2831 		jsctx_queue_foreach(kctx, js, callback);
2832 
2833 	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
2834 }
2835