[sysprof] Skip symbols from IRQ stack.



commit ae77f078d3a1ef81639a73db75b9264f1634889b
Author: Søren Sandmann Pedersen <sandmann daimi au dk>
Date:   Thu Oct 29 07:31:31 2009 -0400

    Skip symbols from IRQ stack.
    
    There is a bug in the kernel where it includes the stack of the IRQ
    that generated the event, so that the stack ends up looking like this:
    
    	[ip] [irq stack] [real stack].
    
    As a temporary workaround, this patch filters out the irq stack
    symbols.

 collector.c |    2 +-
 tracker.c   |   44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 2 deletions(-)
---
diff --git a/collector.c b/collector.c
index aa0fe03..4b75f2d 100644
--- a/collector.c
+++ b/collector.c
@@ -362,7 +362,7 @@ counter_new (Collector *collector,
 	{
 	    attr.type = PERF_TYPE_SOFTWARE;
 	    attr.config = PERF_COUNT_SW_CPU_CLOCK;
-	    attr.sample_period = 2000000;
+	    attr.sample_period = 1000000;
 
 	    fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0);
 	}
diff --git a/tracker.c b/tracker.c
index ac60cf5..c8f7915 100644
--- a/tracker.c
+++ b/tracker.c
@@ -727,18 +727,60 @@ get_kernel_symbols (void)
     return kernel_syms;
 }
 
+static const char skip_kernel_symbols[][32]  =
+{
+    "common_interrupt",
+    "apic_timer_interrupt",
+    "smp_apic_timer_interrupt",
+    "hrtimer_interrupt",
+    "__run_hrtimer",
+    "perf_swevent_hrtimer",
+    "perf_event_overflow",
+    "__perf_event_overflow",
+    "perf_prepare_sample",
+    "perf_callchain",
+    ""
+};
+
 const char *
 lookup_kernel_symbol (gulong address)
 {
     kernel_symbol_t *result;
     GArray *ksyms = get_kernel_symbols ();
+    const char *sym;
+    const char *s;
+    int i;
     
     if (ksyms->len == 0)
 	return NULL;
     
     result = do_lookup ((kernel_symbol_t *)ksyms->data, address, 0, ksyms->len - 1);
     
-    return result? result->name : NULL;
+    sym = result? result->name : NULL;
+
+
+    /* This is a workaround for a kernel bug, where it reports not
+     * only the kernel stack, but also the IRQ stack for the
+     * timer interrupt that generated the stack.
+     *
+     * The stack as reported by the kernel looks like this:
+     *
+     * [ip] [irq stack] [real kernel stack]
+     *
+     * Below we filter out the [irq stack]
+     */
+    i = 0;
+    while (skip_kernel_symbols[i][0] != '\0')
+    {
+	if (strcmp (sym, skip_kernel_symbols[i]) == 0)
+	{
+	    sym = NULL;
+	    break;
+	}
+	i++;
+    }
+
+    return sym;
 }
 
 /* Note that 'unique_symbols' is a direct_hash table. Ie., we



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]