Initial commit
[kernel/linux-3.0.git] / drivers / gpu / vithar_rev0 / kbase / src / common / mali_kbase_jd.c
1 /*
2  *
3  * (C) COPYRIGHT 2010-2012 ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
6  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7  * 
8  * A copy of the licence is included with the program, and can also be obtained from Free Software
9  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
10  * 
11  */
12
13
14
15 #include <kbase/src/common/mali_kbase.h>
16 #include <kbase/src/common/mali_kbase_uku.h>
17
18 #define beenthere(f, a...)  OSK_PRINT_INFO(OSK_BASE_JD, "%s:" f, __func__, ##a)
19
20 /*
21  * This is the kernel side of the API. Only entry points are:
22  * - kbase_jd_submit(): Called from userspace to submit a single bag
23  * - kbase_jd_done(): Called from interrupt context to track the
24  *   completion of a job.
25  * Callouts:
26  * - to the job manager (enqueue a job)
27  * - to the event subsystem (signals the completion/failure of bag/job-chains).
28  */
29
30 STATIC INLINE void dep_raise_sem(u32 *sem, u8 dep)
31 {
32         if (!dep)
33                 return;
34
35         sem[BASEP_JD_SEM_WORD_NR(dep)] |= BASEP_JD_SEM_MASK_IN_WORD(dep);
36 }
37 KBASE_EXPORT_TEST_API(dep_raise_sem)
38
39 STATIC INLINE void dep_clear_sem(u32 *sem, u8 dep)
40 {
41         if (!dep)
42                 return;
43
44         sem[BASEP_JD_SEM_WORD_NR(dep)] &= ~BASEP_JD_SEM_MASK_IN_WORD(dep);
45 }
46 KBASE_EXPORT_TEST_API(dep_clear_sem)
47
48 STATIC INLINE int dep_get_sem(u32 *sem, u8 dep)
49 {
50         if (!dep)
51                 return 0;
52
53         return !!(sem[BASEP_JD_SEM_WORD_NR(dep)] & BASEP_JD_SEM_MASK_IN_WORD(dep));
54 }
55 KBASE_EXPORT_TEST_API(dep_get_sem)
56
57 STATIC INLINE mali_bool jd_add_dep(kbase_jd_context *ctx,
58                                    kbase_jd_atom *katom, u8 d)
59 {
60         kbase_jd_dep_queue *dq = &ctx->dep_queue;
61         u8 s = katom->pre_dep.dep[d];
62
63         if (!dep_get_sem(ctx->dep_queue.sem, s))
64                 return MALI_FALSE;
65
66         /*
67          * The slot must be free already. If not, then something went
68          * wrong in the validate path.
69          */
70         OSK_ASSERT(!dq->queue[s]);
71
72         dq->queue[s] = katom;
73         beenthere("queued %p slot %d", (void *)katom, s);
74
75         return MALI_TRUE;
76 }
77 KBASE_EXPORT_TEST_API(jd_add_dep)
78
79 /*
80  * This function only computes the address of the first possible
81  * atom. It doesn't mean it's actually valid (jd_validate_atom takes
82  * care of that).
83  */
84 STATIC INLINE base_jd_atom *jd_get_first_atom(kbase_jd_context *ctx,
85                                               kbase_jd_bag *bag)
86 {
87         /* Check that offset is within pool */
88         if ((bag->offset + sizeof(base_jd_atom)) > ctx->pool_size)
89                 return NULL;
90
91         return  (base_jd_atom *)((char *)ctx->pool + bag->offset);
92 }
93 KBASE_EXPORT_TEST_API(jd_get_first_atom)
94
95 /*
96  * Same as with jd_get_first_atom, but for any subsequent atom.
97  */
98 STATIC INLINE base_jd_atom *jd_get_next_atom(kbase_jd_atom *katom)
99 {
100         /* Think of adding extra padding for userspace */
101         return (base_jd_atom *)base_jd_get_atom_syncset(katom->user_atom, katom->nr_syncsets);
102 }
103 KBASE_EXPORT_TEST_API(jd_get_next_atom)
104
105 /*
106  * This will check atom for correctness and if so, initialize its js policy.
107  */
108 STATIC INLINE kbase_jd_atom *jd_validate_atom(struct kbase_context *kctx,
109                                               kbase_jd_bag *bag,
110                                               base_jd_atom *atom,
111                                               u32 *sem)
112 {
113         kbase_jd_context *jctx = &kctx->jctx;
114         kbase_jd_atom *katom;
115         u32 nr_syncsets;
116         base_jd_dep pre_dep;
117         int nice_priority;
118
119         /* Check the atom struct fits in the pool before we attempt to access it
120            Note: a bad bag->nr_atom could trigger this condition */
121         if(((char *)atom + sizeof(base_jd_atom)) > ((char *)jctx->pool + jctx->pool_size))
122                 return NULL;
123
124         nr_syncsets = atom->nr_syncsets;
125         pre_dep = atom->pre_dep;
126
127         /* Check that the whole atom fits within the pool.
128          * syncsets integrity will be performed as we execute them */
129         if ((char *)base_jd_get_atom_syncset(atom, nr_syncsets) > ((char *)jctx->pool + jctx->pool_size))
130                 return NULL;
131
132         /*
133          * Check that dependencies are sensible: the atom cannot have
134          * pre-dependencies that are already in use by another atom.
135          */
136         if (jctx->dep_queue.queue[pre_dep.dep[0]] ||
137             jctx->dep_queue.queue[pre_dep.dep[1]])
138                 return NULL;
139
140         /* Check for conflicting dependencies inside the bag */
141         if (dep_get_sem(sem, pre_dep.dep[0]) ||
142             dep_get_sem(sem, pre_dep.dep[1]))
143                 return NULL;
144
145         dep_raise_sem(sem, pre_dep.dep[0]);
146         dep_raise_sem(sem, pre_dep.dep[1]);
147
148         /* We surely want to preallocate a pool of those, or have some
149          * kind of slab allocator around */
150         katom = osk_calloc(sizeof(*katom));
151         if (!katom)
152                 return NULL;    /* Ideally we should handle OOM more gracefully */
153
154         katom->user_atom    = atom;
155         katom->pre_dep      = pre_dep;
156         katom->post_dep     = atom->post_dep;
157         katom->bag          = bag;
158         katom->kctx         = kctx;
159         katom->nr_syncsets  = nr_syncsets;
160         katom->affinity     = 0;
161         katom->core_req     = atom->core_req;
162         katom->jc           = atom->jc;
163
164         /*
165          * If the priority is increased we need to check the caller has security caps to do this, if
166          * prioirty is decreased then this is ok as the result will have no negative impact on other
167          * processes running.
168          */
169         katom->nice_prio = atom->prio;
170         if( 0 > katom->nice_prio)
171         {
172                 mali_bool access_allowed;
173                 access_allowed = kbase_security_has_capability(kctx, KBASE_SEC_MODIFY_PRIORITY, KBASE_SEC_FLAG_NOAUDIT);
174                 if(!access_allowed)
175                 {
176                         /* For unprivileged processes - a negative priority is interpreted as zero */
177                         katom->nice_prio = 0;
178                 }
179         }
180
181         /* Scale priority range to use NICE range */
182         if(katom->nice_prio)
183         {
184                 /* Remove sign for calculation */
185                 nice_priority = katom->nice_prio+128;
186                 /* Fixed point maths to scale from ..255 to 0..39 (NICE range with +20 offset) */
187                 katom->nice_prio = (((20<<16)/128)*nice_priority)>>16;
188         }
189
190         /* pre-fill the event */
191         katom->event.event_code = BASE_JD_EVENT_DONE;
192         katom->event.data       = katom;
193
194         /* Initialize the jobscheduler policy for this atom. Function will
195          * return error if the atom is malformed. Then inmediatelly terminate
196          * the policy to free allocated resources and return error.
197          *
198          * Soft-jobs never enter the job scheduler so we don't initialise the policy for these
199          */
200         if ((katom->core_req & BASE_JD_REQ_SOFT_JOB) == 0)
201         {
202                 kbasep_js_policy *js_policy = &(kctx->kbdev->js_data.policy);
203                 if (MALI_ERROR_NONE != kbasep_js_policy_init_job( js_policy, katom ))
204                 {
205                         osk_free( katom );
206                         return NULL;
207                 }
208         }
209
210         return katom;
211 }
212 KBASE_EXPORT_TEST_API(jd_validate_atom)
213
214 static void kbase_jd_cancel_bag(kbase_context *kctx, kbase_jd_bag *bag,
215                                 base_jd_event_code code)
216 {
217         bag->event.event_code = code;
218         kbase_event_post(kctx, &bag->event);
219 }
220
221 STATIC void kbase_jd_katom_dtor(kbase_event *event)
222 {
223         kbase_jd_atom *katom = CONTAINER_OF(event, kbase_jd_atom, event);
224         kbasep_js_policy *js_policy = &(katom->kctx->kbdev->js_data.policy);
225
226         kbasep_js_policy_term_job( js_policy, katom );
227         osk_free(katom);
228 }
229 KBASE_EXPORT_TEST_API(kbase_jd_katom_dtor)
230
231 STATIC mali_error kbase_jd_validate_bag(kbase_context *kctx,
232                                         kbase_jd_bag *bag,
233                                         osk_dlist *klistp)
234 {
235         kbase_jd_context *jctx = &kctx->jctx;
236         kbase_jd_atom *katom;
237         base_jd_atom *atom;
238         mali_error err = MALI_ERROR_NONE;
239         u32 sem[BASEP_JD_SEM_ARRAY_SIZE] = { 0 };
240         u32 i;
241
242         atom = jd_get_first_atom(jctx, bag);
243         if (!atom)
244         {
245                 /* Bad start... */
246                 kbase_jd_cancel_bag(kctx, bag, BASE_JD_EVENT_BAG_INVALID);
247                 err = MALI_ERROR_FUNCTION_FAILED;
248                 goto out;
249         }
250
251         for (i = 0; i < bag->nr_atoms; i++)
252         {
253                 katom = jd_validate_atom(kctx, bag, atom, sem);
254                 if (!katom)
255                 {
256                         OSK_DLIST_EMPTY_LIST(klistp, kbase_event,
257                                              entry, kbase_jd_katom_dtor);
258                         kbase_jd_cancel_bag(kctx, bag, BASE_JD_EVENT_BAG_INVALID);
259                         err = MALI_ERROR_FUNCTION_FAILED;
260                         goto out;
261                 }
262
263                 OSK_DLIST_PUSH_BACK(klistp, &katom->event,
264                                     kbase_event, entry);
265                 atom = jd_get_next_atom(katom);
266         }
267
268 out:
269         return err;
270 }
271 KBASE_EXPORT_TEST_API(kbase_jd_validate_bag)
272
273 STATIC INLINE kbase_jd_atom *jd_resolve_dep(kbase_jd_atom *katom, u8 d, int zapping)
274 {
275         u8 other_dep;
276         u8 dep;
277         kbase_jd_atom *dep_katom;
278         kbase_jd_context *ctx = &katom->kctx->jctx;
279
280         dep = katom->post_dep.dep[d];
281
282         if (!dep)
283                 return NULL;
284
285         dep_clear_sem(ctx->dep_queue.sem, dep);
286
287         /* Get the atom that's waiting for us (if any), and remove it
288          * from this particular dependency queue */
289         dep_katom = ctx->dep_queue.queue[dep];
290
291         /* Case of a dangling dependency */
292         if (!dep_katom)
293                 return NULL;
294         
295         ctx->dep_queue.queue[dep] = NULL;
296
297         beenthere("removed %p from slot %d",
298                   (void *)dep_katom, dep);
299
300         /* Find out if this atom is waiting for another job to be done.
301          * If it's not waiting anymore, put it on the run queue. */
302         if (dep_katom->pre_dep.dep[0] == dep)
303                 other_dep = dep_katom->pre_dep.dep[1];
304         else
305                 other_dep = dep_katom->pre_dep.dep[0];
306
307         /*
308          * The following line seem to confuse people, so here's the
309          * rational behind it:
310          *
311          * The queue hold pointers to atoms waiting for a single
312          * pre-dependency to be satisfied. Above, we've already
313          * satisfied a pre-dep for an atom (dep_katom). The next step
314          * is to check whether this atom is now free to run, or has to
315          * wait for another pre-dep to be satisfied.
316          *
317          * For a single entry, 3 possibilities:
318          *
319          * - It's a pointer to dep_katom -> the pre-dep has not been
320          *   satisfied yet, and it cannot run immediately.
321          *
322          * - It's NULL -> the atom can be scheduled immediately, as
323          *   the dependency has already been satisfied.
324          *
325          * - Neither of the above: this is the case of a dependency
326          *   that has already been satisfied, and the slot reused by
327          *   an incoming atom -> dep_katom can be run immediately.
328          */
329         if (ctx->dep_queue.queue[other_dep] != dep_katom)
330                 return dep_katom;
331
332         /*
333          * We're on a killing spree. Cancel the additionnal
334          * dependency, and return the atom anyway. An unfortunate
335          * consequence is that userpace may receive notifications out
336          * of order WRT the dependency tree.
337          */
338         if (zapping)
339         {
340                 ctx->dep_queue.queue[other_dep] = NULL;
341                 return dep_katom;
342         }
343
344         beenthere("katom %p waiting for slot %d",
345                   (void *)dep_katom, other_dep);
346         return NULL;
347 }
348 KBASE_EXPORT_TEST_API(jd_resolve_dep)
349
350 /*
351  * Perform the necessary handling of an atom that has finished running
352  * on the GPU. The @a zapping parameter instruct the function to
353  * propagate the state of the completed atom to all the atoms that
354  * depend on it, directly or indirectly.
355  *
356  * This flag is used for error propagation in the "failed job", or
357  * when destroying a context.
358  *
359  * When not zapping, the caller must hold the kbasep_js_kctx_info::ctx::jsctx_mutex.
360  */
361 STATIC mali_bool jd_done_nolock(kbase_jd_atom *katom, int zapping)
362 {
363         kbase_jd_atom *dep_katom;
364         struct kbase_context *kctx = katom->kctx;
365         osk_dlist ts;   /* traversal stack */
366         osk_dlist *tsp = &ts;
367         osk_dlist vl;   /* visited list */
368         osk_dlist *vlp = &vl;
369         kbase_jd_atom *node;
370         base_jd_event_code event_code = katom->event.event_code;
371         mali_bool need_to_try_schedule_context = MALI_FALSE;
372
373         /*
374          * We're trying to achieve two goals here:
375          * - Eliminate dependency atoms very early so we can push real
376          *    jobs to the HW
377          * - Avoid recursion which could result in a nice DoS from
378          *    user-space.
379          *
380          * We use two lists here:
381          * - One as a stack (ts) to get rid of the recursion
382          * - The other to queue jobs that are either done or ready to
383          *   run.
384          */
385         OSK_DLIST_INIT(tsp);
386         OSK_DLIST_INIT(vlp);
387
388         /* push */
389         OSK_DLIST_PUSH_BACK(tsp, &katom->event, kbase_event, entry);
390
391         while(!OSK_DLIST_IS_EMPTY(tsp))
392         {
393                 /* pop */
394                 node = OSK_DLIST_POP_BACK(tsp, kbase_jd_atom, event.entry);
395
396                 if (node == katom ||
397                     node->core_req == BASE_JD_REQ_DEP ||
398                     zapping)
399                 {
400                         int i;
401                         for (i = 0; i < 2; i++)
402                         {
403                                 dep_katom = jd_resolve_dep(node, i, zapping);
404                                 if (dep_katom) /* push */
405                                         OSK_DLIST_PUSH_BACK(tsp,
406                                                             &dep_katom->event,
407                                                             kbase_event,
408                                                             entry);
409                         }
410                 }
411
412                 OSK_DLIST_PUSH_BACK(vlp, &node->event,
413                                     kbase_event, entry);
414         }
415
416         while(!OSK_DLIST_IS_EMPTY(vlp))
417         {
418                 node = OSK_DLIST_POP_FRONT(vlp, kbase_jd_atom, event.entry);
419
420                 if (node == katom ||
421                     node->core_req == BASE_JD_REQ_DEP ||
422                     (node->core_req & BASE_JD_REQ_SOFT_JOB) ||
423                     zapping)
424                 {
425                         kbase_jd_bag *bag = node->bag;
426
427                         /* If we're zapping stuff, propagate the event code */
428                         if (zapping)
429                         {
430                                 node->event.event_code = event_code;
431                         }
432                         else if (node->core_req & BASE_JD_REQ_SOFT_JOB)
433                         {
434                                 kbase_process_soft_job( kctx, node );
435                         }
436
437                         /* This will signal our per-context worker
438                          * thread that we're done with this katom. Any
439                          * use of this katom after that point IS A
440                          * ERROR!!! */
441                         kbase_event_post(kctx, &node->event);
442                         beenthere("done atom %p\n", (void*)node);
443
444                         if (--bag->nr_atoms == 0)
445                         {
446                                 /* This atom was the last, signal userspace */
447                                 kbase_event_post(kctx, &bag->event);
448                                 beenthere("done bag %p\n", (void*)bag);
449                         }
450
451                         /* Decrement and check the TOTAL number of jobs. This includes
452                          * those not tracked by the scheduler: 'not ready to run' and
453                          * 'dependency-only' jobs. */
454                         if (--kctx->jctx.job_nr == 0)
455                         {
456                                 /* All events are safely queued now, and we can signal any waiter
457                                  * that we've got no more jobs (so we can be safely terminated) */
458                                 osk_waitq_set(&kctx->jctx.zero_jobs_waitq);
459                         }
460                 }
461                 else
462                 {
463                         /* Queue an action about whether we should try scheduling a context */
464                         need_to_try_schedule_context |= kbasep_js_add_job( kctx, node );
465                 }
466         }
467
468         return need_to_try_schedule_context;
469 }
470 KBASE_EXPORT_TEST_API(jd_done_nolock)
471
472 mali_error kbase_jd_submit(kbase_context *kctx, const kbase_uk_job_submit *user_bag)
473 {
474         osk_dlist klist;
475         osk_dlist *klistp = &klist;
476         kbase_jd_context *jctx = &kctx->jctx;
477         kbase_jd_atom *katom;
478         kbase_jd_bag *bag;
479         mali_error err = MALI_ERROR_NONE;
480         int i = -1;
481         mali_bool need_to_try_schedule_context = MALI_FALSE;
482         kbase_device *kbdev;
483
484         /*
485          * kbase_jd_submit isn't expected to fail and so all errors with the jobs
486          * are reported by immediately falling them (through event system)
487          */
488
489         kbdev = kctx->kbdev;
490
491         beenthere("%s", "Enter");
492         bag = osk_malloc(sizeof(*bag));
493         if (NULL == bag)
494         {
495                 err = MALI_ERROR_OUT_OF_MEMORY;
496                 goto out_bag;
497         }
498
499         bag->core_restriction       = user_bag->core_restriction;
500         bag->offset                 = user_bag->offset;
501         bag->nr_atoms               = user_bag->nr_atoms;
502         bag->event.event_code       = BASE_JD_EVENT_BAG_DONE;
503         bag->event.data             = (void *)(uintptr_t)user_bag->bag_uaddr;
504
505         osk_mutex_lock(&jctx->lock);
506
507         /*
508          * Use a transient list to store all the validated atoms.
509          * Once we're sure nothing is wrong, there's no going back.
510          */
511         OSK_DLIST_INIT(klistp);
512
513         if (kbase_jd_validate_bag(kctx, bag, klistp))
514         {
515                 err = MALI_ERROR_FUNCTION_FAILED;
516                 goto out;
517         }
518
519         while(!OSK_DLIST_IS_EMPTY(klistp))
520         {
521
522                 katom = OSK_DLIST_POP_FRONT(klistp,
523                                             kbase_jd_atom, event.entry);
524                 i++;
525
526                 /* This is crucial. As jobs are processed in-order, we must
527                  * indicate that any job with a pre-dep on this particular job
528                  * must wait for its completion (indicated as a post-dep).
529                  */
530                 dep_raise_sem(jctx->dep_queue.sem, katom->post_dep.dep[0]);
531                 dep_raise_sem(jctx->dep_queue.sem, katom->post_dep.dep[1]);
532
533                 /* Process pre-exec syncsets before queueing */
534                 kbase_pre_job_sync(kctx,
535                                    base_jd_get_atom_syncset(katom->user_atom, 0),
536                                    katom->nr_syncsets);
537                 /* Update the TOTAL number of jobs. This includes those not tracked by
538                  * the scheduler: 'not ready to run' and 'dependency-only' jobs. */
539                 jctx->job_nr++;
540                 /* Cause any future waiter-on-termination to wait until the jobs are
541                  * finished */
542                 osk_waitq_clear(&jctx->zero_jobs_waitq);
543                 /* If no pre-dep has been set, then we're free to run
544                  * the job immediately */
545                 if ((jd_add_dep(jctx, katom, 0) | jd_add_dep(jctx, katom, 1)))
546                 {
547                         beenthere("queuing atom #%d(%p %p)", i,
548                                   (void *)katom, (void *)katom->user_atom);
549                         continue;
550                 }
551
552                 beenthere("running atom #%d(%p %p)", i,
553                           (void *)katom, (void *)katom->user_atom);
554
555                 /* Lock the JS Context, for submitting jobs, and queue an action about
556                  * whether we need to try scheduling the context */
557                 osk_mutex_lock( &kctx->jctx.sched_info.ctx.jsctx_mutex );
558
559                 if (katom->core_req & BASE_JD_REQ_SOFT_JOB)
560                 {
561                         kbase_process_soft_job( kctx, katom );
562                         /* Pure software job, so resolve it immediately */
563                         need_to_try_schedule_context |= jd_done_nolock(katom, 0);
564                 }
565                 else if (katom->core_req != BASE_JD_REQ_DEP)
566                 {
567                         need_to_try_schedule_context |= kbasep_js_add_job( kctx, katom );
568                 }
569                 else
570                 {
571                         /* This is a pure dependency. Resolve it immediately */
572                         need_to_try_schedule_context |= jd_done_nolock(katom, 0);
573                 }
574                 osk_mutex_unlock( &kctx->jctx.sched_info.ctx.jsctx_mutex );
575         }
576
577         /* Only whilst we've dropped the JS context lock can we schedule a new
578          * context.
579          *
580          * As an optimization, we only need to do this after processing all jobs
581          * resolved from this context. */
582         if ( need_to_try_schedule_context != MALI_FALSE )
583         {
584                 kbasep_js_try_schedule_head_ctx( kbdev );
585         }
586 out:
587         osk_mutex_unlock(&jctx->lock);
588 out_bag:
589         beenthere("%s", "Exit");
590         return err;
591 }
592 KBASE_EXPORT_TEST_API(kbase_jd_submit)
593
594 STATIC void kbasep_jd_check_deref_cores(struct kbase_device *kbdev, struct kbase_jd_atom *katom)
595 {
596         if (katom->affinity != 0)
597         {
598                 u64 tiler_affinity = 0;
599                 if (katom->core_req & BASE_JD_REQ_T)
600                 {
601                         tiler_affinity = kbdev->tiler_present_bitmap;
602                 }
603                 kbase_pm_release_cores(kbdev, katom->affinity, tiler_affinity);
604                 katom->affinity = 0;
605         }
606 }
607
608 /**
609  * This function:
610  * - requeues the job from the runpool (if it was soft-stopped/removed from NEXT registers)
611  * - removes it from the system if it finished/failed/was cancelled.
612  * - resolves dependencies to add dependent jobs to the context, potentially starting them if necessary (which may add more references to the context)
613  * - releases the reference to the context from the no-longer-running job.
614  * - Handles retrying submission outside of IRQ context if it failed from within IRQ context.
615  */
616 static void jd_done_worker(osk_workq_work *data)
617 {
618         kbase_jd_atom *katom = CONTAINER_OF(data, kbase_jd_atom, work);
619         kbase_jd_context *jctx;
620         kbase_context *kctx;
621         kbasep_js_kctx_info *js_kctx_info;
622         kbasep_js_policy *js_policy;
623         kbase_device *kbdev;
624         kbasep_js_device_data *js_devdata;
625         int zapping;
626         u64 cache_jc = katom->jc;
627         base_jd_atom *cache_user_atom = katom->user_atom;
628
629         mali_bool retry_submit;
630         int retry_jobslot;
631
632         kctx = katom->kctx;
633         jctx = &kctx->jctx;
634         kbdev = kctx->kbdev;
635         js_kctx_info = &kctx->jctx.sched_info;
636
637         js_devdata = &kbdev->js_data;
638         js_policy = &kbdev->js_data.policy;
639
640         KBASE_TRACE_ADD( kbdev, JD_DONE_WORKER, kctx, katom->user_atom, katom->jc, 0 );
641         /*
642          * Begin transaction on JD context and JS context
643          */
644         osk_mutex_lock( &jctx->lock );
645         osk_mutex_lock( &js_kctx_info->ctx.jsctx_mutex );
646
647         /* This worker only gets called on contexts that are scheduled *in*. This is
648          * because it only happens in response to an IRQ from a job that was
649          * running.
650          */
651         OSK_ASSERT( js_kctx_info->ctx.is_scheduled != MALI_FALSE );
652
653         /* Release cores this job was using (this might power down unused cores) */ 
654         kbasep_jd_check_deref_cores(kbdev, katom);
655
656         /* Grab the retry_submit state before the katom disappears */
657         retry_submit = kbasep_js_get_job_retry_submit_slot( katom, &retry_jobslot );
658
659         if (katom->event.event_code == BASE_JD_EVENT_STOPPED
660             || katom->event.event_code == BASE_JD_EVENT_REMOVED_FROM_NEXT )
661         {
662                 /* Requeue the atom on soft-stop / removed from NEXT registers */
663                 OSK_PRINT_INFO(OSK_BASE_JM, "JS: Soft Stopped/Removed from next %p on Ctx %p; Requeuing", kctx );
664
665                 osk_mutex_lock( &js_devdata->runpool_mutex );
666                 kbasep_js_clear_job_retry_submit( katom );
667
668                 osk_spinlock_irq_lock( &js_devdata->runpool_irq.lock );
669                 kbasep_js_policy_enqueue_job( js_policy, katom );
670                 osk_spinlock_irq_unlock( &js_devdata->runpool_irq.lock );
671
672                 /* This may now be the only job present (work queues can run items out of order
673                  * e.g. on different CPUs), so we must try to run it, otherwise it might not get
674                  * run at all after this. */
675                 kbasep_js_try_run_next_job( kbdev );
676
677                 osk_mutex_unlock( &js_devdata->runpool_mutex );
678         }
679         else
680         {
681                 /* Remove the job from the system for all other reasons */
682                 mali_bool need_to_try_schedule_context;
683
684                 kbasep_js_remove_job( kctx, katom );
685
686                 zapping = (katom->event.event_code != BASE_JD_EVENT_DONE);
687                 need_to_try_schedule_context = jd_done_nolock(katom, zapping);
688
689                 /* This ctx is already scheduled in, so return value guarenteed FALSE */
690                 OSK_ASSERT( need_to_try_schedule_context == MALI_FALSE );
691         }
692         /* katom may have been freed now, do not use! */
693
694         /*
695          * Transaction complete
696          */
697         osk_mutex_unlock( &js_kctx_info->ctx.jsctx_mutex );
698         osk_mutex_unlock( &jctx->lock );
699
700         /* Job is now no longer running, so can now safely release the context reference
701          * This potentially schedules out the context, schedules in a new one, and
702          * runs a new job on the new one */
703         kbasep_js_runpool_release_ctx( kbdev, kctx );
704
705         /* If the IRQ handler failed to get a job from the policy, try again from
706          * outside the IRQ handler */
707         if ( retry_submit != MALI_FALSE )
708         {
709                 KBASE_TRACE_ADD_SLOT( kbdev, JD_DONE_TRY_RUN_NEXT_JOB, kctx, cache_user_atom, cache_jc, retry_jobslot );
710                 osk_mutex_lock( &js_devdata->runpool_mutex );
711                 kbasep_js_try_run_next_job_on_slot( kbdev, retry_jobslot );
712                 osk_mutex_unlock( &js_devdata->runpool_mutex );
713         }
714         KBASE_TRACE_ADD( kbdev, JD_DONE_WORKER_END, kctx, cache_user_atom, cache_jc, 0 );
715 }
716
717 /*
718  * Work queue job cancel function
719  * Only called as part of 'Zapping' a context (which occurs on termination)
720  * Operates serially with the jd_done_worker() on the work queue
721  */
722 static void jd_cancel_worker(osk_workq_work *data)
723 {
724         kbase_jd_atom *katom = CONTAINER_OF(data, kbase_jd_atom, work);
725         kbase_jd_context *jctx;
726         kbase_context *kctx;
727         kbasep_js_kctx_info *js_kctx_info;
728         mali_bool need_to_try_schedule_context;
729
730         kctx = katom->kctx;
731         jctx = &kctx->jctx;
732         js_kctx_info = &kctx->jctx.sched_info;
733
734         {
735                 kbase_device *kbdev = kctx->kbdev;
736                 KBASE_TRACE_ADD( kbdev, JD_CANCEL_WORKER, kctx, katom->user_atom, katom->jc, 0 );
737         }
738
739         /* This only gets called on contexts that are scheduled out. Hence, we must
740          * make sure we don't de-ref the number of running jobs (there aren't
741          * any), nor must we try to schedule out the context (it's already
742          * scheduled out).
743          */
744         OSK_ASSERT( js_kctx_info->ctx.is_scheduled == MALI_FALSE );
745
746         /* Release cores this job was using (this might power down unused cores) */ 
747         kbasep_jd_check_deref_cores(kctx->kbdev, katom);
748
749         /* Scheduler: Remove the job from the system */
750         osk_mutex_lock( &js_kctx_info->ctx.jsctx_mutex );
751         kbasep_js_remove_job( kctx, katom );
752         osk_mutex_unlock( &js_kctx_info->ctx.jsctx_mutex );
753
754         osk_mutex_lock(&jctx->lock);
755
756         /* Always enable zapping */
757         need_to_try_schedule_context = jd_done_nolock(katom, 1);
758         /* Because we're zapping, we're not adding any more jobs to this ctx, so no need to
759          * schedule the context. There's also no need for the jsctx_mutex to have been taken
760          * around this too. */
761         OSK_ASSERT( need_to_try_schedule_context == MALI_FALSE );
762
763         /* katom may have been freed now, do not use! */
764         osk_mutex_unlock(&jctx->lock);
765
766 }
767
768
769 void kbase_jd_done(kbase_jd_atom *katom)
770 {
771         kbase_context *kctx;
772         kbase_device *kbdev;
773         OSK_ASSERT(katom);
774         kctx = katom->kctx;
775         OSK_ASSERT(kctx);
776         kbdev = kctx->kbdev;
777         OSK_ASSERT(kbdev);
778
779         KBASE_TRACE_ADD( kbdev, JD_DONE, kctx, katom->user_atom, katom->jc, 0 );
780
781         osk_workq_work_init(&katom->work, jd_done_worker);
782         osk_workq_submit(&kctx->jctx.job_done_wq, &katom->work);
783 }
784 KBASE_EXPORT_TEST_API(kbase_jd_done)
785
786 void kbase_jd_cancel(kbase_jd_atom *katom)
787 {
788         kbase_context *kctx;
789         kbasep_js_kctx_info *js_kctx_info;
790         kbase_device *kbdev;
791
792         kctx = katom->kctx;
793         js_kctx_info = &kctx->jctx.sched_info;
794         kbdev = kctx->kbdev;
795
796         KBASE_TRACE_ADD( kbdev, JD_CANCEL, kctx, katom->user_atom, katom->jc, 0 );
797
798         /* This should only be done from a context that is not scheduled */
799         OSK_ASSERT( js_kctx_info->ctx.is_scheduled == MALI_FALSE );
800
801         katom->event.event_code = BASE_JD_EVENT_JOB_CANCELLED;
802
803         osk_workq_work_init(&katom->work, jd_cancel_worker);
804         osk_workq_submit(&kctx->jctx.job_done_wq, &katom->work);
805 }
806
807 void kbase_jd_flush_workqueues(kbase_context *kctx)
808 {
809         kbase_device *kbdev;
810         int i;
811
812         OSK_ASSERT( kctx );
813
814         kbdev = kctx->kbdev;
815         OSK_ASSERT( kbdev );
816
817         osk_workq_flush( &kctx->jctx.job_done_wq );
818
819         /* Flush all workqueues, for simplicity */
820         for (i = 0; i < kbdev->nr_address_spaces; i++)
821         {
822                 osk_workq_flush( &kbdev->as[i].pf_wq );
823         }
824 }
825
826 typedef struct zap_reset_data
827 {
828         /* The stages are:
829          * 1. The timer has never been called
830          * 2. The zap has timed out, all slots are soft-stopped - the GPU reset will happen.
831          *    The GPU has been reset when kbdev->reset_waitq is signalled
832          *
833          * (-1 - The timer has been cancelled)
834          */
835         int             stage;
836         kbase_device    *kbdev;
837         osk_timer       *timer;
838         osk_spinlock    lock;
839 } zap_reset_data;
840
841 static void zap_timeout_callback(void *data)
842 {
843         zap_reset_data *reset_data = (zap_reset_data*)data;
844         kbase_device *kbdev = reset_data->kbdev;
845
846         osk_spinlock_lock(&reset_data->lock);
847
848         if (reset_data->stage == -1)
849         {
850                 goto out;
851         }
852
853         if (kbase_prepare_to_reset_gpu(kbdev))
854         {
855                 kbase_reset_gpu(kbdev);
856         }
857
858         reset_data->stage = 2;
859
860 out:
861         osk_spinlock_unlock(&reset_data->lock);
862 }
863
864 void kbase_jd_zap_context(kbase_context *kctx)
865 {
866         kbase_device *kbdev;
867         osk_timer zap_timeout;
868         osk_error ret;
869         zap_reset_data reset_data;
870
871         OSK_ASSERT(kctx);
872
873         kbdev = kctx->kbdev;
874
875         KBASE_TRACE_ADD( kbdev, JD_ZAP_CONTEXT, kctx, NULL, 0u, 0u );
876         kbase_job_zap_context(kctx);
877
878         ret = osk_timer_on_stack_init(&zap_timeout);
879         if (ret != OSK_ERR_NONE)
880         {
881                 goto skip_timeout;
882         }
883
884         ret = osk_spinlock_init(&reset_data.lock, OSK_LOCK_ORDER_JD_ZAP_CONTEXT);
885         if (ret != OSK_ERR_NONE)
886         {
887                 osk_timer_on_stack_term(&zap_timeout);
888                 goto skip_timeout;
889         }
890
891         reset_data.kbdev = kbdev;
892         reset_data.timer = &zap_timeout;
893         reset_data.stage = 1;
894         osk_timer_callback_set(&zap_timeout, zap_timeout_callback, &reset_data);
895         ret = osk_timer_start(&zap_timeout, ZAP_TIMEOUT);
896
897         if (ret != OSK_ERR_NONE)
898         {
899                 osk_spinlock_term(&reset_data.lock);
900                 osk_timer_on_stack_term(&zap_timeout);
901                 goto skip_timeout;
902         }
903
904         /* If we jump to here then the zap timeout will not be active,
905          * so if the GPU hangs the driver will also hang. This will only
906          * happen if the driver is very resource starved.
907          */
908 skip_timeout:
909
910         /* Wait for all jobs to finish, and for the context to be not-scheduled
911          * (due to kbase_job_zap_context(), we also guarentee it's not in the JS
912          * policy queue either */
913         osk_waitq_wait(&kctx->jctx.zero_jobs_waitq);
914         osk_waitq_wait(&kctx->jctx.sched_info.ctx.not_scheduled_waitq);
915
916         if (ret == OSK_ERR_NONE)
917         {
918                 osk_spinlock_lock(&reset_data.lock);
919                 if (reset_data.stage == 1)
920                 {
921                         /* The timer hasn't run yet - so cancel it */
922                         reset_data.stage = -1;
923                 }
924                 osk_spinlock_unlock(&reset_data.lock);
925
926                 osk_timer_stop(&zap_timeout);
927
928                 if (reset_data.stage == 2)
929                 {
930                         /* The reset has already started.
931                          * Wait for the reset to complete
932                          */
933                         osk_waitq_wait(&kbdev->reset_waitq);
934                 }
935                 osk_timer_on_stack_term(&zap_timeout);
936                 osk_spinlock_term(&reset_data.lock);
937         }
938
939         OSK_PRINT_INFO(OSK_BASE_JM, "Zap: Finished Context %p", kctx );
940
941         /* Ensure that the signallers of the waitqs have finished */
942         osk_mutex_lock(&kctx->jctx.lock);
943         osk_mutex_lock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
944         osk_mutex_unlock(&kctx->jctx.sched_info.ctx.jsctx_mutex);
945         osk_mutex_unlock(&kctx->jctx.lock);
946 }
947 KBASE_EXPORT_TEST_API(kbase_jd_zap_context)
948
949 mali_error kbase_jd_init(struct kbase_context *kctx)
950 {
951         void *kaddr;
952         int i;
953         mali_error mali_err;
954         osk_error osk_err;
955
956         OSK_ASSERT(kctx);
957         OSK_ASSERT(NULL == kctx->jctx.pool);
958
959         kaddr = osk_vmalloc(BASEP_JCTX_RB_NRPAGES * OSK_PAGE_SIZE);
960         if (!kaddr)
961         {
962                 mali_err = MALI_ERROR_OUT_OF_MEMORY;
963                 goto out;
964         }
965         osk_err = osk_workq_init(&kctx->jctx.job_done_wq, "mali_jd", 0);
966         if (OSK_ERR_NONE != osk_err)
967         {
968                 mali_err = MALI_ERROR_OUT_OF_MEMORY;
969                 goto out1;
970         }
971
972         for (i = 0; i < 256; i++)
973                 kctx->jctx.dep_queue.queue[i] = NULL;
974
975         for (i = 0; i < BASEP_JD_SEM_ARRAY_SIZE; i++)
976                 kctx->jctx.dep_queue.sem[i] = 0;
977
978         osk_err = osk_mutex_init(&kctx->jctx.lock, OSK_LOCK_ORDER_JCTX);
979         if (OSK_ERR_NONE != osk_err)
980         {
981                 mali_err = MALI_ERROR_FUNCTION_FAILED;
982                 goto out2;
983         }
984
985         osk_err = osk_waitq_init(&kctx->jctx.zero_jobs_waitq);
986         if (OSK_ERR_NONE != osk_err)
987         {
988                 mali_err = MALI_ERROR_FUNCTION_FAILED;
989                 goto out3;
990         }
991
992         osk_err = osk_spinlock_irq_init(&kctx->jctx.tb_lock, OSK_LOCK_ORDER_TB);
993         if (OSK_ERR_NONE != osk_err)
994         {
995                 mali_err = MALI_ERROR_FUNCTION_FAILED;
996                 goto out4;
997         }
998
999         osk_waitq_set(&kctx->jctx.zero_jobs_waitq);
1000
1001         kctx->jctx.pool         = kaddr;
1002         kctx->jctx.pool_size    = BASEP_JCTX_RB_NRPAGES * OSK_PAGE_SIZE;
1003         kctx->jctx.job_nr       = 0;
1004
1005         return MALI_ERROR_NONE;
1006
1007 out4:
1008         osk_waitq_term(&kctx->jctx.zero_jobs_waitq);
1009 out3:
1010         osk_mutex_term(&kctx->jctx.lock);
1011 out2:
1012         osk_workq_term(&kctx->jctx.job_done_wq);
1013 out1:
1014         osk_vfree(kaddr);
1015 out:
1016         return mali_err;
1017 }
1018 KBASE_EXPORT_TEST_API(kbase_jd_init)
1019
1020 void kbase_jd_exit(struct kbase_context *kctx)
1021 {
1022         OSK_ASSERT(kctx);
1023         /* Assert if kbase_jd_init has not been called before this function
1024            (kbase_jd_init initializes the pool) */
1025         OSK_ASSERT(kctx->jctx.pool);
1026
1027         osk_spinlock_irq_term(&kctx->jctx.tb_lock);
1028         /* Work queue is emptied by this */
1029         osk_workq_term(&kctx->jctx.job_done_wq);
1030         osk_waitq_term(&kctx->jctx.zero_jobs_waitq);
1031         osk_vfree(kctx->jctx.pool);
1032         osk_mutex_term(&kctx->jctx.lock);
1033 }
1034 KBASE_EXPORT_TEST_API(kbase_jd_exit)