9ns: Fix devtab function pointer signatures
[akaros.git] / kern / drivers / dev / kprof.c
index c2b90d2..cbc7b1c 100644 (file)
@@ -27,6 +27,7 @@
 #include <profiler.h>
 #include <kprof.h>
 #include <ros/procinfo.h>
+#include <init.h>
 
 #define KTRACE_BUFFER_SIZE (128 * 1024)
 #define TRACE_PRINTK_BUFFER_SIZE (8 * 1024)
@@ -35,6 +36,7 @@ enum {
        Kprofdirqid = 0,
        Kprofdataqid,
        Kprofctlqid,
+       Kptracectlqid,
        Kptraceqid,
        Kprintxqid,
        Kmpstatqid,
@@ -58,6 +60,7 @@ struct dirtab kproftab[] = {
        {".",                   {Kprofdirqid,           0, QTDIR}, 0,   DMDIR|0550},
        {"kpdata",              {Kprofdataqid},         0,      0600},
        {"kpctl",               {Kprofctlqid},          0,      0600},
+       {"kptrace_ctl", {Kptracectlqid},        0,      0660},
        {"kptrace",             {Kptraceqid},           0,      0600},
        {"kprintx",             {Kprintxqid},           0,      0600},
        {"mpstat",              {Kmpstatqid},           0,      0600},
@@ -182,7 +185,7 @@ static void kprof_shutdown(void)
 }
 
 static struct walkqid *kprof_walk(struct chan *c, struct chan *nc, char **name,
-                                  int nname)
+                                  unsigned int nname)
 {
        return devwalk(c, nc, name, nname, kproftab, ARRAY_SIZE(kproftab), devgen);
 }
@@ -197,7 +200,7 @@ static long kprof_profdata_read(void *dest, long size, int64_t off)
        return profiler_read(dest, size);
 }
 
-static int kprof_stat(struct chan *c, uint8_t *db, int n)
+static size_t kprof_stat(struct chan *c, uint8_t *db, size_t n)
 {
        kproftab[Kprofdataqid].length = kprof_profdata_size();
        kproftab[Kptraceqid].length = kprof_tracedata_size();
@@ -317,7 +320,7 @@ static long mpstatraw_read(void *va, long n, int64_t off)
        return n;
 }
 
-static long kprof_read(struct chan *c, void *va, long n, int64_t off)
+static size_t kprof_read(struct chan *c, void *va, size_t n, off64_t off)
 {
        uint64_t w, *bp;
        char *a, *ea;
@@ -349,7 +352,7 @@ static long kprof_read(struct chan *c, void *va, long n, int64_t off)
        return n;
 }
 
-static long kprof_write(struct chan *c, void *a, long n, int64_t unused)
+static size_t kprof_write(struct chan *c, void *a, size_t n, off64_t unused)
 {
        ERRSTACK(1);
        struct cmdbuf *cb = parsecmd(a, n);
@@ -374,12 +377,21 @@ static long kprof_write(struct chan *c, void *a, long n, int64_t unused)
                        error(EFAIL, kprof_control_usage);
                }
                break;
+       case Kptracectlqid:
+               if (cb->nf < 1)
+                       error(EFAIL, "Bad kptrace_ctl option (reset)");
+               if (!strcmp(cb->f[0], "clear")) {
+                       spin_lock_irqsave(&ktrace_lock);
+                       circular_buffer_clear(&ktrace_data);
+                       spin_unlock_irqsave(&ktrace_lock);
+               }
+               break;
        case Kptraceqid:
                if (a && (n > 0)) {
                        char *uptr = user_strdup_errno(current, a, n);
 
                        if (uptr) {
-                               trace_printk(false, "%s", uptr);
+                               trace_printk("%s", uptr);
                                user_memdup_free(current, uptr);
                        } else {
                                n = -1;
@@ -445,6 +457,17 @@ size_t kprof_tracedata_read(void *data, size_t size, size_t offset)
        return size;
 }
 
+void kprof_dump_data(void)
+{
+       void *buf;
+       size_t len = kprof_tracedata_size();
+
+       buf = kmalloc(len, MEM_WAIT);
+       kprof_tracedata_read(buf, len, 0);
+       printk("%s", buf);
+       kfree(buf);
+}
+
 void kprof_tracedata_write(const char *pretty_buf, size_t len)
 {
        spin_lock_irqsave(&ktrace_lock);
@@ -463,7 +486,7 @@ static struct trace_printk_buffer *kprof_get_printk_buffer(void)
        static struct trace_printk_buffer *cpu_tpbs;
        static atomic_t alloc_done;
 
-       if (unlikely(!num_cores))
+       if (unlikely(booting))
                return &boot_tpb;
        if (unlikely(!cpu_tpbs)) {
                /* Poor man per-CPU data structure. I really do no like littering global
@@ -481,7 +504,7 @@ static struct trace_printk_buffer *kprof_get_printk_buffer(void)
        return cpu_tpbs + core_id_early();
 }
 
-void trace_vprintk(bool btrace, const char *fmt, va_list args)
+void trace_vprintk(const char *fmt, va_list args)
 {
        struct print_buf {
                char *ptr;
@@ -499,14 +522,6 @@ void trace_vprintk(bool btrace, const char *fmt, va_list args)
                }
        }
 
-       void bt_print(void *opaque, const char *str)
-       {
-               struct print_buf *pb = (struct print_buf *) opaque;
-
-               emit_print_buf_str(pb, "\t", 1);
-               emit_print_buf_str(pb, str, -1);
-       }
-
        static const size_t bufsz = TRACE_PRINTK_BUFFER_SIZE;
        static const size_t usr_bufsz = (3 * bufsz) / 8;
        static const size_t kp_bufsz = bufsz - usr_bufsz;
@@ -529,10 +544,6 @@ void trace_vprintk(bool btrace, const char *fmt, va_list args)
 
        if (pb.ptr[-1] != '\n')
                emit_print_buf_str(&pb, "\n", 1);
-       if (btrace) {
-               emit_print_buf_str(&pb, "\tBacktrace:\n", -1);
-               gen_backtrace(bt_print, &pb);
-       }
        /* snprintf null terminates the buffer, and does not count that as part of
         * the len.  If we maxed out the buffer, let's make sure it has a \n.
         */
@@ -555,12 +566,12 @@ void trace_vprintk(bool btrace, const char *fmt, va_list args)
        atomic_set(&tpb->in_use, 0);
 }
 
-void trace_printk(bool btrace, const char *fmt, ...)
+void trace_printk(const char *fmt, ...)
 {
        va_list args;
 
        va_start(args, fmt);
-       trace_vprintk(btrace, fmt, args);
+       trace_vprintk(fmt, args);
        va_end(args);
 }