From ae77f078d3a1ef81639a73db75b9264f1634889b Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Thu, 29 Oct 2009 07:31:31 -0400 Subject: [PATCH] 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 -- 2.7.4