aboutsummaryrefslogtreecommitdiff
path: root/drivers/gator/gator_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gator/gator_main.c')
-rw-r--r--drivers/gator/gator_main.c349
1 files changed, 190 insertions, 159 deletions
diff --git a/drivers/gator/gator_main.c b/drivers/gator/gator_main.c
index 0d867f22364f..30bf60d95286 100644
--- a/drivers/gator/gator_main.c
+++ b/drivers/gator/gator_main.c
@@ -7,8 +7,8 @@
*
*/
-// This version must match the gator daemon version
-#define PROTOCOL_VERSION 19
+/* This version must match the gator daemon version */
+#define PROTOCOL_VERSION 20
static unsigned long gator_protocol_version = PROTOCOL_VERSION;
#include <linux/slab.h>
@@ -25,7 +25,7 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
#include <linux/utsname.h>
#include <linux/kthread.h>
#include <asm/stacktrace.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "gator.h"
@@ -67,11 +67,11 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
#define SUMMARY_BUFFER_SIZE (1*1024)
#define BACKTRACE_BUFFER_SIZE (128*1024)
#define NAME_BUFFER_SIZE (64*1024)
-#define COUNTER_BUFFER_SIZE (64*1024) // counters have the core as part of the data and the core value in the frame header may be discarded
+#define COUNTER_BUFFER_SIZE (64*1024) /* counters have the core as part of the data and the core value in the frame header may be discarded */
#define BLOCK_COUNTER_BUFFER_SIZE (128*1024)
-#define ANNOTATE_BUFFER_SIZE (128*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded
+#define ANNOTATE_BUFFER_SIZE (128*1024) /* annotate counters have the core as part of the data and the core value in the frame header may be discarded */
#define SCHED_TRACE_BUFFER_SIZE (128*1024)
-#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded
+#define IDLE_BUFFER_SIZE (32*1024) /* idle counters have the core as part of the data and the core value in the frame header may be discarded */
#define ACTIVITY_BUFFER_SIZE (128*1024)
#define NO_COOKIE 0U
@@ -89,24 +89,24 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
#define MESSAGE_END_BACKTRACE 1
-// Name Frame Messages
+/* Name Frame Messages */
#define MESSAGE_COOKIE 1
#define MESSAGE_THREAD_NAME 2
#define MESSAGE_LINK 4
-// Scheduler Trace Frame Messages
+/* Scheduler Trace Frame Messages */
#define MESSAGE_SCHED_SWITCH 1
#define MESSAGE_SCHED_EXIT 2
-// Idle Frame Messages
+/* Idle Frame Messages */
#define MESSAGE_IDLE_ENTER 1
#define MESSAGE_IDLE_EXIT 2
-// Summary Frame Messages
+/* Summary Frame Messages */
#define MESSAGE_SUMMARY 1
#define MESSAGE_CORE_NAME 3
-// Activity Frame Messages
+/* Activity Frame Messages */
#define MESSAGE_SWITCH 2
#define MESSAGE_EXIT 3
@@ -140,14 +140,15 @@ enum {
* Globals
******************************************************************************/
static unsigned long gator_cpu_cores;
-// Size of the largest buffer. Effectively constant, set in gator_op_create_files
+/* Size of the largest buffer. Effectively constant, set in gator_op_create_files */
static unsigned long userspace_buffer_size;
static unsigned long gator_backtrace_depth;
-// How often to commit the buffers for live in nanoseconds
+/* How often to commit the buffers for live in nanoseconds */
static u64 gator_live_rate;
static unsigned long gator_started;
static u64 gator_monotonic_started;
+static u64 gator_sync_time;
static u64 gator_hibernate_time;
static unsigned long gator_buffer_opened;
static unsigned long gator_timer_count;
@@ -161,7 +162,7 @@ static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait);
static DECLARE_WAIT_QUEUE_HEAD(gator_annotate_wait);
static struct timer_list gator_buffer_wake_up_timer;
static bool gator_buffer_wake_run;
-// Initialize semaphore unlocked to initialize memory values
+/* Initialize semaphore unlocked to initialize memory values */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
static DECLARE_MUTEX(gator_buffer_wake_sem);
#else
@@ -183,33 +184,43 @@ static DEFINE_PER_CPU(bool, in_scheduler_context);
* Prototypes
******************************************************************************/
static u64 gator_get_time(void);
+static void gator_emit_perf_time(u64 time);
static void gator_op_create_files(struct super_block *sb, struct dentry *root);
-// gator_buffer is protected by being per_cpu and by having IRQs disabled when writing to it.
-// Most marshal_* calls take care of this except for marshal_cookie*, marshal_backtrace* and marshal_frame where the caller is responsible for doing so.
-// No synchronization is needed with the backtrace buffer as it is per cpu and is only used from the hrtimer.
-// The annotate_lock must be held when using the annotation buffer as it is not per cpu.
-// collect_counters which is the sole writer to the block counter frame is additionally protected by the per cpu collecting flag
+/* gator_buffer is protected by being per_cpu and by having IRQs
+ * disabled when writing to it. Most marshal_* calls take care of this
+ * except for marshal_cookie*, marshal_backtrace* and marshal_frame
+ * where the caller is responsible for doing so. No synchronization is
+ * needed with the backtrace buffer as it is per cpu and is only used
+ * from the hrtimer. The annotate_lock must be held when using the
+ * annotation buffer as it is not per cpu. collect_counters which is
+ * the sole writer to the block counter frame is additionally
+ * protected by the per cpu collecting flag.
+ */
-// Size of the buffer, must be a power of 2. Effectively constant, set in gator_op_setup.
+/* Size of the buffer, must be a power of 2. Effectively constant, set in gator_op_setup. */
static uint32_t gator_buffer_size[NUM_GATOR_BUFS];
-// gator_buffer_size - 1, bitwise and with pos to get offset into the array. Effectively constant, set in gator_op_setup.
+/* gator_buffer_size - 1, bitwise and with pos to get offset into the array. Effectively constant, set in gator_op_setup. */
static uint32_t gator_buffer_mask[NUM_GATOR_BUFS];
-// Read position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are read by userspace in userspace_buffer_read
+/* Read position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are read by userspace in userspace_buffer_read */
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_read);
-// Write position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are written to the buffer
+/* Write position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are written to the buffer */
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_write);
-// Commit position in the buffer. Initialized to zero in gator_op_setup and incremented after a frame is ready to be read by userspace
+/* Commit position in the buffer. Initialized to zero in gator_op_setup and incremented after a frame is ready to be read by userspace */
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_commit);
-// If set to false, decreases the number of bytes returned by buffer_bytes_available. Set in buffer_check_space if no space is remaining. Initialized to true in gator_op_setup
-// This means that if we run out of space, continue to report that no space is available until bytes are read by userspace
+/* If set to false, decreases the number of bytes returned by
+ * buffer_bytes_available. Set in buffer_check_space if no space is
+ * remaining. Initialized to true in gator_op_setup. This means that
+ * if we run out of space, continue to report that no space is
+ * available until bytes are read by userspace
+ */
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], buffer_space_available);
-// The buffer. Allocated in gator_op_setup
+/* The buffer. Allocated in gator_op_setup */
static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
-// The time after which the buffer should be committed for live display
+/* The time after which the buffer should be committed for live display */
static DEFINE_PER_CPU(u64, gator_buffer_commit_time);
-// List of all gator events - new events must be added to this list
+/* List of all gator events - new events must be added to this list */
#define GATOR_EVENTS_LIST \
GATOR_EVENT(gator_events_armv6_init) \
GATOR_EVENT(gator_events_armv7_init) \
@@ -218,15 +229,14 @@ static DEFINE_PER_CPU(u64, gator_buffer_commit_time);
GATOR_EVENT(gator_events_irq_init) \
GATOR_EVENT(gator_events_l2c310_init) \
GATOR_EVENT(gator_events_mali_init) \
- GATOR_EVENT(gator_events_mali_t6xx_hw_init) \
- GATOR_EVENT(gator_events_mali_t6xx_init) \
+ GATOR_EVENT(gator_events_mali_midgard_hw_init) \
+ GATOR_EVENT(gator_events_mali_midgard_init) \
GATOR_EVENT(gator_events_meminfo_init) \
GATOR_EVENT(gator_events_mmapped_init) \
GATOR_EVENT(gator_events_net_init) \
GATOR_EVENT(gator_events_perf_pmu_init) \
GATOR_EVENT(gator_events_sched_init) \
GATOR_EVENT(gator_events_scorpion_init) \
- GATOR_EVENT(gator_events_threads_init) \
#define GATOR_EVENT(EVENT_INIT) __weak int EVENT_INIT(void);
GATOR_EVENTS_LIST
@@ -315,13 +325,6 @@ static const struct gator_cpu gator_cpus[] = {
.pmnc_counters = 6,
},
{
- .cpuid = CORTEX_A12,
- .core_name = "Cortex-A12",
- .pmnc_name = "ARMv7_Cortex_A12",
- .dt_name = "arm,cortex-a12",
- .pmnc_counters = 6,
- },
- {
.cpuid = CORTEX_A15,
.core_name = "Cortex-A15",
.pmnc_name = "ARMv7_Cortex_A15",
@@ -400,23 +403,32 @@ const struct gator_cpu *gator_find_cpu_by_cpuid(const u32 cpuid)
for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
const struct gator_cpu *const gator_cpu = &gator_cpus[i];
- if (gator_cpu->cpuid == cpuid) {
+
+ if (gator_cpu->cpuid == cpuid)
return gator_cpu;
- }
}
return NULL;
}
+static const char OLD_PMU_PREFIX[] = "ARMv7 Cortex-";
+static const char NEW_PMU_PREFIX[] = "ARMv7_Cortex_";
+
const struct gator_cpu *gator_find_cpu_by_pmu_name(const char *const name)
{
int i;
for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
const struct gator_cpu *const gator_cpu = &gator_cpus[i];
- if (gator_cpu->pmnc_name != NULL && strcmp(gator_cpu->pmnc_name, name) == 0) {
+
+ if (gator_cpu->pmnc_name != NULL &&
+ /* Do the names match exactly? */
+ (strcasecmp(gator_cpu->pmnc_name, name) == 0 ||
+ /* Do these names match but have the old vs new prefix? */
+ ((strncasecmp(name, OLD_PMU_PREFIX, sizeof(OLD_PMU_PREFIX) - 1) == 0 &&
+ strncasecmp(gator_cpu->pmnc_name, NEW_PMU_PREFIX, sizeof(NEW_PMU_PREFIX) - 1) == 0 &&
+ strcasecmp(name + sizeof(OLD_PMU_PREFIX) - 1, gator_cpu->pmnc_name + sizeof(NEW_PMU_PREFIX) - 1) == 0))))
return gator_cpu;
- }
}
return NULL;
@@ -445,16 +457,15 @@ static void gator_buffer_wake_up(unsigned long data)
static int gator_buffer_wake_func(void *data)
{
for (;;) {
- if (down_killable(&gator_buffer_wake_sem)) {
+ if (down_killable(&gator_buffer_wake_sem))
break;
- }
- // Eat up any pending events
- while (!down_trylock(&gator_buffer_wake_sem));
+ /* Eat up any pending events */
+ while (!down_trylock(&gator_buffer_wake_sem))
+ ;
- if (!gator_buffer_wake_run) {
+ if (!gator_buffer_wake_run)
break;
- }
gator_buffer_wake_up(0);
}
@@ -468,6 +479,7 @@ static int gator_buffer_wake_func(void *data)
static bool buffer_commit_ready(int *cpu, int *buftype)
{
int cpu_x, x;
+
for_each_present_cpu(cpu_x) {
for (x = 0; x < NUM_GATOR_BUFS; x++)
if (per_cpu(gator_buffer_commit, cpu_x)[x] != per_cpu(gator_buffer_read, cpu_x)[x]) {
@@ -487,6 +499,7 @@ static bool buffer_commit_ready(int *cpu, int *buftype)
static void gator_timer_interrupt(void)
{
struct pt_regs *const regs = get_irq_regs();
+
gator_backtrace_handler(regs);
}
@@ -495,15 +508,14 @@ void gator_backtrace_handler(struct pt_regs *const regs)
u64 time = gator_get_time();
int cpu = get_physical_cpu();
- // Output backtrace
+ /* Output backtrace */
gator_add_sample(cpu, regs, time);
- // Collect counters
- if (!per_cpu(collecting, cpu)) {
- collect_counters(time, NULL);
- }
+ /* Collect counters */
+ if (!per_cpu(collecting, cpu))
+ collect_counters(time, current, false);
- // No buffer flushing occurs during sched switch for RT-Preempt full. The block counter frame will be flushed by collect_counters, but the sched buffer needs to be explicitly flushed
+ /* No buffer flushing occurs during sched switch for RT-Preempt full. The block counter frame will be flushed by collect_counters, but the sched buffer needs to be explicitly flushed */
#ifdef CONFIG_PREEMPT_RT_FULL
buffer_check(cpu, SCHED_TRACE_BUF, time);
#endif
@@ -511,7 +523,7 @@ void gator_backtrace_handler(struct pt_regs *const regs)
static int gator_running;
-// This function runs in interrupt context and on the appropriate core
+/* This function runs in interrupt context and on the appropriate core */
static void gator_timer_offline(void *migrate)
{
struct gator_interface *gi;
@@ -522,11 +534,10 @@ static void gator_timer_offline(void *migrate)
gator_trace_sched_offline();
gator_trace_power_offline();
- if (!migrate) {
+ if (!migrate)
gator_hrtimer_offline();
- }
- // Offline any events and output counters
+ /* Offline any events and output counters */
time = gator_get_time();
if (marshal_event_header(time)) {
list_for_each_entry(gi, &gator_events, list) {
@@ -535,24 +546,23 @@ static void gator_timer_offline(void *migrate)
marshal_event(len, buffer);
}
}
- // Only check after writing all counters so that time and corresponding counters appear in the same frame
+ /* Only check after writing all counters so that time and corresponding counters appear in the same frame */
buffer_check(cpu, BLOCK_COUNTER_BUF, time);
}
- // Flush all buffers on this core
+ /* Flush all buffers on this core */
for (i = 0; i < NUM_GATOR_BUFS; i++)
gator_commit_buffer(cpu, i, time);
}
-// This function runs in interrupt context and may be running on a core other than core 'cpu'
+/* This function runs in interrupt context and may be running on a core other than core 'cpu' */
static void gator_timer_offline_dispatch(int cpu, bool migrate)
{
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list) {
- if (gi->offline_dispatch) {
+ if (gi->offline_dispatch)
gi->offline_dispatch(cpu, migrate);
- }
}
}
@@ -579,16 +589,15 @@ static void gator_send_core_name(const int cpu, const u32 cpuid)
const char *core_name = NULL;
char core_name_buf[32];
- // Save off this cpuid
+ /* Save off this cpuid */
gator_cpuids[cpu] = cpuid;
if (gator_cpu != NULL) {
core_name = gator_cpu->core_name;
} else {
- if (cpuid == -1) {
+ if (cpuid == -1)
snprintf(core_name_buf, sizeof(core_name_buf), "Unknown");
- } else {
+ else
snprintf(core_name_buf, sizeof(core_name_buf), "Unknown (0x%.3x)", cpuid);
- }
core_name = core_name_buf;
}
@@ -598,12 +607,12 @@ static void gator_send_core_name(const int cpu, const u32 cpuid)
#endif
}
-static void gator_read_cpuid(void * arg)
+static void gator_read_cpuid(void *arg)
{
gator_cpuids[get_physical_cpu()] = gator_cpuid();
}
-// This function runs in interrupt context and on the appropriate core
+/* This function runs in interrupt context and on the appropriate core */
static void gator_timer_online(void *migrate)
{
struct gator_interface *gi;
@@ -611,12 +620,12 @@ static void gator_timer_online(void *migrate)
int *buffer;
u64 time;
- // Send what is currently running on this core
+ /* Send what is currently running on this core */
marshal_sched_trace_switch(current->pid, 0);
gator_trace_power_online();
- // online any events and output counters
+ /* online any events and output counters */
time = gator_get_time();
if (marshal_event_header(time)) {
list_for_each_entry(gi, &gator_events, list) {
@@ -625,26 +634,24 @@ static void gator_timer_online(void *migrate)
marshal_event(len, buffer);
}
}
- // Only check after writing all counters so that time and corresponding counters appear in the same frame
+ /* Only check after writing all counters so that time and corresponding counters appear in the same frame */
buffer_check(cpu, BLOCK_COUNTER_BUF, time);
}
- if (!migrate) {
+ if (!migrate)
gator_hrtimer_online();
- }
gator_send_core_name(cpu, gator_cpuid());
}
-// This function runs in interrupt context and may be running on a core other than core 'cpu'
+/* This function runs in interrupt context and may be running on a core other than core 'cpu' */
static void gator_timer_online_dispatch(int cpu, bool migrate)
{
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list) {
- if (gi->online_dispatch) {
+ if (gi->online_dispatch)
gi->online_dispatch(cpu, migrate);
- }
}
}
@@ -661,15 +668,14 @@ static int gator_timer_start(unsigned long sample_rate)
gator_running = 1;
- // event based sampling trumps hr timer based sampling
- if (event_based_sampling) {
+ /* event based sampling trumps hr timer based sampling */
+ if (event_based_sampling)
sample_rate = 0;
- }
if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1)
return -1;
- // Send off the previously saved cpuids
+ /* Send off the previously saved cpuids */
for_each_present_cpu(cpu) {
preempt_disable();
gator_send_core_name(cpu, gator_cpuids[cpu]);
@@ -693,21 +699,24 @@ static u64 gator_get_time(void)
u64 delta;
int cpu = smp_processor_id();
- // Match clock_gettime(CLOCK_MONOTONIC_RAW, &ts) from userspace
+ /* Match clock_gettime(CLOCK_MONOTONIC_RAW, &ts) from userspace */
getrawmonotonic(&ts);
timestamp = timespec_to_ns(&ts);
- // getrawmonotonic is not monotonic on all systems. Detect and attempt to correct these cases.
- // up to 0.5ms delta has been seen on some systems, which can skew Streamline data when viewing at high resolution.
- // This doesn't work well with interrupts, but that it's OK - the real concern is to catch big jumps in time
+ /* getrawmonotonic is not monotonic on all systems. Detect and
+ * attempt to correct these cases. up to 0.5ms delta has been seen
+ * on some systems, which can skew Streamline data when viewing at
+ * high resolution. This doesn't work well with interrupts, but that
+ * it's OK - the real concern is to catch big jumps in time
+ */
prev_timestamp = per_cpu(last_timestamp, cpu);
if (prev_timestamp <= timestamp) {
per_cpu(last_timestamp, cpu) = timestamp;
} else {
delta = prev_timestamp - timestamp;
- // Log the error once
+ /* Log the error once */
if (!printed_monotonic_warning && delta > 500000) {
- printk(KERN_ERR "%s: getrawmonotonic is not monotonic cpu: %i delta: %lli\nSkew in Streamline data may be present at the fine zoom levels\n", __FUNCTION__, cpu, delta);
+ pr_err("%s: getrawmonotonic is not monotonic cpu: %i delta: %lli\nSkew in Streamline data may be present at the fine zoom levels\n", __func__, cpu, delta);
printed_monotonic_warning = true;
}
timestamp = prev_timestamp;
@@ -716,6 +725,19 @@ static u64 gator_get_time(void)
return timestamp - gator_monotonic_started;
}
+static void gator_emit_perf_time(u64 time)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ if (time >= gator_sync_time) {
+ int cpu = get_physical_cpu();
+
+ marshal_event_single64(0, -1, local_clock());
+ gator_sync_time += NSEC_PER_SEC;
+ gator_commit_buffer(cpu, COUNTER_BUF, time);
+ }
+#endif
+}
+
/******************************************************************************
* cpu hotplug and pm notifiers
******************************************************************************/
@@ -743,8 +765,10 @@ static struct notifier_block __refdata gator_hotcpu_notifier = {
.notifier_call = gator_hotcpu_notify,
};
-// n.b. calling "on_each_cpu" only runs on those that are online
-// Registered linux events are not disabled, so their counters will continue to collect
+/* n.b. calling "on_each_cpu" only runs on those that are online.
+ * Registered linux events are not disabled, so their counters will
+ * continue to collect
+ */
static int gator_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy)
{
int cpu;
@@ -760,13 +784,13 @@ static int gator_pm_notify(struct notifier_block *nb, unsigned long event, void
gator_timer_offline_dispatch(lcpu_to_pcpu(cpu), false);
}
- // Record the wallclock hibernate time
+ /* Record the wallclock hibernate time */
getnstimeofday(&ts);
gator_hibernate_time = timespec_to_ns(&ts) - gator_get_time();
break;
case PM_POST_HIBERNATION:
case PM_POST_SUSPEND:
- // Adjust gator_monotonic_started for the time spent sleeping, as gator_get_time does not account for it
+ /* Adjust gator_monotonic_started for the time spent sleeping, as gator_get_time does not account for it */
if (gator_hibernate_time > 0) {
getnstimeofday(&ts);
gator_monotonic_started += gator_hibernate_time + gator_get_time() - timespec_to_ns(&ts);
@@ -792,6 +816,7 @@ static struct notifier_block gator_pm_notifier = {
static int gator_notifier_start(void)
{
int retval;
+
retval = register_hotcpu_notifier(&gator_hotcpu_notifier);
if (retval == 0)
retval = register_pm_notifier(&gator_pm_notifier);
@@ -812,28 +837,37 @@ static void gator_summary(void)
u64 timestamp, uptime;
struct timespec ts;
char uname_buf[512];
- void (*m2b)(struct timespec *ts);
snprintf(uname_buf, sizeof(uname_buf), "%s %s %s %s %s GNU/Linux", utsname()->sysname, utsname()->nodename, utsname()->release, utsname()->version, utsname()->machine);
getnstimeofday(&ts);
timestamp = timespec_to_ns(&ts);
- do_posix_clock_monotonic_gettime(&ts);
- // monotonic_to_bootbased is not defined for some versions of Android
- m2b = symbol_get(monotonic_to_bootbased);
- if (m2b) {
- m2b(&ts);
+ /* Similar to reading /proc/uptime from fs/proc/uptime.c, calculate uptime */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
+ {
+ void (*m2b)(struct timespec *ts);
+
+ do_posix_clock_monotonic_gettime(&ts);
+ /* monotonic_to_bootbased is not defined for some versions of Android */
+ m2b = symbol_get(monotonic_to_bootbased);
+ if (m2b)
+ m2b(&ts);
}
+#else
+ get_monotonic_boottime(&ts);
+#endif
uptime = timespec_to_ns(&ts);
- // Disable preemption as gator_get_time calls smp_processor_id to verify time is monotonic
+ /* Disable preemption as gator_get_time calls smp_processor_id to verify time is monotonic */
preempt_disable();
- // Set monotonic_started to zero as gator_get_time is uptime minus monotonic_started
+ /* Set monotonic_started to zero as gator_get_time is uptime minus monotonic_started */
gator_monotonic_started = 0;
gator_monotonic_started = gator_get_time();
marshal_summary(timestamp, uptime, gator_monotonic_started, uname_buf);
+ gator_sync_time = 0;
+ gator_emit_perf_time(gator_monotonic_started);
preempt_enable();
}
@@ -846,12 +880,14 @@ int gator_events_install(struct gator_interface *interface)
int gator_events_get_key(void)
{
- // key 0 is reserved as a timestamp
- // key 1 is reserved as the marker for thread specific counters
- // Odd keys are assigned by the driver, even keys by the daemon
+ /* key 0 is reserved as a timestamp. key 1 is reserved as the marker
+ * for thread specific counters. key 2 is reserved as the marker for
+ * core. Odd keys are assigned by the driver, even keys by the
+ * daemon.
+ */
static int key = 3;
-
const int ret = key;
+
key += 2;
return ret;
}
@@ -862,7 +898,7 @@ static int gator_init(void)
calc_first_cluster_size();
- // events sources
+ /* events sources */
for (i = 0; i < ARRAY_SIZE(gator_events_list); i++)
if (gator_events_list[i])
gator_events_list[i]();
@@ -888,26 +924,25 @@ static int gator_start(void)
struct gator_interface *gi;
gator_buffer_wake_run = true;
- if (IS_ERR(gator_buffer_wake_thread = kthread_run(gator_buffer_wake_func, NULL, "gator_bwake"))) {
+ gator_buffer_wake_thread = kthread_run(gator_buffer_wake_func, NULL, "gator_bwake");
+ if (IS_ERR(gator_buffer_wake_thread))
goto bwake_failure;
- }
if (gator_migrate_start())
goto migrate_failure;
- // Initialize the buffer with the frame type and core
+ /* Initialize the buffer with the frame type and core */
for_each_present_cpu(cpu) {
- for (i = 0; i < NUM_GATOR_BUFS; i++) {
+ for (i = 0; i < NUM_GATOR_BUFS; i++)
marshal_frame(cpu, i);
- }
per_cpu(last_timestamp, cpu) = 0;
}
printed_monotonic_warning = false;
- // Capture the start time
+ /* Capture the start time */
gator_summary();
- // start all events
+ /* start all events */
list_for_each_entry(gi, &gator_events, list) {
if (gi->start && gi->start() != 0) {
struct list_head *ptr = gi->list.prev;
@@ -924,7 +959,7 @@ static int gator_start(void)
}
}
- // cookies shall be initialized before trace_sched_start() and gator_timer_start()
+ /* cookies shall be initialized before trace_sched_start() and gator_timer_start() */
if (cookies_initialize())
goto cookies_failure;
if (gator_annotate_start())
@@ -955,7 +990,7 @@ sched_failure:
annotate_failure:
cookies_release();
cookies_failure:
- // stop all events
+ /* stop all events */
list_for_each_entry(gi, &gator_events, list)
if (gi->stop)
gi->stop();
@@ -979,11 +1014,11 @@ static void gator_stop(void)
gator_trace_power_stop();
gator_trace_gpu_stop();
- // stop all interrupt callback reads before tearing down other interfaces
- gator_notifier_stop(); // should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined
+ /* stop all interrupt callback reads before tearing down other interfaces */
+ gator_notifier_stop(); /* should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined */
gator_timer_stop();
- // stop all events
+ /* stop all events */
list_for_each_entry(gi, &gator_events, list)
if (gi->stop)
gi->stop();
@@ -1033,9 +1068,9 @@ static int gator_op_setup(void)
gator_buffer_size[ACTIVITY_BUF] = ACTIVITY_BUFFER_SIZE;
gator_buffer_mask[ACTIVITY_BUF] = ACTIVITY_BUFFER_SIZE - 1;
- // Initialize percpu per buffer variables
+ /* Initialize percpu per buffer variables */
for (i = 0; i < NUM_GATOR_BUFS; i++) {
- // Verify buffers are a power of 2
+ /* Verify buffers are a power of 2 */
if (gator_buffer_size[i] & (gator_buffer_size[i] - 1)) {
err = -ENOEXEC;
goto setup_error;
@@ -1048,7 +1083,7 @@ static int gator_op_setup(void)
per_cpu(buffer_space_available, cpu)[i] = true;
per_cpu(gator_buffer_commit_time, cpu) = gator_live_rate;
- // Annotation is a special case that only uses a single buffer
+ /* Annotation is a special case that only uses a single buffer */
if (cpu > 0 && i == ANNOTATE_BUF) {
per_cpu(gator_buffer, cpu)[i] = NULL;
continue;
@@ -1188,7 +1223,8 @@ static int userspace_buffer_open(struct inode *inode, struct file *file)
if (test_and_set_bit_lock(0, &gator_buffer_opened))
return -EBUSY;
- if ((err = gator_op_setup()))
+ err = gator_op_setup();
+ if (err)
goto fail;
/* NB: the actual start happens from userspace
@@ -1218,22 +1254,20 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf, size_t
int cpu, buftype;
int written = 0;
- // ensure there is enough space for a whole frame
- if (count < userspace_buffer_size || *offset) {
+ /* ensure there is enough space for a whole frame */
+ if (count < userspace_buffer_size || *offset)
return -EINVAL;
- }
- // sleep until the condition is true or a signal is received
- // the condition is checked each time gator_buffer_wait is woken up
+ /* sleep until the condition is true or a signal is received the
+ * condition is checked each time gator_buffer_wait is woken up
+ */
wait_event_interruptible(gator_buffer_wait, buffer_commit_ready(&cpu, &buftype) || !gator_started);
- if (signal_pending(current)) {
+ if (signal_pending(current))
return -EINTR;
- }
- if (buftype == -1 || cpu == -1) {
+ if (buftype == -1 || cpu == -1)
return 0;
- }
mutex_lock(&gator_buffer_mutex);
@@ -1241,12 +1275,11 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf, size_t
read = per_cpu(gator_buffer_read, cpu)[buftype];
commit = per_cpu(gator_buffer_commit, cpu)[buftype];
- // May happen if the buffer is freed during pending reads.
- if (!per_cpu(gator_buffer, cpu)[buftype]) {
+ /* May happen if the buffer is freed during pending reads. */
+ if (!per_cpu(gator_buffer, cpu)[buftype])
break;
- }
- // determine the size of two halves
+ /* determine the size of two halves */
length1 = commit - read;
length2 = 0;
buffer1 = &(per_cpu(gator_buffer, cpu)[buftype][read]);
@@ -1256,32 +1289,28 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf, size_t
length2 = commit;
}
- if (length1 + length2 > count - written) {
+ if (length1 + length2 > count - written)
break;
- }
- // start, middle or end
- if (length1 > 0 && copy_to_user(&buf[written], buffer1, length1)) {
+ /* start, middle or end */
+ if (length1 > 0 && copy_to_user(&buf[written], buffer1, length1))
break;
- }
- // possible wrap around
- if (length2 > 0 && copy_to_user(&buf[written + length1], buffer2, length2)) {
+ /* possible wrap around */
+ if (length2 > 0 && copy_to_user(&buf[written + length1], buffer2, length2))
break;
- }
per_cpu(gator_buffer_read, cpu)[buftype] = commit;
written += length1 + length2;
- // Wake up annotate_write if more space is available
- if (buftype == ANNOTATE_BUF) {
+ /* Wake up annotate_write if more space is available */
+ if (buftype == ANNOTATE_BUF)
wake_up(&gator_annotate_wait);
- }
} while (buffer_commit_ready(&cpu, &buftype));
mutex_unlock(&gator_buffer_mutex);
- // kick just in case we've lost an SMP event
+ /* kick just in case we've lost an SMP event */
wake_up(&gator_buffer_wait);
return written > 0 ? written : -EFAULT;
@@ -1348,19 +1377,19 @@ static void gator_op_create_files(struct super_block *sb, struct dentry *root)
gatorfs_create_ro_u64(sb, root, "started", &gator_monotonic_started);
gatorfs_create_u64(sb, root, "live_rate", &gator_live_rate);
- // Annotate interface
+ /* Annotate interface */
gator_annotate_create_files(sb, root);
- // Linux Events
+ /* Linux Events */
dir = gatorfs_mkdir(sb, root, "events");
list_for_each_entry(gi, &gator_events, list)
if (gi->create_files)
gi->create_files(sb, dir);
- // Sched Events
+ /* Sched Events */
sched_trace_create_files(sb, dir);
- // Power interface
+ /* Power interface */
gator_trace_power_create_files(sb, dir);
}
@@ -1396,19 +1425,22 @@ static void gator_op_create_files(struct super_block *sb, struct dentry *root)
GATOR_HANDLE_TRACEPOINT(sched_process_free); \
GATOR_HANDLE_TRACEPOINT(sched_switch); \
GATOR_HANDLE_TRACEPOINT(softirq_exit); \
+ GATOR_HANDLE_TRACEPOINT(task_rename); \
#define GATOR_HANDLE_TRACEPOINT(probe_name) \
struct tracepoint *gator_tracepoint_##probe_name
GATOR_TRACEPOINTS;
#undef GATOR_HANDLE_TRACEPOINT
-static void gator_fct(struct tracepoint *tp, void *priv)
+static void gator_save_tracepoint(struct tracepoint *tp, void *priv)
{
#define GATOR_HANDLE_TRACEPOINT(probe_name) \
- if (strcmp(tp->name, #probe_name) == 0) { \
- gator_tracepoint_##probe_name = tp; \
- return; \
- }
+ do { \
+ if (strcmp(tp->name, #probe_name) == 0) { \
+ gator_tracepoint_##probe_name = tp; \
+ return; \
+ } \
+ } while (0)
GATOR_TRACEPOINTS;
#undef GATOR_HANDLE_TRACEPOINT
}
@@ -1421,11 +1453,10 @@ GATOR_TRACEPOINTS;
static int __init gator_module_init(void)
{
- for_each_kernel_tracepoint(gator_fct, NULL);
+ for_each_kernel_tracepoint(gator_save_tracepoint, NULL);
- if (gatorfs_register()) {
+ if (gatorfs_register())
return -1;
- }
if (gator_init()) {
gatorfs_unregister();
@@ -1434,7 +1465,7 @@ static int __init gator_module_init(void)
setup_timer(&gator_buffer_wake_up_timer, gator_buffer_wake_up, 0);
- // Initialize the list of cpuids
+ /* Initialize the list of cpuids */
memset(gator_cpuids, -1, sizeof(gator_cpuids));
on_each_cpu(gator_read_cpuid, NULL, 1);