MALI: rockchip: upgrade to DDK r7p0-02rel0.
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / mali_kbase_debug_job_fault.c
1 /*
2  *
3  * (C) COPYRIGHT 2012-2015 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
17
18 #include "mali_kbase_debug_job_fault.h"
19
20 #ifdef CONFIG_DEBUG_FS
21
22 static bool kbase_is_job_fault_event_pending(struct list_head *event_list)
23 {
24         bool ret;
25
26         ret = (!list_empty(event_list));
27
28         return ret;
29 }
30
31 static bool kbase_ctx_has_no_event_pending(
32                 struct kbase_context *kctx, struct list_head *event_list)
33 {
34         struct base_job_fault_event *event;
35
36         if (list_empty(event_list))
37                 return true;
38         list_for_each_entry(event, event_list, head) {
39                 if (event->katom->kctx == kctx)
40                         return false;
41         }
42         return false;
43 }
44
45 /* wait until the fault happen and copy the event */
46 static int kbase_job_fault_event_wait(struct kbase_device *kbdev,
47                 struct list_head *event_list,
48                 struct base_job_fault_event *event)
49 {
50         struct base_job_fault_event *event_in;
51
52         if (list_empty(event_list)) {
53                 if (wait_event_interruptible(kbdev->job_fault_wq,
54                                 kbase_is_job_fault_event_pending(event_list)))
55                         return -ERESTARTSYS;
56         }
57
58         event_in = list_entry(event_list->next,
59                         struct base_job_fault_event, head);
60
61         event->event_code = event_in->event_code;
62         event->katom = event_in->katom;
63         return 0;
64
65 }
66
67 /* remove the event from the queue */
68 static struct base_job_fault_event *kbase_job_fault_event_dequeue(
69                 struct kbase_device *kbdev, struct list_head *event_list)
70 {
71         struct base_job_fault_event *event;
72
73         event = list_entry(event_list->next,
74                         struct base_job_fault_event, head);
75         list_del(event_list->next);
76
77         return event;
78
79 }
80
81 /* Remove all the following atoms after the failed atom in the same context
82  * Call the postponed bottom half of job done.
83  * Then, this context could be rescheduled.
84  */
85 static void kbase_job_fault_resume_event_cleanup(struct kbase_context *kctx)
86 {
87         struct list_head *event_list = &kctx->job_fault_resume_event_list;
88
89         while (!list_empty(event_list)) {
90                 struct base_job_fault_event *event;
91
92                 event = kbase_job_fault_event_dequeue(kctx->kbdev,
93                                 &kctx->job_fault_resume_event_list);
94                 kbase_jd_done_worker(&event->katom->work);
95         }
96
97 }
98
99 /* Remove all the failed atoms that belong to different contexts
100  * Resume all the contexts that were suspend due to failed job
101  */
102 static void kbase_job_fault_event_cleanup(struct kbase_device *kbdev)
103 {
104         struct list_head *event_list = &kbdev->job_fault_event_list;
105
106         while (!list_empty(event_list)) {
107
108                 kbase_job_fault_event_dequeue(kbdev, event_list);
109                 wake_up(&kbdev->job_fault_resume_wq);
110         }
111 }
112
113 static void kbase_job_fault_resume_worker(struct work_struct *data)
114 {
115         struct base_job_fault_event *event = container_of(data,
116                         struct base_job_fault_event, job_fault_work);
117         struct kbase_context *kctx;
118         struct kbase_jd_atom *katom;
119
120         katom = event->katom;
121         kctx = katom->kctx;
122
123         dev_info(kctx->kbdev->dev, "Job dumping wait\n");
124
125         /* When it was waked up, it need to check if queue is empty or the
126          * failed atom belongs to different context. If yes, wake up. Both
127          * of them mean the failed job has been dumped. Please note, it
128          * should never happen that the job_fault_event_list has the two
129          * atoms belong to the same context.
130          */
131         wait_event(kctx->kbdev->job_fault_resume_wq,
132                         kbase_ctx_has_no_event_pending(kctx,
133                                         &kctx->kbdev->job_fault_event_list));
134
135         atomic_set(&kctx->job_fault_count, 0);
136         kbase_jd_done_worker(&katom->work);
137
138         /* In case the following atoms were scheduled during failed job dump
139          * the job_done_worker was held. We need to rerun it after the dump
140          * was finished
141          */
142         kbase_job_fault_resume_event_cleanup(kctx);
143
144         dev_info(kctx->kbdev->dev, "Job dumping finish, resume scheduler\n");
145 }
146
147 static struct base_job_fault_event *kbase_job_fault_event_queue(
148                 struct list_head *event_list,
149                 struct kbase_jd_atom *atom,
150                 u32 completion_code)
151 {
152         struct base_job_fault_event *event;
153
154         event = &atom->fault_event;
155
156         event->katom = atom;
157         event->event_code = completion_code;
158
159         list_add_tail(&event->head, event_list);
160
161         return event;
162
163 }
164
165 static void kbase_job_fault_event_post(struct kbase_device *kbdev,
166                 struct kbase_jd_atom *katom, u32 completion_code)
167 {
168         struct base_job_fault_event *event;
169
170         event = kbase_job_fault_event_queue(&kbdev->job_fault_event_list,
171                                 katom, completion_code);
172
173         wake_up_interruptible(&kbdev->job_fault_wq);
174
175         INIT_WORK(&event->job_fault_work, kbase_job_fault_resume_worker);
176         queue_work(kbdev->job_fault_resume_workq, &event->job_fault_work);
177
178         dev_info(katom->kctx->kbdev->dev, "Job fault happen, start dump: %d_%d",
179                         katom->kctx->tgid, katom->kctx->id);
180
181 }
182
183 /*
184  * This function will process the job fault
185  * Get the register copy
186  * Send the failed job dump event
187  * Create a Wait queue to wait until the job dump finish
188  */
189
190 bool kbase_debug_job_fault_process(struct kbase_jd_atom *katom,
191                 u32 completion_code)
192 {
193         struct kbase_context *kctx = katom->kctx;
194
195         /* Check if dumping is in the process
196          * only one atom of each context can be dumped at the same time
197          * If the atom belongs to different context, it can be dumped
198          */
199         if (atomic_read(&kctx->job_fault_count) > 0) {
200                 kbase_job_fault_event_queue(
201                                 &kctx->job_fault_resume_event_list,
202                                 katom, completion_code);
203                 dev_info(kctx->kbdev->dev, "queue:%d\n",
204                                 kbase_jd_atom_id(kctx, katom));
205                 return true;
206         }
207
208         if (kctx->kbdev->job_fault_debug == true) {
209
210                 if (completion_code != BASE_JD_EVENT_DONE) {
211
212                         if (kbase_job_fault_get_reg_snapshot(kctx) == false) {
213                                 dev_warn(kctx->kbdev->dev, "get reg dump failed\n");
214                                 return false;
215                         }
216
217                         kbase_job_fault_event_post(kctx->kbdev, katom,
218                                         completion_code);
219                         atomic_inc(&kctx->job_fault_count);
220                         dev_info(kctx->kbdev->dev, "post:%d\n",
221                                         kbase_jd_atom_id(kctx, katom));
222                         return true;
223
224                 }
225         }
226         return false;
227
228 }
229
230 static int debug_job_fault_show(struct seq_file *m, void *v)
231 {
232         struct kbase_device *kbdev = m->private;
233         struct base_job_fault_event *event = (struct base_job_fault_event *)v;
234         struct kbase_context *kctx = event->katom->kctx;
235         int i;
236
237         dev_info(kbdev->dev, "debug job fault seq show:%d_%d, %d",
238                         kctx->tgid, kctx->id, event->reg_offset);
239
240         if (kctx->reg_dump == NULL) {
241                 dev_warn(kbdev->dev, "reg dump is NULL");
242                 return -1;
243         }
244
245         if (kctx->reg_dump[event->reg_offset] ==
246                         REGISTER_DUMP_TERMINATION_FLAG) {
247                 /* Return the error here to stop the read. And the
248                  * following next() will not be called. The stop can
249                  * get the real event resource and release it
250                  */
251                 return -1;
252         }
253
254         if (event->reg_offset == 0)
255                 seq_printf(m, "%d_%d\n", kctx->tgid, kctx->id);
256
257         for (i = 0; i < 50; i++) {
258                 if (kctx->reg_dump[event->reg_offset] ==
259                                 REGISTER_DUMP_TERMINATION_FLAG) {
260                         break;
261                 }
262                 seq_printf(m, "%08x: %08x\n",
263                                 kctx->reg_dump[event->reg_offset],
264                                 kctx->reg_dump[1+event->reg_offset]);
265                 event->reg_offset += 2;
266
267         }
268
269
270         return 0;
271 }
272 static void *debug_job_fault_next(struct seq_file *m, void *v, loff_t *pos)
273 {
274         struct kbase_device *kbdev = m->private;
275         struct base_job_fault_event *event = (struct base_job_fault_event *)v;
276
277         dev_info(kbdev->dev, "debug job fault seq next:%d, %d",
278                         event->reg_offset, (int)*pos);
279
280         return event;
281 }
282
283 static void *debug_job_fault_start(struct seq_file *m, loff_t *pos)
284 {
285         struct kbase_device *kbdev = m->private;
286         struct base_job_fault_event *event;
287
288         dev_info(kbdev->dev, "fault job seq start:%d", (int)*pos);
289
290         /* The condition is trick here. It needs make sure the
291          * fault hasn't happened and the dumping hasn't been started,
292          * or the dumping has finished
293          */
294         if (*pos == 0) {
295                 event = kmalloc(sizeof(*event), GFP_KERNEL);
296                 event->reg_offset = 0;
297                 if (kbase_job_fault_event_wait(kbdev,
298                                 &kbdev->job_fault_event_list, event)) {
299                         kfree(event);
300                         return NULL;
301                 }
302
303                 /* The cache flush workaround is called in bottom half of
304                  * job done but we delayed it. Now we should clean cache
305                  * earlier. Then the GPU memory dump should be correct.
306                  */
307                 if (event->katom->need_cache_flush_cores_retained) {
308                         kbase_gpu_cacheclean(kbdev, event->katom);
309                         event->katom->need_cache_flush_cores_retained = 0;
310                 }
311
312         } else
313                 return NULL;
314
315         return event;
316 }
317
318 static void debug_job_fault_stop(struct seq_file *m, void *v)
319 {
320         struct kbase_device *kbdev = m->private;
321
322         /* here we wake up the kbase_jd_done_worker after stop, it needs
323          * get the memory dump before the register dump in debug daemon,
324          * otherwise, the memory dump may be incorrect.
325          */
326
327         if (v != NULL) {
328                 kfree(v);
329                 dev_info(kbdev->dev, "debug job fault seq stop stage 1");
330
331         } else {
332                 if (!list_empty(&kbdev->job_fault_event_list)) {
333                         kbase_job_fault_event_dequeue(kbdev,
334                                 &kbdev->job_fault_event_list);
335                         wake_up(&kbdev->job_fault_resume_wq);
336                 }
337                 dev_info(kbdev->dev, "debug job fault seq stop stage 2");
338         }
339
340 }
341
342 static const struct seq_operations ops = {
343         .start = debug_job_fault_start,
344         .next = debug_job_fault_next,
345         .stop = debug_job_fault_stop,
346         .show = debug_job_fault_show,
347 };
348
349 static int debug_job_fault_open(struct inode *in, struct file *file)
350 {
351         struct kbase_device *kbdev = in->i_private;
352
353         seq_open(file, &ops);
354
355         ((struct seq_file *)file->private_data)->private = kbdev;
356         dev_info(kbdev->dev, "debug job fault seq open");
357
358         kbdev->job_fault_debug = true;
359
360         return 0;
361
362 }
363
364 static int debug_job_fault_release(struct inode *in, struct file *file)
365 {
366         struct kbase_device *kbdev = in->i_private;
367
368         seq_release(in, file);
369
370         kbdev->job_fault_debug = false;
371
372         /* Clean the unprocessed job fault. After that, all the suspended
373          * contexts could be rescheduled.
374          */
375         kbase_job_fault_event_cleanup(kbdev);
376
377         dev_info(kbdev->dev, "debug job fault seq close");
378
379         return 0;
380 }
381
382 static const struct file_operations kbasep_debug_job_fault_fops = {
383         .open = debug_job_fault_open,
384         .read = seq_read,
385         .llseek = seq_lseek,
386         .release = debug_job_fault_release,
387 };
388
389 static int kbase_job_fault_event_init(struct kbase_device *kbdev)
390 {
391
392         INIT_LIST_HEAD(&kbdev->job_fault_event_list);
393
394         init_waitqueue_head(&(kbdev->job_fault_wq));
395         init_waitqueue_head(&(kbdev->job_fault_resume_wq));
396
397         kbdev->job_fault_resume_workq = alloc_workqueue(
398                         "kbase_job_fault_resume_work_queue", WQ_MEM_RECLAIM, 1);
399
400         return 0;
401 }
402
403 /*
404  *  Initialize debugfs entry for job fault dump
405  */
406 void kbase_debug_job_fault_dev_init(struct kbase_device *kbdev)
407 {
408         debugfs_create_file("job_fault", S_IRUGO,
409                         kbdev->mali_debugfs_directory, kbdev,
410                         &kbasep_debug_job_fault_fops);
411
412         kbase_job_fault_event_init(kbdev);
413         kbdev->job_fault_debug = false;
414
415 }
416
417 /*
418  *  Initialize the relevant data structure per context
419  */
420 void kbase_debug_job_fault_context_init(struct kbase_context *kctx)
421 {
422
423         /* We need allocate double size register range
424          * Because this memory will keep the register address and value
425          */
426         kctx->reg_dump = kmalloc(0x4000 * 2, GFP_KERNEL);
427         if (kctx->reg_dump == NULL)
428                 return;
429
430         if (kbase_debug_job_fault_reg_snapshot_init(kctx, 0x4000) == false) {
431                 kfree(kctx->reg_dump);
432                 kctx->reg_dump = NULL;
433         }
434         INIT_LIST_HEAD(&kctx->job_fault_resume_event_list);
435         atomic_set(&kctx->job_fault_count, 0);
436
437 }
438
439 /*
440  *  release the relevant resource per context
441  */
442 void kbase_debug_job_fault_context_exit(struct kbase_context *kctx)
443 {
444         kfree(kctx->reg_dump);
445 }
446
447 #endif