summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2014-12-02 15:23:26 +0400
committerWinnie Hsu <whsu@nvidia.com>2015-01-29 22:04:31 -0800
commit091550d652f58ecbb8772e18ef1471ddeb96cc8b (patch)
tree938e7b3de324da3f61e1942f20fddff286b25b70
parente37209ae78a8b668a5779911a6a2b7a7ac753743 (diff)
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 <inabirushkin@nvidia.com> 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 <vmoganty@nvidia.com>
-rw-r--r--drivers/misc/tegra-profiler/hrt.c42
-rw-r--r--drivers/misc/tegra-profiler/hrt.h1
-rw-r--r--drivers/misc/tegra-profiler/main.c8
-rw-r--r--drivers/misc/tegra-profiler/version.h2
-rw-r--r--include/linux/tegra_profiler.h11
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 <linux/ioctl.h>
-#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;