oprofile: sampling works
authorRonald G. Minnich <rminnich@google.com>
Fri, 23 May 2014 02:49:46 +0000 (19:49 -0700)
committerRonald G. Minnich <rminnich@google.com>
Fri, 23 May 2014 02:49:46 +0000 (19:49 -0700)
ash /ifconfig
echo opstart > /prof/kpctl
do stuff
echo opstop > /prof/kpctl

cat /prof/kpoprofile > /whatever (or 9p place)
profit.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/drivers/dev/kprof.c
kern/include/oprofile.h
kern/src/oprofile/cpu_buffer.c

index 8df568d..042d86e 100644 (file)
@@ -72,9 +72,6 @@ struct dirtab kproftab[]={
        {"kpoprofile",  {Kprofoprofileqid},     0,      0600},
 };
 
-/* the oprofile queue */
-extern struct queue *opq;
-
 static struct chan*
 kprofattach(char *spec)
 {
@@ -175,7 +172,7 @@ static int
 kprofstat(struct chan *c, uint8_t *db, int n)
 {
        /* barf. */
-       kproftab[3].length = qlen(opq);
+       kproftab[3].length = oproflen();
 
        return devstat(c, db, n, kproftab, ARRAY_SIZE(kproftab), devgen);
 }
@@ -271,7 +268,7 @@ kprofread(struct chan *c, void *va, long n, int64_t off)
                n = ret;
                break;
        case Kprofoprofileqid:
-               n = qread(opq, va, n);
+               n = oprofread(va,n);
                break;
        default:
                n = 0;
index fcf33b3..914bd84 100644 (file)
@@ -146,6 +146,8 @@ unsigned long op_cpu_buffer_entries(int cpu);
 void oprofile_cpubuf_flushone(int core, int newbuf);
 void oprofile_cpubuf_flushall(int alloc);
 void oprofile_control_trace(int onoff);
+int oprofread(void *,int);
+int oproflen(void);
 
 #if 0 
 make these weak funcitons. 
index a94483d..32bee6c 100644 (file)
@@ -29,7 +29,7 @@
 struct oprofile_cpu_buffer *op_cpu_buffer;
 
 /* this one queue is used by #K to get all events. */
-struct queue *opq;
+static struct queue *opq;
 
 /* this is run from core 0 for all cpu buffers. */
 static void wq_sync_buffer(void);
@@ -138,7 +138,7 @@ int alloc_cpu_buffers(void)
         */
        /* what limit? No idea. */
        if (!opq)
-               opq = qopen(1024, Qmsg, NULL, NULL);
+               opq = qopen(1024, 0, NULL, NULL);
        if (!opq)
                goto fail;
 
@@ -228,9 +228,9 @@ static struct block *op_cpu_buffer_write_reserve(struct oprofile_cpu_buffer *cpu
        b = cpu_buf->block;
        /* we might have run out. */
        if ((! b) || (b->lim - b->wp) < size) {
-               if (b)
+               if (b){
                        qibwrite(opq, b);
-               printk("After qibwrite in %s, opq len %d\n", __func__, qlen(opq));
+               }
                /* For now. Later, we will grab a block off the
                 * emptyblock queue.
                 */
@@ -637,7 +637,6 @@ void oprofile_add_trace(unsigned long pc)
         */
        if (pc == ESCAPE_CODE)
                goto fail;
-
        if (op_add_sample(cpu_buf, pc, nsec()))
                goto fail;
 
@@ -650,3 +649,25 @@ fail:
        //print_func_exit();
        return;
 }
+
+int
+oproflen(void)
+{
+       return qlen(opq);
+}
+
+/* return # bytes read, or 0 if profiling is off, or block if profiling on and no data.
+ */
+int
+oprofread(void *va, int n)
+{
+       int len = qlen(opq);
+       struct oprofile_cpu_buffer *cpu_buf = &op_cpu_buffer[core_id()];
+       if (len == 0) {
+               if (cpu_buf->tracing == 0)
+                       return 0;
+       }
+
+       len = qread(opq, va, n);
+       return len;
+}