5036d7a1a3dd1b03c4ab066650c50033a83fec48
[akaros.git] / kern / src / oprofile / cpu_buffer.c
1 /**
2  * @file cpu_buffer.c
3  *
4  * @remark Copyright 2002-2009 OProfile authors
5  * @remark Read the file COPYING
6  *
7  * @author John Levon <levon@movementarian.org>
8  * @author Barry Kasindorf <barry.kasindorf@amd.com>
9  * @author Robert Richter <robert.richter@amd.com>
10  *
11  * Each CPU has a local buffer that stores PC value/event
12  * pairs. We also log context switches when we notice them.
13  * Eventually each CPU's buffer is processed into the global
14  * event buffer by sync_buffer().
15  *
16  * We use a local buffer for two reasons: an NMI or similar
17  * interrupt cannot synchronise, and high sampling rates
18  * would lead to catastrophic global synchronisation if
19  * a global buffer was used.
20  */
21 #include "event_buffer.h"
22 #include "cpu_buffer.h"
23 #include "buffer_sync.h"
24 #include "oprof.h"
25
26 #define OP_BUFFER_FLAGS 0
27
28 /* we allocate an array of these and set the pointer in pcpui */
29 struct oprofile_cpu_buffer *op_cpu_buffer;
30
31 /* this one queue is used by #K to get all events. */
32 static struct queue *opq;
33
34 /* this is run from core 0 for all cpu buffers. */
35 static void wq_sync_buffer(void);
36 unsigned long oprofile_cpu_buffer_size = 65536;
37 unsigned long oprofile_backtrace_depth = 16;
38
39 #define DEFAULT_TIMER_EXPIRE (HZ / 10)
40 static int work_enabled;
41
42 /*
43  * Resets the cpu buffer to a sane state.
44  *
45  * reset these to invalid values; the next sample collected will
46  * populate the buffer with proper values to initialize the buffer
47  */
48 static inline void op_cpu_buffer_reset(int cpu)
49 {
50         //print_func_entry();
51         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
52
53         cpu_buf->last_is_kernel = -1;
54         cpu_buf->last_proc = NULL;
55         //print_func_exit();
56 }
57
58 /* returns the remaining free size of data in the entry */
59 static inline
60         int op_cpu_buffer_add_data(struct op_entry *entry, unsigned long val)
61 {
62         //print_func_entry();
63         assert(entry->size >= 0);
64         if (!entry->size) {
65                 //print_func_exit();
66                 return 0;
67         }
68         *entry->data = val;
69         entry->size--;
70         entry->data++;
71         //print_func_exit();
72         return entry->size;
73 }
74
75 /* returns the size of data in the entry */
76 static inline int op_cpu_buffer_get_size(struct op_entry *entry)
77 {
78         //print_func_entry();
79         //print_func_exit();
80         return entry->size;
81 }
82
83 /* returns 0 if empty or the size of data including the current value */
84 static inline
85         int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val)
86 {
87         //print_func_entry();
88         int size = entry->size;
89         if (!size) {
90                 //print_func_exit();
91                 return 0;
92         }
93         *val = *entry->data;
94         entry->size--;
95         entry->data++;
96         //print_func_exit();
97         return size;
98 }
99
100 unsigned long oprofile_get_cpu_buffer_size(void)
101 {
102         //print_func_entry();
103         //print_func_exit();
104         return oprofile_cpu_buffer_size;
105 }
106
107 void oprofile_cpu_buffer_inc_smpl_lost(void)
108 {
109         //print_func_entry();
110         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
111
112         cpu_buf->sample_lost_overflow++;
113         //print_func_exit();
114 }
115
116 void free_cpu_buffers(void)
117 {
118         //print_func_entry();
119         kfree(op_cpu_buffer);
120         /* we can just leave the queue set up; it will then always return EOF */
121         //print_func_exit();
122 }
123
124 #define RB_EVENT_HDR_SIZE 4
125
126 int alloc_cpu_buffers(void)
127 {
128         //print_func_entry();
129         /* should probably start using waserror() here. The fail stuff just gets
130          * ugly.
131          */
132         int i;
133         unsigned long buffer_size = oprofile_cpu_buffer_size;
134         unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
135                                                  RB_EVENT_HDR_SIZE);
136         /* this can get called lots of times. Things might have been freed.
137          * So be careful.
138          */
139         /* what limit? No idea. */
140         if (!opq)
141                 opq = qopen(1024, 0, NULL, NULL);
142         if (!opq)
143                 goto fail;
144
145         /* we *really* don't want to block. Losing data is better. */
146         qnoblock(opq, 1);
147         if (!op_cpu_buffer) {
148                 op_cpu_buffer =
149                         kzmalloc(sizeof(*op_cpu_buffer) * num_cpus, KMALLOC_WAIT);
150                 if (!op_cpu_buffer)
151                         goto fail;
152
153                 for (i = 0; i < num_cpus; i++) {
154                         struct oprofile_cpu_buffer *b = &op_cpu_buffer[i];
155                         b->last_proc = NULL;
156                         b->last_is_kernel = -1;
157                         b->tracing = 0;
158                         b->buffer_size = buffer_size;
159                         b->sample_received = 0;
160                         b->sample_lost_overflow = 0;
161                         b->backtrace_aborted = 0;
162                         b->sample_invalid_eip = 0;
163                         b->cpu = i;
164                         b->fullqueue = qopen(1024, Qmsg, NULL, NULL);
165                         b->emptyqueue = qopen(1024, Qmsg, NULL, NULL);
166                         spinlock_init_irqsave(&b->lock);
167                 }
168         }
169
170         //print_func_exit();
171         return 0;
172
173 fail:
174         free_cpu_buffers();
175         //print_func_exit();
176         return -ENOMEM;
177 }
178
179 void start_cpu_work(void)
180 {
181         //print_func_entry();
182         int i;
183
184         work_enabled = 1;
185         /* task starts here.
186            schedule_delayed_work_on(i, &b->work, DEFAULT_TIMER_EXPIRE + i);
187          */
188         //print_func_exit();
189 }
190
191 void end_cpu_work(void)
192 {
193         //print_func_entry();
194         work_enabled = 0;
195         //print_func_exit();
196 }
197
198 /* placeholder. Not used yet.
199  */
200 void flush_cpu_work(void)
201 {
202         //print_func_entry();
203         int i;
204         struct oprofile_cpu_buffer *b = &op_cpu_buffer[core_id()];
205
206         //print_func_exit();
207 }
208
209 /* Not used since we're not doing per-cpu buffering yet.
210  */
211
212 struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
213 {
214         //print_func_entry();
215         //print_func_exit();
216         return NULL;
217 }
218
219 static struct block *op_cpu_buffer_write_reserve(struct oprofile_cpu_buffer *cpu_buf,
220         struct op_entry *entry, int size)
221 {
222         //print_func_entry();
223         struct block *b;
224         int totalsize = sizeof(struct op_sample) +
225                 size * sizeof(entry->sample->data[0]);
226
227         b = cpu_buf->block;
228         /* we might have run out. */
229         if ((! b) || (b->lim - b->wp) < size) {
230                 if (b){
231                         qibwrite(opq, b);
232                 }
233                 /* For now. Later, we will grab a block off the
234                  * emptyblock queue.
235                  */
236                 cpu_buf->block = b = iallocb(oprofile_cpu_buffer_size);
237                 if (!b) {
238                         printk("%s: fail\n", __func__);
239                         //print_func_exit();
240                         return NULL;
241                 }
242         }
243         entry->sample = (void *)b->wp;
244         entry->size = size;
245         entry->data = entry->sample->data;
246
247         b->wp += totalsize;
248         //print_func_exit();
249         return b;
250
251 }
252
253 static int
254 op_add_code(struct oprofile_cpu_buffer *cpu_buf, unsigned long backtrace,
255                         int is_kernel, struct proc *proc)
256 {
257         //print_func_entry();
258         struct block *b;
259         struct op_entry entry;
260         struct op_sample *sample;
261         unsigned long flags;
262         int size;
263         ERRSTACK(1);
264
265         flags = 0;
266
267         if (waserror()) {
268                 poperror();
269                 printk("%s: failed\n", __func__);
270                 //print_func_exit();
271                 return 1;
272         }
273
274         if (backtrace)
275                 flags |= TRACE_BEGIN;
276
277         /* notice a switch from user->kernel or vice versa */
278         is_kernel = ! !is_kernel;
279         if (cpu_buf->last_is_kernel != is_kernel) {
280                 cpu_buf->last_is_kernel = is_kernel;
281                 flags |= KERNEL_CTX_SWITCH;
282                 if (is_kernel)
283                         flags |= IS_KERNEL;
284         }
285
286         /* notice a proc switch */
287         if (cpu_buf->last_proc != proc) {
288                 cpu_buf->last_proc = proc;
289                 flags |= USER_CTX_SWITCH;
290         }
291
292         if (!flags) {
293                 poperror();
294                 /* nothing to do */
295                 //print_func_exit();
296                 return 0;
297         }
298
299         if (flags & USER_CTX_SWITCH)
300                 size = 1;
301         else
302                 size = 0;
303
304         b = op_cpu_buffer_write_reserve(cpu_buf, &entry, size);
305
306         entry.sample->eip = ESCAPE_CODE;
307         entry.sample->event = flags;
308
309         if (size)
310                 op_cpu_buffer_add_data(&entry, (unsigned long)proc);
311
312         poperror();
313         //print_func_exit();
314         return 0;
315 }
316
317 static inline int
318 op_add_sample(struct oprofile_cpu_buffer *cpu_buf,
319                           unsigned long pc, unsigned long event)
320 {
321         //print_func_entry();
322         ERRSTACK(1);
323         struct op_entry entry;
324         struct op_sample *sample;
325         struct block *b;
326
327         if (waserror()) {
328                 poperror();
329                 printk("%s: failed\n", __func__);
330                 //print_func_exit();
331                 return 1;
332         }
333
334         b = op_cpu_buffer_write_reserve(cpu_buf, &entry, 0);
335
336         sample = entry.sample;
337         sample->eip = pc;
338         sample->event = event;
339         poperror();
340         //print_func_exit();
341         return 0;
342 }
343
344 /*
345  * This must be safe from any context.
346  *
347  * is_kernel is needed because on some architectures you cannot
348  * tell if you are in kernel or user space simply by looking at
349  * pc. We tag this in the buffer by generating kernel enter/exit
350  * events whenever is_kernel changes
351  */
352 static int
353 log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc,
354                    unsigned long backtrace, int is_kernel, unsigned long event,
355                    struct proc *proc)
356 {
357         //print_func_entry();
358         struct proc *tsk = proc ? proc : current;
359         cpu_buf->sample_received++;
360
361         if (pc == ESCAPE_CODE) {
362                 cpu_buf->sample_invalid_eip++;
363                 //print_func_exit();
364                 return 0;
365         }
366
367         /* ah, so great. op_add* return 1 in event of failure.
368          * this function returns 0 in event of failure.
369          * what a cluster.
370          */
371         spin_lock_irqsave(&cpu_buf->lock);
372         if (op_add_code(cpu_buf, backtrace, is_kernel, tsk))
373                 goto fail;
374
375         if (op_add_sample(cpu_buf, pc, event))
376                 goto fail;
377         spin_unlock_irqsave(&cpu_buf->lock);
378
379         //print_func_exit();
380         return 1;
381
382 fail:
383         cpu_buf->sample_lost_overflow++;
384         //print_func_exit();
385         return 0;
386 }
387
388 static inline void oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf)
389 {
390         //print_func_entry();
391         cpu_buf->tracing = 1;
392         //print_func_exit();
393 }
394
395 static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf)
396 {
397         //print_func_entry();
398         cpu_buf->tracing = 0;
399         //print_func_exit();
400 }
401
402 void oprofile_cpubuf_flushone(int core, int newbuf)
403 {
404         //print_func_entry();
405         struct oprofile_cpu_buffer *cpu_buf;
406         cpu_buf = &op_cpu_buffer[core];
407         spin_lock_irqsave(&cpu_buf->lock);
408         if (cpu_buf->block) {
409                 printk("Core %d has data\n", core);
410                 qibwrite(opq, cpu_buf->block);
411                 printk("After qibwrite in %s, opq len %d\n", __func__, qlen(opq));
412         }
413         if (newbuf)
414                 cpu_buf->block = iallocb(oprofile_cpu_buffer_size);
415         else
416                 cpu_buf->block = NULL;
417         spin_unlock_irqsave(&cpu_buf->lock);
418         //print_func_exit();
419 }
420
421 void oprofile_cpubuf_flushall(int alloc)
422 {
423         //print_func_entry();
424         int core;
425
426         for(core = 0; core < num_cpus; core++) {
427                 oprofile_cpubuf_flushone(core, alloc);
428         }
429         //print_func_exit();
430 }
431
432 void oprofile_control_trace(int onoff)
433 {
434         //print_func_entry();
435         int core;
436         struct oprofile_cpu_buffer *cpu_buf;
437
438         for(core = 0; core < num_cpus; core++) {
439                 cpu_buf = &op_cpu_buffer[core];
440                 cpu_buf->tracing = onoff;
441
442                 if (onoff) {
443                         printk("Enable tracing on %d\n", core);
444                         continue;
445                 }
446
447                 /* halting. Force out all buffers. */
448                 oprofile_cpubuf_flushone(core, 0);
449         }
450         //print_func_exit();
451 }
452
453 static inline void
454 __oprofile_add_ext_sample(unsigned long pc,
455                                                   void /*struct pt_regs */ *const regs,
456                                                   unsigned long event, int is_kernel, struct proc *proc)
457 {
458         //print_func_entry();
459         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
460         unsigned long backtrace = oprofile_backtrace_depth;
461
462         /*
463          * if log_sample() fail we can't backtrace since we lost the
464          * source of this event
465          */
466         if (!log_sample(cpu_buf, pc, backtrace, is_kernel, event, proc))
467                 /* failed */
468         {
469                 //print_func_exit();
470                 return;
471         }
472
473         if (!backtrace) {
474                 //print_func_exit();
475                 return;
476         }
477 #if 0
478         oprofile_begin_trace(cpu_buf);
479         oprofile_ops.backtrace(regs, backtrace);
480         oprofile_end_trace(cpu_buf);
481 #endif
482         //print_func_exit();
483 }
484
485 void oprofile_add_ext_hw_sample(unsigned long pc,
486                                                                 void /*struct pt_regs */ *const regs,
487                                                                 unsigned long event, int is_kernel,
488                                                                 struct proc *proc)
489 {
490         //print_func_entry();
491         __oprofile_add_ext_sample(pc, regs, event, is_kernel, proc);
492         //print_func_exit();
493 }
494
495 void oprofile_add_ext_sample(unsigned long pc,
496                                                          void /*struct pt_regs */ *const regs,
497                                                          unsigned long event, int is_kernel)
498 {
499         //print_func_entry();
500         __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL);
501         //print_func_exit();
502 }
503
504 void oprofile_add_sample(void /*struct pt_regs */ *const regs,
505                                                  unsigned long event)
506 {
507         //print_func_entry();
508         int is_kernel;
509         unsigned long pc;
510
511         if (regs) {
512                 is_kernel = 0;  // FIXME!user_mode(regs);
513                 pc = 0; // FIXME profile_pc(regs);
514         } else {
515                 is_kernel = 0;  /* This value will not be used */
516                 pc = ESCAPE_CODE;       /* as this causes an early return. */
517         }
518
519         __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL);
520         //print_func_exit();
521 }
522
523 /*
524  * Add samples with data to the ring buffer.
525  *
526  * Use oprofile_add_data(&entry, val) to add data and
527  * oprofile_write_commit(&entry) to commit the sample.
528  */
529 void
530 oprofile_write_reserve(struct op_entry *entry,
531                                            void /*struct pt_regs */ *const regs,
532                                            unsigned long pc, int code, int size)
533 {
534         //print_func_entry();
535         ERRSTACK(1);
536         struct op_sample *sample;
537         struct block *b;
538         int is_kernel = 0;                      // FIXME!user_mode(regs);
539         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
540
541         if (waserror()) {
542                 printk("%s: failed\n", __func__);
543                 poperror();
544                 goto fail;
545         }
546         cpu_buf->sample_received++;
547
548         /* no backtraces for samples with data */
549         if (op_add_code(cpu_buf, 0, is_kernel, current))
550                 goto fail;
551
552         b = op_cpu_buffer_write_reserve(cpu_buf, entry, size + 2);
553         sample = entry->sample;
554         sample->eip = ESCAPE_CODE;
555         sample->event = 0;      /* no flags */
556
557         op_cpu_buffer_add_data(entry, code);
558         op_cpu_buffer_add_data(entry, pc);
559         poperror();
560         //print_func_exit();
561         return;
562 fail:
563         entry->event = NULL;
564         cpu_buf->sample_lost_overflow++;
565         //print_func_exit();
566 }
567
568 int oprofile_add_data(struct op_entry *entry, unsigned long val)
569 {
570         //print_func_entry();
571         if (!entry->event) {
572                 //print_func_exit();
573                 return 0;
574         }
575         //print_func_exit();
576         return op_cpu_buffer_add_data(entry, val);
577 }
578
579 int oprofile_add_data64(struct op_entry *entry, uint64_t val)
580 {
581         //print_func_entry();
582         if (!entry->event) {
583                 //print_func_exit();
584                 return 0;
585         }
586         if (op_cpu_buffer_get_size(entry) < 2)
587                 /*
588                  * the function returns 0 to indicate a too small
589                  * buffer, even if there is some space left
590                  */
591         {
592                 //print_func_exit();
593                 return 0;
594         }
595         if (!op_cpu_buffer_add_data(entry, (uint32_t) val)) {
596                 //print_func_exit();
597                 return 0;
598         }
599         //print_func_exit();
600         return op_cpu_buffer_add_data(entry, (uint32_t) (val >> 32));
601 }
602
603 int oprofile_write_commit(struct op_entry *entry)
604 {
605         //print_func_entry();
606         /* not much to do at present. In future, we might write the Block
607          * to opq.
608          */
609         //print_func_exit();
610         return 0;
611 }
612
613 void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
614 {
615         //print_func_entry();
616         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
617         log_sample(cpu_buf, pc, 0, is_kernel, event, NULL);
618         //print_func_exit();
619 }
620
621 void oprofile_add_trace(unsigned long pc)
622 {
623         if (! op_cpu_buffer)
624                 return;
625         //print_func_entry();
626         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
627
628         if (!cpu_buf->tracing) {
629                 //print_func_exit();
630                 return;
631         }
632
633         /*
634          * broken frame can give an eip with the same value as an
635          * escape code, abort the trace if we get it
636          */
637         if (pc == ESCAPE_CODE)
638                 goto fail;
639         if (op_add_sample(cpu_buf, pc, nsec()&~0xf))
640                 goto fail;
641
642         //print_func_exit();
643         return;
644 fail:
645         printk("%s: fail. Turning of tracing on cpu %d\n", core_id());
646         cpu_buf->tracing = 0;
647         cpu_buf->backtrace_aborted++;
648         //print_func_exit();
649         return;
650 }
651
652 /* Format for samples:
653  * first word:
654  * high 8 bits is ee, which is an invalid address on amd64. 
655  * next 8 bits is protocol version
656  * next 16 bits is unused, MBZ. Later, we can make it a packet type. 
657  * next 16 bits is core id
658  * next 8 bits is unused
659  * next 8 bits is # PCs following. This should be at least 1, for one EIP.
660  *
661  * second word is time in ns.
662  * 
663  * Third and following words are PCs, there must be at least one of them. 
664  */
665 void oprofile_add_backtrace(uintptr_t pc, uintptr_t fp)
666 {
667         /* version 1. */
668         uint64_t descriptor = 0xee01ULL<<48;
669         if (! op_cpu_buffer)
670                 return;
671         //print_func_entry();
672         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
673
674         if (!cpu_buf->tracing) {
675                 //print_func_exit();
676                 return;
677         }
678
679         struct op_entry entry;
680         struct op_sample *sample;
681         struct block *b;
682         uint64_t event = nsec();
683
684         uintptr_t bt_pcs[oprofile_backtrace_depth];
685
686         int nr_pcs;
687         nr_pcs = backtrace_list(pc, fp, bt_pcs, oprofile_backtrace_depth);
688
689         /* write_reserve always assumes passed-in-size + 2.
690          * backtrace_depth should always be > 0.
691          */
692         b = op_cpu_buffer_write_reserve(cpu_buf, &entry, nr_pcs);
693
694         if (! b)
695                 return;
696
697         /* we are changing the sample format, but not the struct
698          * member names yet. Later, assuming this works out.
699          */
700         descriptor |= (core_id() << 16) | nr_pcs;
701         sample = entry.sample;
702         sample->eip = descriptor;
703         sample->event = event;
704         memcpy(sample->data, bt_pcs, sizeof(uintptr_t) * nr_pcs);
705
706         //print_func_exit();
707         return;
708 fail:
709         printk("%s: fail. Turning of tracing on cpu %d\n", core_id());
710         cpu_buf->tracing = 0;
711         cpu_buf->backtrace_aborted++;
712         //print_func_exit();
713         return;
714 }
715
716 void oprofile_add_userpc(uintptr_t pc)
717 {
718         struct oprofile_cpu_buffer *cpu_buf;
719         uint32_t pcoreid = core_id();
720         struct op_entry entry;
721         struct block *b;
722         uint64_t descriptor = (0xee01ULL << 48) | (pcoreid << 16) | 1;
723
724         if (!op_cpu_buffer)
725                 return;
726         cpu_buf = &op_cpu_buffer[pcoreid];
727         if (!cpu_buf->tracing)
728                 return;
729         /* write_reserve always assumes passed-in-size + 2.  need room for 1 PC. */
730         b = op_cpu_buffer_write_reserve(cpu_buf, &entry, 1);
731         if (!b)
732                 return;
733         entry.sample->eip = descriptor;
734         entry.sample->event = nsec();
735         /* entry.sample->data == entry.data */
736         assert(entry.sample->data == entry.data);
737         *entry.sample->data = pc;
738 }
739
740 int
741 oproflen(void)
742 {
743         return qlen(opq);
744 }
745
746 /* return # bytes read, or 0 if profiling is off, or block if profiling on and no data.
747  */
748 int
749 oprofread(void *va, int n)
750 {
751         int len = qlen(opq);
752         struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
753         if (len == 0) {
754                 if (cpu_buf->tracing == 0)
755                         return 0;
756         }
757
758         len = qread(opq, va, n);
759         return len;
760 }