summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2014-01-27 01:28:57 +0400
committerRiham Haidar <rhaidar@nvidia.com>2014-02-19 16:09:40 -0800
commitdc6c3f57c97814269da805492139e95056c48579 (patch)
tree1be36ec5fc4320df71c8c46407ed1224344c45c8
parent7e3458cef594184e0244627a3f40f4a22cfeedf5 (diff)
misc: tegra-profiler: add thread state field
Tegra Profiler: state, in_interrupt fields were added into samples Bug 1447655 Change-Id: I082b63ff854da34df45160a6f07dbe5ee73ca7f7 Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com> Reviewed-on: http://git-master/r/365867 (cherry picked from commit 868545a99d8385a850fc87a4ad97dc8fb44a6e76) Reviewed-on: http://git-master/r/368212 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Tested-by: Maxim Morin <mmorin@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/misc/tegra-profiler/comm.c6
-rw-r--r--drivers/misc/tegra-profiler/hrt.c73
-rw-r--r--drivers/misc/tegra-profiler/version.h2
-rw-r--r--include/linux/tegra_profiler.h7
4 files changed, 61 insertions, 27 deletions
diff --git a/drivers/misc/tegra-profiler/comm.c b/drivers/misc/tegra-profiler/comm.c
index 8d15fb1cc296..c91af7c3f003 100644
--- a/drivers/misc/tegra-profiler/comm.c
+++ b/drivers/misc/tegra-profiler/comm.c
@@ -18,13 +18,15 @@
#include <linux/module.h>
#include <linux/fs.h>
-#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/bitops.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
#include <linux/tegra_profiler.h>
@@ -282,6 +284,8 @@ static ssize_t read_sample(char __user *buffer, size_t max_length)
nr_events = __sw_hweight32(record.sample.events_flags);
length_extra += nr_events * sizeof(u32);
+
+ length_extra += sample->state ? sizeof(u32) : 0;
break;
case QUADD_RECORD_TYPE_MMAP:
diff --git a/drivers/misc/tegra-profiler/hrt.c b/drivers/misc/tegra-profiler/hrt.c
index 945708cb3fef..d1a67c61bf80 100644
--- a/drivers/misc/tegra-profiler/hrt.c
+++ b/drivers/misc/tegra-profiler/hrt.c
@@ -19,13 +19,15 @@
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>
-#include <asm/cputype.h>
#include <linux/hrtimer.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/ratelimit.h>
-#include <asm/irq_regs.h>
#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+
+#include <asm/cputype.h>
+#include <asm/irq_regs.h>
#include <linux/tegra_profiler.h>
@@ -40,7 +42,8 @@
static struct quadd_hrt_ctx hrt;
-static void read_all_sources(struct pt_regs *regs, pid_t pid);
+static void
+read_all_sources(struct pt_regs *regs, struct task_struct *task);
struct hrt_event_value {
int event_id;
@@ -59,7 +62,7 @@ static enum hrtimer_restart hrtimer_handler(struct hrtimer *hrtimer)
qm_debug_handler_sample(regs);
if (regs)
- read_all_sources(regs, -1);
+ read_all_sources(regs, NULL);
hrtimer_forward_now(hrtimer, ns_to_ktime(hrt.sample_period));
qm_debug_timer_forward(regs, hrt.sample_period);
@@ -161,12 +164,11 @@ void quadd_put_sample(struct quadd_record_data *data,
}
static int get_sample_data(struct quadd_sample_data *sample,
- struct pt_regs *regs, pid_t pid)
+ struct pt_regs *regs,
+ struct task_struct *task)
{
unsigned int cpu, flags;
- struct quadd_thread_data *t_data;
struct quadd_ctx *quadd_ctx = hrt.quadd_ctx;
- struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
cpu = quadd_get_processor_id(regs, &flags);
sample->cpu = cpu;
@@ -186,20 +188,16 @@ static int get_sample_data(struct quadd_sample_data *sample,
sample->time = quadd_get_time();
sample->reserved = 0;
-
- if (pid > 0) {
- sample->pid = pid;
- } else {
- t_data = &cpu_ctx->active_thread;
- sample->pid = t_data->pid;
- }
+ sample->pid = task->pid;
+ sample->in_interrupt = in_interrupt() ? 1 : 0;
return 0;
}
static int read_source(struct quadd_event_source_interface *source,
- struct pt_regs *regs, pid_t pid,
- struct hrt_event_value *events_vals, int max_events)
+ struct pt_regs *regs,
+ struct hrt_event_value *events_vals,
+ int max_events)
{
int nr_events, i;
u32 prev_val, val, res_val;
@@ -235,12 +233,14 @@ static int read_source(struct quadd_event_source_interface *source,
return nr_events;
}
-static void read_all_sources(struct pt_regs *regs, pid_t pid)
+static void
+read_all_sources(struct pt_regs *regs, struct task_struct *task)
{
+ u32 state;
int i, vec_idx = 0, bt_size = 0;
int nr_events = 0, nr_positive_events = 0;
struct pt_regs *user_regs;
- struct quadd_iovec vec[2];
+ struct quadd_iovec vec[3];
struct hrt_event_value events[QUADD_MAX_COUNTERS];
u32 events_extra[QUADD_MAX_COUNTERS];
@@ -257,14 +257,31 @@ static void read_all_sources(struct pt_regs *regs, pid_t pid)
if (atomic_read(&cpu_ctx->nr_active) == 0)
return;
- quadd_get_mmap_object(cpu_ctx, regs, pid);
+ if (!task) {
+ pid_t pid;
+ struct pid *pid_s;
+ struct quadd_thread_data *t_data;
+
+ t_data = &cpu_ctx->active_thread;
+ pid = t_data->pid;
+
+ rcu_read_lock();
+ pid_s = find_vpid(pid);
+ if (pid_s)
+ task = pid_task(pid_s, PIDTYPE_PID);
+ rcu_read_unlock();
+ if (!task)
+ return;
+ }
+
+ quadd_get_mmap_object(cpu_ctx, regs, task->pid);
if (ctx->pmu && ctx->pmu_info.active)
- nr_events += read_source(ctx->pmu, regs, pid,
+ nr_events += read_source(ctx->pmu, regs,
events, QUADD_MAX_COUNTERS);
if (ctx->pl310 && ctx->pl310_info.active)
- nr_events += read_source(ctx->pl310, regs, pid,
+ nr_events += read_source(ctx->pl310, regs,
events + nr_events,
QUADD_MAX_COUNTERS - nr_events);
@@ -276,7 +293,7 @@ static void read_all_sources(struct pt_regs *regs, pid_t pid)
else
user_regs = task_pt_regs(current);
- if (get_sample_data(s, regs, pid))
+ if (get_sample_data(s, regs, task))
return;
if (ctx->param.backtrace) {
@@ -309,6 +326,16 @@ static void read_all_sources(struct pt_regs *regs, pid_t pid)
vec[vec_idx].len = nr_positive_events * sizeof(events_extra[0]);
vec_idx++;
+ state = task->state;
+ if (state) {
+ s->state = 1;
+ vec[vec_idx].base = &state;
+ vec[vec_idx].len = sizeof(state);
+ vec_idx++;
+ } else {
+ s->state = 0;
+ }
+
quadd_put_sample(&record_data, vec, vec_idx);
}
@@ -419,7 +446,7 @@ void __quadd_task_sched_out(struct task_struct *prev,
if (prev_flag) {
user_regs = task_pt_regs(prev);
if (user_regs)
- read_all_sources(user_regs, prev->pid);
+ read_all_sources(user_regs, prev);
n = remove_active_thread(cpu_ctx, prev->pid);
atomic_sub(n, &cpu_ctx->nr_active);
diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h
index b90b524339b7..da3f73cebd98 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.43"
+#define QUADD_MODULE_VERSION "1.44"
#define QUADD_MODULE_BRANCH "Dev"
#endif /* __QUADD_VERSION_H */
diff --git a/include/linux/tegra_profiler.h b/include/linux/tegra_profiler.h
index 277fc93241e4..28924f51eaf8 100644
--- a/include/linux/tegra_profiler.h
+++ b/include/linux/tegra_profiler.h
@@ -19,7 +19,7 @@
#include <linux/ioctl.h>
-#define QUADD_SAMPLES_VERSION 18
+#define QUADD_SAMPLES_VERSION 19
#define QUADD_IO_VERSION 9
#define QUADD_IO_VERSION_DYNAMIC_RB 5
@@ -30,6 +30,7 @@
#define QUADD_SAMPLE_VERSION_THUMB_MODE_FLAG 17
#define QUADD_SAMPLE_VERSION_GROUP_SAMPLES 18
+#define QUADD_SAMPLE_VERSION_THREAD_STATE_FLD 19
#define QUADD_MAX_COUNTERS 32
#define QUADD_MAX_PROCESS 64
@@ -140,7 +141,9 @@ struct quadd_sample_data {
user_mode:1,
lp_mode:1,
thumb_mode:1,
- reserved:7;
+ state:1,
+ in_interrupt:1,
+ reserved:5;
u8 callchain_nr;
u32 events_flags;