From 091550d652f58ecbb8772e18ef1471ddeb96cc8b Mon Sep 17 00:00:00 2001 From: Igor Nabirushkin Date: Tue, 2 Dec 2014 15:23:26 +0400 Subject: tegra-profiler: record offset of the stack pointer Tegra Profiler: when collecting backtraces, record remaining data stack size. Bug 1584533 Bug 1598009 Change-Id: I608ab73f8e1b7da84221a17a782080fdf5598111 Signed-off-by: Igor Nabirushkin Reviewed-on: http://git-master/r/658431 (cherry picked from commit 803c1a41e9b7ebcbf297bd7ce5caeed1d1f800ce) Reviewed-on: http://git-master/r/672039 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Venkat Moganty --- drivers/misc/tegra-profiler/hrt.c | 42 +++++++++++++++++++++++++++++++++++ drivers/misc/tegra-profiler/hrt.h | 1 + drivers/misc/tegra-profiler/main.c | 8 +++---- drivers/misc/tegra-profiler/version.h | 2 +- include/linux/tegra_profiler.h | 11 +++++++-- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/misc/tegra-profiler/hrt.c b/drivers/misc/tegra-profiler/hrt.c index 1850f3f8003c..b7bd00c795ac 100644 --- a/drivers/misc/tegra-profiler/hrt.c +++ b/drivers/misc/tegra-profiler/hrt.c @@ -186,6 +186,9 @@ static void put_header(void) if (hrt.use_arch_timer) hdr->reserved |= QUADD_HDR_USE_ARCH_TIMER; + if (hrt.get_stack_offset) + hdr->reserved |= QUADD_HDR_STACK_OFFSET; + if (pmu) nr_events += pmu->get_current_events(events, max_events); @@ -295,6 +298,28 @@ static int read_source(struct quadd_event_source_interface *source, return nr_events; } +static long +get_stack_offset(struct task_struct *task, + struct pt_regs *regs, + struct quadd_callchain *cc) +{ + unsigned long sp; + struct vm_area_struct *vma; + struct mm_struct *mm = task->mm; + + if (!regs || !mm) + return -ENOMEM; + + sp = cc->nr > 0 ? cc->curr_sp : + quadd_user_stack_pointer(regs); + + vma = find_vma(mm, sp); + if (!vma) + return -ENOMEM; + + return vma->vm_end - sp; +} + static void read_all_sources(struct pt_regs *regs, struct task_struct *task) { @@ -355,6 +380,11 @@ read_all_sources(struct pt_regs *regs, struct task_struct *task) s->reserved = 0; + cc->nr = 0; + cc->curr_sp = 0; + cc->curr_fp = 0; + cc->curr_pc = 0; + if (ctx->param.backtrace) { cc->unw_method = hrt.unw_method; bt_size = quadd_get_user_callchain(user_regs, cc, ctx, task); @@ -394,6 +424,15 @@ read_all_sources(struct pt_regs *regs, struct task_struct *task) } s->callchain_nr = bt_size; + if (hrt.get_stack_offset) { + long offset = get_stack_offset(task, user_regs, cc); + if (offset > 0) { + u32 off = offset >> 2; + off = min_t(u32, off, 0xffff); + extra_data |= off << QUADD_SED_STACK_OFFSET_SHIFT; + } + } + record_data.record_type = QUADD_RECORD_TYPE_SAMPLE; s->events_flags = 0; @@ -627,6 +666,9 @@ int quadd_hrt_start(void) pr_info("timer: %s\n", hrt.use_arch_timer ? "arch" : "monotonic clock"); + hrt.get_stack_offset = + (extra & QUADD_PARAM_EXTRA_STACK_OFFSET) ? 1 : 0; + put_header(); if (extra & QUADD_PARAM_EXTRA_GET_MMAP) { diff --git a/drivers/misc/tegra-profiler/hrt.h b/drivers/misc/tegra-profiler/hrt.h index 47662fbf7682..3361c61e6f3f 100644 --- a/drivers/misc/tegra-profiler/hrt.h +++ b/drivers/misc/tegra-profiler/hrt.h @@ -65,6 +65,7 @@ struct quadd_hrt_ctx { int use_arch_timer; unsigned int unw_method; + int get_stack_offset; }; #define QUADD_HRT_MIN_FREQ 100 diff --git a/drivers/misc/tegra-profiler/main.c b/drivers/misc/tegra-profiler/main.c index 1e967a419bef..f0116af49035 100644 --- a/drivers/misc/tegra-profiler/main.c +++ b/drivers/misc/tegra-profiler/main.c @@ -518,11 +518,11 @@ static int __init quadd_module_init(void) QUADD_MAX_COUNTERS); ctx.pmu_info.nr_supported_events = nr_events; - pr_info("PMU: amount of events: %d\n", nr_events); + pr_debug("PMU: amount of events: %d\n", nr_events); for (i = 0; i < nr_events; i++) - pr_info("PMU event: %s\n", - quadd_get_event_str(events[i])); + pr_debug("PMU event: %s\n", + quadd_get_event_str(events[i])); } #ifdef CONFIG_CACHE_L2X0 @@ -543,7 +543,7 @@ static int __init quadd_module_init(void) pr_info("pl310 event: %s\n", quadd_get_event_str(events[i])); } else { - pr_info("PL310 not found\n"); + pr_debug("PL310 not found\n"); } ctx.hrt = quadd_hrt_init(&ctx); diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h index 88210df23026..3836f6683f55 100644 --- a/drivers/misc/tegra-profiler/version.h +++ b/drivers/misc/tegra-profiler/version.h @@ -18,7 +18,7 @@ #ifndef __QUADD_VERSION_H #define __QUADD_VERSION_H -#define QUADD_MODULE_VERSION "1.84" +#define QUADD_MODULE_VERSION "1.85" #define QUADD_MODULE_BRANCH "Dev" #endif /* __QUADD_VERSION_H */ diff --git a/include/linux/tegra_profiler.h b/include/linux/tegra_profiler.h index ad62d9a8e918..4225e7e9274e 100644 --- a/include/linux/tegra_profiler.h +++ b/include/linux/tegra_profiler.h @@ -19,8 +19,8 @@ #include -#define QUADD_SAMPLES_VERSION 30 -#define QUADD_IO_VERSION 15 +#define QUADD_SAMPLES_VERSION 31 +#define QUADD_IO_VERSION 16 #define QUADD_IO_VERSION_DYNAMIC_RB 5 #define QUADD_IO_VERSION_RB_MAX_FILL_COUNT 6 @@ -33,6 +33,7 @@ #define QUADD_IO_VERSION_ARCH_TIMER_OPT 13 #define QUADD_IO_VERSION_DATA_MMAP 14 #define QUADD_IO_VERSION_BT_LOWER_BOUND 15 +#define QUADD_IO_VERSION_STACK_OFFSET 16 #define QUADD_SAMPLE_VERSION_THUMB_MODE_FLAG 17 #define QUADD_SAMPLE_VERSION_GROUP_SAMPLES 18 @@ -46,6 +47,7 @@ #define QUADD_SAMPLE_VERSION_SCHED_SAMPLES 28 #define QUADD_SAMPLE_VERSION_HDR_UNW_METHOD 29 #define QUADD_SAMPLE_VERSION_HDR_ARCH_TIMER 30 +#define QUADD_SAMPLE_VERSION_STACK_OFFSET 31 #define QUADD_MMAP_HEADER_VERSION 1 @@ -192,6 +194,9 @@ enum { #define QUADD_SED_UNW_METHOD_SHIFT 1 #define QUADD_SED_UNW_METHOD_MASK (0x07 << QUADD_SED_UNW_METHOD_SHIFT) +#define QUADD_SED_STACK_OFFSET_SHIFT 4 +#define QUADD_SED_STACK_OFFSET_MASK (0xffff << QUADD_SED_STACK_OFFSET_SHIFT) + enum { QUADD_UNW_TYPE_FP = 0, QUADD_UNW_TYPE_UT, @@ -302,6 +307,7 @@ struct quadd_debug_data { #define QUADD_HDR_UNW_METHOD_MASK (0x07 << QUADD_HDR_UNW_METHOD_SHIFT) #define QUADD_HDR_USE_ARCH_TIMER (1 << 3) +#define QUADD_HDR_STACK_OFFSET (1 << 4) struct quadd_header_data { u16 magic; @@ -354,6 +360,7 @@ enum { #define QUADD_PARAM_EXTRA_BT_UNWIND_TABLES (1 << 2) #define QUADD_PARAM_EXTRA_BT_MIXED (1 << 3) #define QUADD_PARAM_EXTRA_USE_ARCH_TIMER (1 << 4) +#define QUADD_PARAM_EXTRA_STACK_OFFSET (1 << 5) struct quadd_parameters { u32 freq; -- cgit v1.2.3