diff options
Diffstat (limited to 'drivers/gator/gator_main.c')
-rw-r--r-- | drivers/gator/gator_main.c | 349 |
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); |