Kprof samples during the timer IRQ
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 22 May 2014 21:54:37 +0000 (14:54 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 22 May 2014 21:54:37 +0000 (14:54 -0700)
It's a bit cheap, since the timer won't rearm til we handle RKMs.  This means
that during heavy activity, we might not take the samples as frequently.  I've
got some ideas to fix this.  For now, we can at least get a sample from IRQ
context.

kern/drivers/dev/kprof.c
kern/include/smp.h
kern/src/time.c

index 252674b..8df568d 100644 (file)
@@ -137,19 +137,27 @@ kproftimer(uintptr_t pc)
 
 static void setup_timers(void)
 {
-       void handler(struct alarm_waiter *waiter)
+       void dummy_alarm(struct alarm_waiter *waiter)
        {
                struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
-               kproftimer(per_cpu_info[core_id()].rip);
                set_awaiter_rel(waiter, 1000);
                __set_alarm(tchain, waiter);
        }
+       void kprof_irq_handler(struct hw_trapframe *hw_tf, void *data)
+       {
+               kproftimer(x86_get_hwtf_pc(hw_tf));     /* TODO arch */
+       }
        struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
        struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
-       init_awaiter(waiter, handler);
+       init_awaiter(waiter, dummy_alarm);
        set_awaiter_rel(waiter, 1000);
+       /* with this style, the timer IRQ goes off and runs us, but doesn't get
+        * reprogrammed til the next alarm. TODO: irq/rkm alarms. */
+       register_irq(IdtLAPIC_TIMER, kprof_irq_handler, NULL,
+                    MKBUS(BusLAPIC, 0, 0, 0));
        set_alarm(tchain, waiter);
 }
+
 static void
 kprofinit(void)
 {
index 7f2b9ab..4b17ba1 100644 (file)
@@ -29,8 +29,6 @@ typedef sharC_env_t;
 struct per_cpu_info {
 #ifdef CONFIG_X86_64
        uintptr_t stacktop;
-       /* the rip at the last clock interrupt. For profiling. */
-       uintptr_t rip;
        /* virtual machines */
        /* this is all kind of gross, but so it goes. Kmalloc
         * the vmxarea. It varies in size depending on the architecture.
index 3be9d8f..cd886ef 100644 (file)
@@ -59,8 +59,6 @@ void timer_interrupt(struct hw_trapframe *hw_tf, void *data)
        int coreid = core_id();
        /* run the alarms out of RKM context, so that event delivery works nicely
         * (keeps the proc lock and ksched lock non-irqsave) */
-       /* this is about the only place we can stash this info. */
-       per_cpu_info[coreid].rip = hw_tf->tf_rip;
        send_kernel_message(coreid, __trigger_tchain,
                            (long)&per_cpu_info[coreid].tchain, 0, 0, KMSG_ROUTINE);
 }