misc: tegra-profiler: add time source option
Igor Nabirushkin [Tue, 24 Jun 2014 08:18:29 +0000 (12:18 +0400)]
* Add time source option (CNTVCT or kernel monotonic clock).
* Do not use arch timer if user does not have direct access to
  CNTVCT register.

Bug 1508327

Change-Id: I0efc619146c1256ac57120b8646ecd8e819a1315
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/427620
(cherry picked from commit 5e375e6dbca8211bb2af04bd25d5e5d66371aa4f)
Reviewed-on: http://git-master/r/433507
Reviewed-by: Andrey Trachenko <atrachenko@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Maxim Morin <mmorin@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/misc/tegra-profiler/hrt.c
drivers/misc/tegra-profiler/hrt.h
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/quadd_proc.c
drivers/misc/tegra-profiler/version.h
include/linux/tegra_profiler.h

index 22ba32e..0a1da91 100644 (file)
@@ -114,10 +114,9 @@ u64 quadd_get_time(void)
 {
        struct timecounter *tc = hrt.tc;
 
-       if (tc)
-               return get_arch_time(tc);
-       else
-               return get_posix_clock_monotonic_time();
+       return (tc && hrt.use_arch_timer) ?
+               get_arch_time(tc) :
+               get_posix_clock_monotonic_time();
 }
 
 static void put_header(void)
@@ -161,6 +160,9 @@ static void put_header(void)
 
        hdr->reserved |= hrt.unw_method << QUADD_HDR_UNW_METHOD_SHIFT;
 
+       if (hrt.use_arch_timer)
+               hdr->reserved |= QUADD_HDR_USE_ARCH_TIMER;
+
        if (pmu)
                nr_events += pmu->get_current_events(events, max_events);
 
@@ -591,18 +593,8 @@ int quadd_hrt_start(void)
 
        reset_cpu_ctx();
 
-       put_header();
-
        extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
 
-       if (extra & QUADD_PARAM_EXTRA_GET_MMAP) {
-               err = quadd_get_current_mmap(param->pids[0]);
-               if (err) {
-                       pr_err("error: quadd_get_current_mmap\n");
-                       return err;
-               }
-       }
-
        if (extra & QUADD_PARAM_EXTRA_BT_MIXED)
                hrt.unw_method = QUADD_UNW_METHOD_MIXED;
        else if (extra & QUADD_PARAM_EXTRA_BT_UNWIND_TABLES)
@@ -612,6 +604,23 @@ int quadd_hrt_start(void)
        else
                hrt.unw_method = QUADD_UNW_METHOD_NONE;
 
+       if (hrt.tc && (extra & QUADD_PARAM_EXTRA_USE_ARCH_TIMER))
+               hrt.use_arch_timer = 1;
+       else
+               hrt.use_arch_timer = 0;
+
+       pr_info("timer: %s\n", hrt.use_arch_timer ? "arch" : "monotonic clock");
+
+       put_header();
+
+       if (extra & QUADD_PARAM_EXTRA_GET_MMAP) {
+               err = quadd_get_current_mmap(param->pids[0]);
+               if (err) {
+                       pr_err("error: quadd_get_current_mmap\n");
+                       return err;
+               }
+       }
+
        if (ctx->pl310)
                ctx->pl310->start();
 
@@ -656,6 +665,16 @@ void quadd_hrt_get_state(struct quadd_module_state *state)
        state->nr_skipped_samples = 0;
 }
 
+static void init_arch_timer(void)
+{
+       u32 cntkctl = arch_timer_get_cntkctl();
+
+       if (cntkctl & ARCH_TIMER_USR_VCT_ACCESS_EN)
+               hrt.tc = arch_timer_get_timecounter();
+       else
+               hrt.tc = NULL;
+}
+
 struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
 {
        int cpu_id;
@@ -677,7 +696,7 @@ struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
                hrt.ma_period = 0;
 
        atomic64_set(&hrt.counter_samples, 0);
-       hrt.tc = arch_timer_get_timecounter();
+       init_arch_timer();
 
        hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
        if (!hrt.cpu_ctx)
index b32f037..c4393aa 100644 (file)
@@ -58,6 +58,8 @@ struct quadd_hrt_ctx {
        unsigned long rss_size_prev;
 
        struct timecounter *tc;
+       int use_arch_timer;
+
        unsigned int unw_method;
 };
 
index 555cc25..0f364d7 100644 (file)
@@ -433,7 +433,7 @@ static void get_capabilities(struct quadd_comm_cap *cap)
        extra |= QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE;
 
        if (ctx.hrt->tc)
-               extra |= QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER;
+               extra |= QUADD_COMM_CAP_EXTRA_ARCH_TIMER;
 
        cap->reserved[QUADD_COMM_CAP_IDX_EXTRA] = extra;
 }
index 12f5fc9..779c79a 100644 (file)
@@ -96,8 +96,8 @@ static int show_capabilities(struct seq_file *f, void *offset)
                   YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNWIND_MIXED));
        seq_printf(f, "information about unwind entry:        %s\n",
                   YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE));
-       seq_printf(f, "use arch timer:                        %s\n",
-                  YES_NO(extra & QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER));
+       seq_printf(f, "arch timer is available:               %s\n",
+                  YES_NO(extra & QUADD_COMM_CAP_EXTRA_ARCH_TIMER));
 
        seq_puts(f, "\n");
 
index 1225073..96299d5 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.75"
+#define QUADD_MODULE_VERSION           "1.76"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */
index 3ba50b6..5434d58 100644 (file)
@@ -19,8 +19,8 @@
 
 #include <linux/ioctl.h>
 
-#define QUADD_SAMPLES_VERSION  29
-#define QUADD_IO_VERSION       12
+#define QUADD_SAMPLES_VERSION  30
+#define QUADD_IO_VERSION       13
 
 #define QUADD_IO_VERSION_DYNAMIC_RB            5
 #define QUADD_IO_VERSION_RB_MAX_FILL_COUNT     6
@@ -30,6 +30,7 @@
 #define QUADD_IO_VERSION_BT_UNWIND_TABLES      10
 #define QUADD_IO_VERSION_UNWIND_MIXED          11
 #define QUADD_IO_VERSION_EXTABLES_MMAP         12
+#define QUADD_IO_VERSION_ARCH_TIMER_OPT                13
 
 #define QUADD_SAMPLE_VERSION_THUMB_MODE_FLAG   17
 #define QUADD_SAMPLE_VERSION_GROUP_SAMPLES     18
@@ -42,6 +43,7 @@
 #define QUADD_SAMPLE_VERSION_USE_ARCH_TIMER    27
 #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_MAX_COUNTERS     32
 #define QUADD_MAX_PROCESS      64
@@ -290,6 +292,8 @@ struct quadd_debug_data {
 #define QUADD_HDR_UNW_METHOD_SHIFT     0
 #define QUADD_HDR_UNW_METHOD_MASK      (0x07 << QUADD_HDR_UNW_METHOD_SHIFT)
 
+#define QUADD_HDR_USE_ARCH_TIMER       (1 << 3)
+
 struct quadd_header_data {
        u16 magic;
        u16 version;
@@ -339,6 +343,7 @@ enum {
 #define QUADD_PARAM_EXTRA_BT_FP                        (1 << 1)
 #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)
 
 struct quadd_parameters {
        u32 freq;
@@ -389,7 +394,7 @@ enum {
 #define QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP (1 << 5)
 #define QUADD_COMM_CAP_EXTRA_UNWIND_MIXED      (1 << 6)
 #define QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE    (1 << 7)
-#define QUADD_COMM_CAP_EXTRA_USE_ARCH_TIMER    (1 << 8)
+#define QUADD_COMM_CAP_EXTRA_ARCH_TIMER                (1 << 8)
 
 struct quadd_comm_cap {
        u32     pmu:1,