From 15ce78dafc08b1c5c3ec8f42070ae37160b5154c Mon Sep 17 00:00:00 2001 From: Jon Medhurst Date: Thu, 10 Apr 2014 09:02:02 +0100 Subject: gator: Version 5.18 Signed-off-by: Jon Medhurst --- drivers/gator/Kconfig | 39 +++ drivers/gator/gator.h | 13 +- drivers/gator/gator_annotate.c | 2 +- drivers/gator/gator_annotate_kernel.c | 8 +- drivers/gator/gator_backtrace.c | 48 +++- drivers/gator/gator_buffer.c | 168 ++++++++++++ drivers/gator/gator_buffer_write.c | 80 ++++++ drivers/gator/gator_cookies.c | 82 ++++-- drivers/gator/gator_events_armv6.c | 2 +- drivers/gator/gator_events_armv7.c | 18 +- drivers/gator/gator_events_block.c | 2 +- drivers/gator/gator_events_ccn-504.c | 2 +- drivers/gator/gator_events_irq.c | 2 +- drivers/gator/gator_events_l2c-310.c | 2 +- drivers/gator/gator_events_mali_4xx.c | 2 +- drivers/gator/gator_events_mali_4xx.h | 2 +- drivers/gator/gator_events_mali_common.c | 2 +- drivers/gator/gator_events_mali_common.h | 2 +- drivers/gator/gator_events_mali_t6xx.c | 8 +- drivers/gator/gator_events_mali_t6xx_hw.c | 10 +- drivers/gator/gator_events_mali_t6xx_hw_test.c | 2 +- drivers/gator/gator_events_meminfo.c | 28 +- drivers/gator/gator_events_mmapped.c | 2 +- drivers/gator/gator_events_net.c | 2 +- drivers/gator/gator_events_perf_pmu.c | 2 +- drivers/gator/gator_events_sched.c | 2 +- drivers/gator/gator_events_scorpion.c | 2 +- drivers/gator/gator_fs.c | 47 ++-- drivers/gator/gator_hrtimer_gator.c | 8 +- drivers/gator/gator_hrtimer_perf.c | 113 -------- drivers/gator/gator_iks.c | 4 +- drivers/gator/gator_main.c | 286 +++++---------------- drivers/gator/gator_marshaling.c | 97 ++----- drivers/gator/gator_pack.c | 58 ----- drivers/gator/gator_trace_gpu.c | 13 +- drivers/gator/gator_trace_gpu.h | 2 +- drivers/gator/gator_trace_power.c | 6 +- drivers/gator/gator_trace_sched.c | 20 +- .../gator/mali/mali_mjollnir_profiling_gator_api.h | 2 +- .../gator/mali/mali_utgard_profiling_gator_api.h | 2 +- drivers/gator/mali_t6xx.mk | 9 + 41 files changed, 608 insertions(+), 593 deletions(-) create mode 100644 drivers/gator/Kconfig create mode 100644 drivers/gator/gator_buffer.c create mode 100644 drivers/gator/gator_buffer_write.c delete mode 100644 drivers/gator/gator_hrtimer_perf.c delete mode 100644 drivers/gator/gator_pack.c (limited to 'drivers') diff --git a/drivers/gator/Kconfig b/drivers/gator/Kconfig new file mode 100644 index 00000000000..e46ccb9b806 --- /dev/null +++ b/drivers/gator/Kconfig @@ -0,0 +1,39 @@ +config GATOR + tristate "Gator module for ARM's Streamline Performance Analyzer" + default m if (ARM || ARM64) + depends on PROFILING + depends on HIGH_RES_TIMERS + depends on LOCAL_TIMERS || !(ARM && SMP) + depends on PERF_EVENTS + depends on HW_PERF_EVENTS || !(ARM || ARM64) + select TRACING + help + Gator module for ARM's Streamline Performance Analyzer + +config GATOR_WITH_MALI_SUPPORT + bool + +choice + prompt "Enable Mali GPU support in Gator" + depends on GATOR + optional + help + Enable Mali GPU support in Gator + +config GATOR_MALI_4XXMP + bool "Mali-400MP or Mali-450MP" + select GATOR_WITH_MALI_SUPPORT + +config GATOR_MALI_T6XX + bool "Mali-T604 or Mali-T658" + select GATOR_WITH_MALI_SUPPORT + +endchoice + +config GATOR_MALI_PATH + string "Path to Mali driver" + depends on GATOR_WITH_MALI_SUPPORT + default "drivers/gpu/arm/mali400mp" + help + The gator code adds this to its include path so it can get the Mali + trace headers with: #include "linux/mali_linux_trace.h" diff --git a/drivers/gator/gator.h b/drivers/gator/gator.h index d8981ed85a6..586cd9e742f 100644 --- a/drivers/gator/gator.h +++ b/drivers/gator/gator.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -31,6 +31,7 @@ #define CORTEX_A9 0xc09 #define CORTEX_A12 0xc0d #define CORTEX_A15 0xc0f +#define CORTEX_A17 0xc0e #define SCORPION 0x00f #define SCORPIONMP 0x02d #define KRAITSIM 0x049 @@ -47,9 +48,7 @@ struct gator_cpu { const int cpuid; // Human readable name const char core_name[MAXSIZE_CORE_NAME]; - // Perf PMU name - const char * const pmu_name; - // gatorfs event name + // gatorfs event and Perf PMU name const char * const pmnc_name; // compatible from Documentation/devicetree/bindings/arm/cpus.txt const char * const dt_name; @@ -62,10 +61,6 @@ const struct gator_cpu *gator_find_cpu_by_pmu_name(const char *const name); /****************************************************************************** * Filesystem ******************************************************************************/ -int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, - char const *name, - const struct file_operations *fops, int perm); - struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root, char const *name); @@ -75,8 +70,6 @@ int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, char const *name, unsigned long *val); -void gator_op_create_files(struct super_block *sb, struct dentry *root); - /****************************************************************************** * Tracepoints ******************************************************************************/ diff --git a/drivers/gator/gator_annotate.c b/drivers/gator/gator_annotate.c index 5b9399bea23..7e2c6e5d871 100644 --- a/drivers/gator/gator_annotate.c +++ b/drivers/gator/gator_annotate.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_annotate_kernel.c b/drivers/gator/gator_annotate_kernel.c index a406e488297..01080682552 100644 --- a/drivers/gator/gator_annotate_kernel.c +++ b/drivers/gator/gator_annotate_kernel.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -29,12 +29,14 @@ static void kannotate_write(const char *ptr, unsigned int size) } } -static void marshal_u16(char *buf, u16 val) { +static void marshal_u16(char *buf, u16 val) +{ buf[0] = val & 0xff; buf[1] = (val >> 8) & 0xff; } -static void marshal_u32(char *buf, u32 val) { +static void marshal_u32(char *buf, u32 val) +{ buf[0] = val & 0xff; buf[1] = (val >> 8) & 0xff; buf[2] = (val >> 16) & 0xff; diff --git a/drivers/gator/gator_backtrace.c b/drivers/gator/gator_backtrace.c index ffacb490194..9f305cf7242 100644 --- a/drivers/gator/gator_backtrace.c +++ b/drivers/gator/gator_backtrace.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -30,6 +30,18 @@ struct stack_frame_eabi { }; }; +static void gator_add_trace(int cpu, unsigned long address) +{ + off_t offset = 0; + unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset); + + if (cookie == NO_COOKIE || cookie == UNRESOLVED_COOKIE) { + offset = address; + } + + marshal_backtrace(offset & ~1, cookie, 0); +} + static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth) { #if defined(__arm__) || defined(__aarch64__) @@ -122,7 +134,7 @@ static int report_trace(struct stackframe *frame, void *d) addr = addr - (unsigned long)mod->module_core; } #endif - marshal_backtrace(addr & ~1, cookie); + marshal_backtrace(addr & ~1, cookie, 1); (*depth)--; } @@ -136,7 +148,7 @@ static int report_trace(struct stackframe *frame, void *d) #if (defined(__arm__) || defined(__aarch64__)) && !defined(GATOR_KERNEL_STACK_UNWINDING) // Disabled by default MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding."); -bool kernel_stack_unwinding = 0; +static bool kernel_stack_unwinding = 0; module_param(kernel_stack_unwinding, bool, 0644); #endif @@ -163,6 +175,34 @@ static void kernel_backtrace(int cpu, struct pt_regs *const regs) #endif walk_stackframe(&frame, report_trace, &depth); #else - marshal_backtrace(PC_REG & ~1, NO_COOKIE); + marshal_backtrace(PC_REG & ~1, NO_COOKIE, 1); #endif } + +static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time) +{ + bool in_kernel; + unsigned long exec_cookie; + + if (!regs) + return; + + in_kernel = !user_mode(regs); + exec_cookie = get_exec_cookie(cpu, current); + + if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, time)) + return; + + if (in_kernel) { + kernel_backtrace(cpu, regs); + } else { + // Cookie+PC + gator_add_trace(cpu, PC_REG); + + // Backtrace + if (gator_backtrace_depth) + arm_backtrace_eabi(cpu, regs, gator_backtrace_depth); + } + + marshal_backtrace_footer(time); +} diff --git a/drivers/gator/gator_buffer.c b/drivers/gator/gator_buffer.c new file mode 100644 index 00000000000..eba22dfe3bf --- /dev/null +++ b/drivers/gator/gator_buffer.c @@ -0,0 +1,168 @@ +/** + * Copyright (C) ARM Limited 2010-2014. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +static void marshal_frame(int cpu, int buftype) +{ + int frame; + + if (!per_cpu(gator_buffer, cpu)[buftype]) { + return; + } + + switch (buftype) { + case SUMMARY_BUF: + frame = FRAME_SUMMARY; + break; + case BACKTRACE_BUF: + frame = FRAME_BACKTRACE; + break; + case NAME_BUF: + frame = FRAME_NAME; + break; + case COUNTER_BUF: + frame = FRAME_COUNTER; + break; + case BLOCK_COUNTER_BUF: + frame = FRAME_BLOCK_COUNTER; + break; + case ANNOTATE_BUF: + frame = FRAME_ANNOTATE; + break; + case SCHED_TRACE_BUF: + frame = FRAME_SCHED_TRACE; + break; + case GPU_TRACE_BUF: + frame = FRAME_GPU_TRACE; + break; + case IDLE_BUF: + frame = FRAME_IDLE; + break; + default: + frame = -1; + break; + } + + // add response type + if (gator_response_type > 0) { + gator_buffer_write_packed_int(cpu, buftype, gator_response_type); + } + + // leave space for 4-byte unpacked length + per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype]; + + // add frame type and core number + gator_buffer_write_packed_int(cpu, buftype, frame); + gator_buffer_write_packed_int(cpu, buftype, cpu); +} + +static int buffer_bytes_available(int cpu, int buftype) +{ + int remaining, filled; + + filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype]; + if (filled < 0) { + filled += gator_buffer_size[buftype]; + } + + remaining = gator_buffer_size[buftype] - filled; + + if (per_cpu(buffer_space_available, cpu)[buftype]) { + // Give some extra room; also allows space to insert the overflow error packet + remaining -= 200; + } else { + // Hysteresis, prevents multiple overflow messages + remaining -= 2000; + } + + return remaining; +} + +static bool buffer_check_space(int cpu, int buftype, int bytes) +{ + int remaining = buffer_bytes_available(cpu, buftype); + + if (remaining < bytes) { + per_cpu(buffer_space_available, cpu)[buftype] = false; + } else { + per_cpu(buffer_space_available, cpu)[buftype] = true; + } + + return per_cpu(buffer_space_available, cpu)[buftype]; +} + +static int contiguous_space_available(int cpu, int buftype) +{ + int remaining = buffer_bytes_available(cpu, buftype); + int contiguous = gator_buffer_size[buftype] - per_cpu(gator_buffer_write, cpu)[buftype]; + if (remaining < contiguous) + return remaining; + else + return contiguous; +} + +static void gator_commit_buffer(int cpu, int buftype, u64 time) +{ + int type_length, commit, length, byte; + unsigned long flags; + + if (!per_cpu(gator_buffer, cpu)[buftype]) + return; + + // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload + local_irq_save(flags); + type_length = gator_response_type ? 1 : 0; + commit = per_cpu(gator_buffer_commit, cpu)[buftype]; + length = per_cpu(gator_buffer_write, cpu)[buftype] - commit; + if (length < 0) { + length += gator_buffer_size[buftype]; + } + length = length - type_length - sizeof(s32); + + if (length <= FRAME_HEADER_SIZE) { + // Nothing to write, only the frame header is present + local_irq_restore(flags); + return; + } + + for (byte = 0; byte < sizeof(s32); byte++) { + per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF; + } + + per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype]; + + if (gator_live_rate > 0) { + while (time > per_cpu(gator_buffer_commit_time, cpu)) { + per_cpu(gator_buffer_commit_time, cpu) += gator_live_rate; + } + } + + marshal_frame(cpu, buftype); + local_irq_restore(flags); + + // had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater + if (per_cpu(in_scheduler_context, cpu)) { +#ifndef CONFIG_PREEMPT_RT_FULL + // mod_timer can not be used in interrupt context in RT-Preempt full + mod_timer(&gator_buffer_wake_up_timer, jiffies + 1); +#endif + } else { + up(&gator_buffer_wake_sem); + } +} + +static void buffer_check(int cpu, int buftype, u64 time) +{ + int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype]; + if (filled < 0) { + filled += gator_buffer_size[buftype]; + } + if (filled >= ((gator_buffer_size[buftype] * 3) / 4)) { + gator_commit_buffer(cpu, buftype, time); + } +} diff --git a/drivers/gator/gator_buffer_write.c b/drivers/gator/gator_buffer_write.c new file mode 100644 index 00000000000..b621ba93ee5 --- /dev/null +++ b/drivers/gator/gator_buffer_write.c @@ -0,0 +1,80 @@ +/** + * Copyright (C) ARM Limited 2010-2014. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +static void gator_buffer_write_packed_int(int cpu, int buftype, int x) +{ + uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; + uint32_t mask = gator_buffer_mask[buftype]; + char *buffer = per_cpu(gator_buffer, cpu)[buftype]; + int packedBytes = 0; + int more = true; + while (more) { + // low order 7 bits of x + char b = x & 0x7f; + x >>= 7; + + if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) { + more = false; + } else { + b |= 0x80; + } + + buffer[(write + packedBytes) & mask] = b; + packedBytes++; + } + + per_cpu(gator_buffer_write, cpu)[buftype] = (write + packedBytes) & mask; +} + +static void gator_buffer_write_packed_int64(int cpu, int buftype, long long x) +{ + uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; + uint32_t mask = gator_buffer_mask[buftype]; + char *buffer = per_cpu(gator_buffer, cpu)[buftype]; + int packedBytes = 0; + int more = true; + while (more) { + // low order 7 bits of x + char b = x & 0x7f; + x >>= 7; + + if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) { + more = false; + } else { + b |= 0x80; + } + + buffer[(write + packedBytes) & mask] = b; + packedBytes++; + } + + per_cpu(gator_buffer_write, cpu)[buftype] = (write + packedBytes) & mask; +} + +static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len) +{ + int i; + u32 write = per_cpu(gator_buffer_write, cpu)[buftype]; + u32 mask = gator_buffer_mask[buftype]; + char *buffer = per_cpu(gator_buffer, cpu)[buftype]; + + for (i = 0; i < len; i++) { + buffer[write] = x[i]; + write = (write + 1) & mask; + } + + per_cpu(gator_buffer_write, cpu)[buftype] = write; +} + +static void gator_buffer_write_string(int cpu, int buftype, const char *x) +{ + int len = strlen(x); + gator_buffer_write_packed_int(cpu, buftype, len); + gator_buffer_write_bytes(cpu, buftype, x, len); +} diff --git a/drivers/gator/gator_cookies.c b/drivers/gator/gator_cookies.c index 91adfdde9be..5c7d842070e 100644 --- a/drivers/gator/gator_cookies.c +++ b/drivers/gator/gator_cookies.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,17 +15,22 @@ static uint32_t *gator_crc32_table; static unsigned int translate_buffer_mask; +struct cookie_args { + struct task_struct *task; + const char *text; +}; + static DEFINE_PER_CPU(char *, translate_text); static DEFINE_PER_CPU(uint32_t, cookie_next_key); static DEFINE_PER_CPU(uint64_t *, cookie_keys); static DEFINE_PER_CPU(uint32_t *, cookie_values); static DEFINE_PER_CPU(int, translate_buffer_read); static DEFINE_PER_CPU(int, translate_buffer_write); -static DEFINE_PER_CPU(void **, translate_buffer); +static DEFINE_PER_CPU(struct cookie_args *, translate_buffer); static uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq); static void wq_cookie_handler(struct work_struct *unused); -DECLARE_WORK(cookie_work, wq_cookie_handler); +static DECLARE_WORK(cookie_work, wq_cookie_handler); static struct timer_list app_process_wake_up_timer; static void app_process_wake_up_handler(unsigned long unused_data); @@ -109,36 +114,62 @@ static void cookiemap_add(uint64_t key, uint32_t value) } #ifndef CONFIG_PREEMPT_RT_FULL -static void translate_buffer_write_ptr(int cpu, void *x) +static void translate_buffer_write_args(int cpu, struct task_struct *task, const char *text) { - per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; - per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; + unsigned long flags; + int write; + int next_write; + struct cookie_args *args; + + local_irq_save(flags); + + write = per_cpu(translate_buffer_write, cpu); + next_write = (write + 1) & translate_buffer_mask; + + // At least one entry must always remain available as when read == write, the queue is empty not full + if (next_write != per_cpu(translate_buffer_read, cpu)) { + args = &per_cpu(translate_buffer, cpu)[write]; + args->task = task; + args->text = text; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) + get_task_struct(task); +#endif + per_cpu(translate_buffer_write, cpu) = next_write; + } + + local_irq_restore(flags); } #endif -static void *translate_buffer_read_ptr(int cpu) +static void translate_buffer_read_args(int cpu, struct cookie_args *args) { - void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; - per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; - return value; + unsigned long flags; + int read; + + local_irq_save(flags); + + read = per_cpu(translate_buffer_read, cpu); + *args = per_cpu(translate_buffer, cpu)[read]; + per_cpu(translate_buffer_read, cpu) = (read + 1) & translate_buffer_mask; + + local_irq_restore(flags); } static void wq_cookie_handler(struct work_struct *unused) { - struct task_struct *task; - char *text; + struct cookie_args args; int cpu = get_physical_cpu(), cookie; - unsigned int commit; mutex_lock(&start_mutex); if (gator_started != 0) { - commit = per_cpu(translate_buffer_write, cpu); - while (per_cpu(translate_buffer_read, cpu) != commit) { - task = (struct task_struct *)translate_buffer_read_ptr(cpu); - text = (char *)translate_buffer_read_ptr(cpu); - cookie = get_cookie(cpu, task, text, true); - marshal_link(cookie, task->tgid, task->pid); + while (per_cpu(translate_buffer_read, cpu) != per_cpu(translate_buffer_write, cpu)) { + translate_buffer_read_args(cpu, &args); + cookie = get_cookie(cpu, args.task, args.text, true); + marshal_link(cookie, args.task->tgid, args.task->pid); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) + put_task_struct(args.task); +#endif } } @@ -169,15 +200,14 @@ static int translate_app_process(const char **text, int cpu, struct task_struct // inconsistent during a context switch between android/linux versions if (!from_wq) { // Check if already in buffer - int ptr = per_cpu(translate_buffer_read, cpu); - while (ptr != per_cpu(translate_buffer_write, cpu)) { - if (per_cpu(translate_buffer, cpu)[ptr] == (void *)task) + int pos = per_cpu(translate_buffer_read, cpu); + while (pos != per_cpu(translate_buffer_write, cpu)) { + if (per_cpu(translate_buffer, cpu)[pos].task == task) goto out; - ptr = (ptr + 2) & translate_buffer_mask; + pos = (pos + 1) & translate_buffer_mask; } - translate_buffer_write_ptr(cpu, (void *)task); - translate_buffer_write_ptr(cpu, (void *)*text); + translate_buffer_write_args(cpu, task, *text); // Not safe to call in RT-Preempt full in schedule switch context mod_timer(&app_process_wake_up_timer, jiffies + 1); @@ -340,7 +370,7 @@ static int cookies_initialize(void) } memset(per_cpu(cookie_values, cpu), 0, size); - per_cpu(translate_buffer, cpu) = (void **)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL); + per_cpu(translate_buffer, cpu) = (struct cookie_args *)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL); if (!per_cpu(translate_buffer, cpu)) { err = -ENOMEM; goto cookie_setup_error; diff --git a/drivers/gator/gator_events_armv6.c b/drivers/gator/gator_events_armv6.c index dd7974090b8..35364562230 100644 --- a/drivers/gator/gator_events_armv6.c +++ b/drivers/gator/gator_events_armv6.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_armv7.c b/drivers/gator/gator_events_armv7.c index 30881c8fd3f..153119b463e 100644 --- a/drivers/gator/gator_events_armv7.c +++ b/drivers/gator/gator_events_armv7.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -141,9 +141,9 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry for (i = 0; i < pmnc_counters; i++) { char buf[40]; if (i == 0) { - snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name); + snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name); } else { - snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1); + snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i - 1); } dir = gatorfs_mkdir(sb, root, buf); if (!dir) { @@ -275,25 +275,27 @@ int gator_events_armv7_init(void) switch (gator_cpuid()) { case CORTEX_A5: - pmnc_name = "Cortex-A5"; + pmnc_name = "ARMv7_Cortex_A5"; pmnc_counters = 2; break; case CORTEX_A7: - pmnc_name = "Cortex-A7"; + pmnc_name = "ARMv7_Cortex_A7"; pmnc_counters = 4; break; case CORTEX_A8: - pmnc_name = "Cortex-A8"; + pmnc_name = "ARMv7_Cortex_A8"; pmnc_counters = 4; break; case CORTEX_A9: - pmnc_name = "Cortex-A9"; + pmnc_name = "ARMv7_Cortex_A9"; pmnc_counters = 6; break; + // ARM Cortex A12 is not supported by version of Linux before 3.0 case CORTEX_A15: - pmnc_name = "Cortex-A15"; + pmnc_name = "ARMv7_Cortex_A15"; pmnc_counters = 6; break; + // ARM Cortex A17 is not supported by version of Linux before 3.0 default: return -1; } diff --git a/drivers/gator/gator_events_block.c b/drivers/gator/gator_events_block.c index 691ef257453..b2bc414e462 100644 --- a/drivers/gator/gator_events_block.c +++ b/drivers/gator/gator_events_block.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_ccn-504.c b/drivers/gator/gator_events_ccn-504.c index b89231967c7..024ffc2856a 100644 --- a/drivers/gator/gator_events_ccn-504.c +++ b/drivers/gator/gator_events_ccn-504.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2013. All rights reserved. + * Copyright (C) ARM Limited 2013-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_irq.c b/drivers/gator/gator_events_irq.c index b11879a248f..facbdd62325 100644 --- a/drivers/gator/gator_events_irq.c +++ b/drivers/gator/gator_events_irq.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_l2c-310.c b/drivers/gator/gator_events_l2c-310.c index ee521af2251..553f9707bdb 100644 --- a/drivers/gator/gator_events_l2c-310.c +++ b/drivers/gator/gator_events_l2c-310.c @@ -1,7 +1,7 @@ /** * l2c310 (L2 Cache Controller) event counters for gator * - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_mali_4xx.c b/drivers/gator/gator_events_mali_4xx.c index 6719c1ec73a..85d47645a9d 100644 --- a/drivers/gator/gator_events_mali_4xx.c +++ b/drivers/gator/gator_events_mali_4xx.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_mali_4xx.h b/drivers/gator/gator_events_mali_4xx.h index 413ad0ffe79..976ca8c4cfa 100644 --- a/drivers/gator/gator_events_mali_4xx.h +++ b/drivers/gator/gator_events_mali_4xx.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. + * Copyright (C) ARM Limited 2011-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_mali_common.c b/drivers/gator/gator_events_mali_common.c index 466ca1683c7..dc58dcf0c66 100644 --- a/drivers/gator/gator_events_mali_common.c +++ b/drivers/gator/gator_events_mali_common.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_mali_common.h b/drivers/gator/gator_events_mali_common.h index 509f9b61884..41c2a3c13fa 100644 --- a/drivers/gator/gator_events_mali_common.h +++ b/drivers/gator/gator_events_mali_common.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_mali_t6xx.c b/drivers/gator/gator_events_mali_t6xx.c index 7bf7d6a6dbf..76f14eee767 100644 --- a/drivers/gator/gator_events_mali_t6xx.c +++ b/drivers/gator/gator_events_mali_t6xx.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. + * Copyright (C) ARM Limited 2011-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,7 +15,13 @@ #include #include +#ifdef MALI_DIR_MIDGARD +/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/ +#include "mali_linux_trace.h" +#else +/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/ #include "linux/mali_linux_trace.h" +#endif #include "gator_events_mali_common.h" diff --git a/drivers/gator/gator_events_mali_t6xx_hw.c b/drivers/gator/gator_events_mali_t6xx_hw.c index e406991398d..dfbc91ffd76 100644 --- a/drivers/gator/gator_events_mali_t6xx_hw.c +++ b/drivers/gator/gator_events_mali_t6xx_hw.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,9 +16,17 @@ #include /* Mali T6xx DDK includes */ +#ifdef MALI_DIR_MIDGARD +/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/ +#include "mali_linux_trace.h" +#include "mali_kbase.h" +#include "mali_kbase_mem_linux.h" +#else +/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/ #include "linux/mali_linux_trace.h" #include "kbase/src/common/mali_kbase.h" #include "kbase/src/linux/mali_kbase_mem_linux.h" +#endif #include "gator_events_mali_common.h" diff --git a/drivers/gator/gator_events_mali_t6xx_hw_test.c b/drivers/gator/gator_events_mali_t6xx_hw_test.c index efb32ddf548..ba6553f3540 100644 --- a/drivers/gator/gator_events_mali_t6xx_hw_test.c +++ b/drivers/gator/gator_events_mali_t6xx_hw_test.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_meminfo.c b/drivers/gator/gator_events_meminfo.c index 451290d9af1..c633dfdce30 100644 --- a/drivers/gator/gator_events_meminfo.c +++ b/drivers/gator/gator_events_meminfo.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -274,6 +274,28 @@ static int gator_events_meminfo_read(long long **buffer) return meminfo_length; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) + +static inline unsigned long gator_get_mm_counter(struct mm_struct *mm, int member) +{ +#ifdef SPLIT_RSS_COUNTING + long val = atomic_long_read(&mm->rss_stat.count[member]); + if (val < 0) + val = 0; + return (unsigned long)val; +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) + return mm->rss_stat.count[member]; +#else + return atomic_long_read(&mm->rss_stat.count[member]); +#endif +#endif +} + +#define get_mm_counter(mm, member) gator_get_mm_counter(mm, member) + +#endif + static int gator_events_meminfo_read_proc(long long **buffer, struct task_struct *task) { struct mm_struct *mm; @@ -302,7 +324,7 @@ static int gator_events_meminfo_read_proc(long long **buffer, struct task_struct // Derived from task_statm in fs/proc/task_mmu.c if (meminfo_enabled[MEMINFO_MEMUSED] || proc_enabled[PROC_SHARE]) { share = get_mm_counter(mm, -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 32) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) file_rss #else MM_FILEPAGES @@ -338,7 +360,7 @@ static int gator_events_meminfo_read_proc(long long **buffer, struct task_struct if (meminfo_enabled[MEMINFO_MEMUSED]) { value = share + get_mm_counter(mm, -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 32) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) anon_rss #else MM_ANONPAGES diff --git a/drivers/gator/gator_events_mmapped.c b/drivers/gator/gator_events_mmapped.c index f055e48d317..3b248ec24e6 100644 --- a/drivers/gator/gator_events_mmapped.c +++ b/drivers/gator/gator_events_mmapped.c @@ -1,7 +1,7 @@ /* * Example events provider * - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_net.c b/drivers/gator/gator_events_net.c index 9c8d3a43eae..11c10e37551 100644 --- a/drivers/gator/gator_events_net.c +++ b/drivers/gator/gator_events_net.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_perf_pmu.c b/drivers/gator/gator_events_perf_pmu.c index d472df918ab..8b2d67a058b 100644 --- a/drivers/gator/gator_events_perf_pmu.c +++ b/drivers/gator/gator_events_perf_pmu.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_sched.c b/drivers/gator/gator_events_sched.c index 29f4e39e261..9e391583018 100644 --- a/drivers/gator/gator_events_sched.c +++ b/drivers/gator/gator_events_sched.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_events_scorpion.c b/drivers/gator/gator_events_scorpion.c index c91db1219d0..8ca251af0e2 100644 --- a/drivers/gator/gator_events_scorpion.c +++ b/drivers/gator/gator_events_scorpion.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. + * Copyright (C) ARM Limited 2011-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_fs.c b/drivers/gator/gator_fs.c index fe6f83d547e..166cfe7d681 100644 --- a/drivers/gator/gator_fs.c +++ b/drivers/gator/gator_fs.c @@ -39,12 +39,7 @@ static const struct super_operations s_ops = { .drop_inode = generic_delete_inode, }; -ssize_t gatorfs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset) -{ - return simple_read_from_buffer(buf, count, offset, str, strlen(str)); -} - -ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset) +static ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset) { char tmpbuf[TMPBUFSIZE]; size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val); @@ -53,7 +48,7 @@ ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen); } -ssize_t gatorfs_u64_to_user(u64 val, char __user *buf, size_t count, loff_t *offset) +static ssize_t gatorfs_u64_to_user(u64 val, char __user *buf, size_t count, loff_t *offset) { char tmpbuf[TMPBUFSIZE]; size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%llu\n", val); @@ -62,7 +57,7 @@ ssize_t gatorfs_u64_to_user(u64 val, char __user *buf, size_t count, loff_t *off return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen); } -int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) +static int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) { char tmpbuf[TMPBUFSIZE]; unsigned long flags; @@ -84,7 +79,7 @@ int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t c return 0; } -int gatorfs_u64_from_user(u64 *val, char const __user *buf, size_t count) +static int gatorfs_u64_from_user(u64 *val, char const __user *buf, size_t count) { char tmpbuf[TMPBUFSIZE]; unsigned long flags; @@ -211,8 +206,8 @@ int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, return 0; } -int gatorfs_create_u64(struct super_block *sb, struct dentry *root, - char const *name, u64 *val) +static int gatorfs_create_u64(struct super_block *sb, struct dentry *root, + char const *name, u64 *val) { struct dentry *d = __gatorfs_create_file(sb, root, name, &u64_fops, 0644); @@ -235,8 +230,8 @@ int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, return 0; } -int gatorfs_create_ro_u64(struct super_block *sb, struct dentry *root, - char const *name, u64 * val) +static int gatorfs_create_ro_u64(struct super_block *sb, struct dentry *root, + char const *name, u64 * val) { struct dentry *d = __gatorfs_create_file(sb, root, name, &u64_ro_fops, 0444); @@ -258,29 +253,17 @@ static const struct file_operations atomic_ro_fops = { .open = default_open, }; -int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root, - char const *name, atomic_t *val) -{ - struct dentry *d = __gatorfs_create_file(sb, root, name, - &atomic_ro_fops, 0444); - if (!d) - return -EFAULT; - - d->d_inode->i_private = val; - return 0; -} - -int gatorfs_create_file(struct super_block *sb, struct dentry *root, - char const *name, const struct file_operations *fops) +static int gatorfs_create_file(struct super_block *sb, struct dentry *root, + char const *name, const struct file_operations *fops) { if (!__gatorfs_create_file(sb, root, name, fops, 0644)) return -EFAULT; return 0; } -int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, - char const *name, - const struct file_operations *fops, int perm) +static int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, + char const *name, + const struct file_operations *fops, int perm) { if (!__gatorfs_create_file(sb, root, name, fops, perm)) return -EFAULT; @@ -371,12 +354,12 @@ static struct file_system_type gatorfs_type = { .kill_sb = kill_litter_super, }; -int __init gatorfs_register(void) +static int __init gatorfs_register(void) { return register_filesystem(&gatorfs_type); } -void gatorfs_unregister(void) +static void gatorfs_unregister(void) { unregister_filesystem(&gatorfs_type); } diff --git a/drivers/gator/gator_hrtimer_gator.c b/drivers/gator/gator_hrtimer_gator.c index b0c947afe1e..76584554b00 100644 --- a/drivers/gator/gator_hrtimer_gator.c +++ b/drivers/gator/gator_hrtimer_gator.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. + * Copyright (C) ARM Limited 2011-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -7,10 +7,6 @@ * */ -// gator_hrtimer_perf.c is used if perf is supported -// update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers -#if 1 - void (*callback)(void); DEFINE_PER_CPU(struct hrtimer, percpu_hrtimer); DEFINE_PER_CPU(ktime_t, hrtimer_expire); @@ -82,5 +78,3 @@ static void gator_hrtimer_shutdown(void) { /* empty */ } - -#endif diff --git a/drivers/gator/gator_hrtimer_perf.c b/drivers/gator/gator_hrtimer_perf.c deleted file mode 100644 index 7b95399478e..00000000000 --- a/drivers/gator/gator_hrtimer_perf.c +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -// gator_hrtimer_gator.c is used if perf is not supported -// update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers -#if 0 - -// Note: perf Cortex support added in 2.6.35 and PERF_COUNT_SW_CPU_CLOCK/hrtimer broken on 2.6.35 and 2.6.36 -// not relevant as this code is not active until 3.0.0, but wanted to document the issue - -void (*callback)(void); -static int profiling_interval; -static DEFINE_PER_CPU(struct perf_event *, perf_hrtimer); -static DEFINE_PER_CPU(struct perf_event_attr *, perf_hrtimer_attr); - -static void gator_hrtimer_shutdown(void); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) -static void hrtimer_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) -#else -static void hrtimer_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) -#endif -{ - (*callback)(); -} - -static int gator_online_single_hrtimer(int cpu) -{ - if (per_cpu(perf_hrtimer, cpu) != 0 || per_cpu(perf_hrtimer_attr, cpu) == 0) - return 0; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) - per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler); -#else - per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler, 0); -#endif - if (IS_ERR(per_cpu(perf_hrtimer, cpu))) { - per_cpu(perf_hrtimer, cpu) = NULL; - return -1; - } - - if (per_cpu(perf_hrtimer, cpu)->state != PERF_EVENT_STATE_ACTIVE) { - perf_event_release_kernel(per_cpu(perf_hrtimer, cpu)); - per_cpu(perf_hrtimer, cpu) = NULL; - return -1; - } - - return 0; -} - -static void gator_hrtimer_online(int cpu) -{ - if (gator_online_single_hrtimer(cpu) < 0) { - pr_debug("gator: unable to online the hrtimer on cpu%d\n", cpu); - } -} - -static void gator_hrtimer_offline(int cpu) -{ - if (per_cpu(perf_hrtimer, cpu)) { - perf_event_release_kernel(per_cpu(perf_hrtimer, cpu)); - per_cpu(perf_hrtimer, cpu) = NULL; - } -} - -static int gator_hrtimer_init(int interval, void (*func)(void)) -{ - u32 size = sizeof(struct perf_event_attr); - int cpu; - - callback = func; - - // calculate profiling interval - profiling_interval = 1000000000 / interval; - - for_each_present_cpu(cpu) { - per_cpu(perf_hrtimer, cpu) = 0; - per_cpu(perf_hrtimer_attr, cpu) = kmalloc(size, GFP_KERNEL); - if (per_cpu(perf_hrtimer_attr, cpu) == 0) { - gator_hrtimer_shutdown(); - return -1; - } - - memset(per_cpu(perf_hrtimer_attr, cpu), 0, size); - per_cpu(perf_hrtimer_attr, cpu)->type = PERF_TYPE_SOFTWARE; - per_cpu(perf_hrtimer_attr, cpu)->size = size; - per_cpu(perf_hrtimer_attr, cpu)->config = PERF_COUNT_SW_CPU_CLOCK; - per_cpu(perf_hrtimer_attr, cpu)->sample_period = profiling_interval; - per_cpu(perf_hrtimer_attr, cpu)->pinned = 1; - } - - return 0; -} - -static void gator_hrtimer_shutdown(void) -{ - int cpu; - - for_each_present_cpu(cpu) { - if (per_cpu(perf_hrtimer_attr, cpu)) { - kfree(per_cpu(perf_hrtimer_attr, cpu)); - per_cpu(perf_hrtimer_attr, cpu) = NULL; - } - } -} - -#endif diff --git a/drivers/gator/gator_iks.c b/drivers/gator/gator_iks.c index 24233d77558..e90dfcce938 100644 --- a/drivers/gator/gator_iks.c +++ b/drivers/gator/gator_iks.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2013. All rights reserved. + * Copyright (C) ARM Limited 2013-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -147,11 +147,13 @@ static void gator_send_iks_core_names(void) { int cpu; // Send the cpu names + preempt_disable(); for (cpu = 0; cpu < nr_cpu_ids; ++cpu) { if (mpidr_cpus[cpu] != NULL) { gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid, mpidr_cpus[cpu]); } } + preempt_enable(); } static int gator_migrate_start(void) diff --git a/drivers/gator/gator_main.c b/drivers/gator/gator_main.c index 9773ae24d6f..e67f7c5cc61 100644 --- a/drivers/gator/gator_main.c +++ b/drivers/gator/gator_main.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -8,7 +8,7 @@ */ // This version must match the gator daemon version -#define PROTOCOL_VERSION 17 +#define PROTOCOL_VERSION 18 static unsigned long gator_protocol_version = PROTOCOL_VERSION; #include @@ -89,20 +89,27 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION; #define MESSAGE_END_BACKTRACE 1 +// Name Frame Messages #define MESSAGE_COOKIE 1 #define MESSAGE_THREAD_NAME 2 -#define HRTIMER_CORE_NAME 3 #define MESSAGE_LINK 4 +// GPU Trace Frame Messages #define MESSAGE_GPU_START 1 #define MESSAGE_GPU_STOP 2 +// Scheduler Trace Frame Messages #define MESSAGE_SCHED_SWITCH 1 #define MESSAGE_SCHED_EXIT 2 #define MESSAGE_SCHED_START 3 +// Idle Frame Messages #define MESSAGE_IDLE_ENTER 1 -#define MESSAGE_IDLE_EXIT 2 +#define MESSAGE_IDLE_EXIT 2 + +// Summary Frame Messages +#define MESSAGE_SUMMARY 1 +#define MESSAGE_CORE_NAME 3 #define MAXSIZE_PACK32 5 #define MAXSIZE_PACK64 10 @@ -154,7 +161,13 @@ bool event_based_sampling; 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_stop; +static bool gator_buffer_wake_run; +// Initialize semaphore unlocked to initialize memory values +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) +static DECLARE_MUTEX(gator_buffer_wake_sem); +#else +static DEFINE_SEMAPHORE(gator_buffer_wake_sem); +#endif static struct task_struct *gator_buffer_wake_thread; static LIST_HEAD(gator_events); @@ -164,21 +177,19 @@ static bool printed_monotonic_warning; static bool sent_core_name[NR_CPUS]; +static DEFINE_PER_CPU(bool, in_scheduler_context); + /****************************************************************************** * Prototypes ******************************************************************************/ -static void buffer_check(int cpu, int buftype, u64 time); -static void gator_commit_buffer(int cpu, int buftype, u64 time); -static int buffer_bytes_available(int cpu, int buftype); -static bool buffer_check_space(int cpu, int buftype, int bytes); -static int contiguous_space_available(int cpu, int bufytpe); -static void gator_buffer_write_packed_int(int cpu, int buftype, int x); -static void gator_buffer_write_packed_int64(int cpu, int buftype, long long x); -static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len); -static void gator_buffer_write_string(int cpu, int buftype, const char *x); -static void gator_add_trace(int cpu, unsigned long address); -static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time); static u64 gator_get_time(void); +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 // 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]; @@ -229,8 +240,10 @@ GATOR_EVENTS_LIST /****************************************************************************** * Application Includes ******************************************************************************/ +#include "gator_fs.c" +#include "gator_buffer_write.c" +#include "gator_buffer.c" #include "gator_marshaling.c" -#include "gator_hrtimer_perf.c" #include "gator_hrtimer_gator.c" #include "gator_cookies.c" #include "gator_annotate.c" @@ -238,14 +251,12 @@ GATOR_EVENTS_LIST #include "gator_trace_power.c" #include "gator_trace_gpu.c" #include "gator_backtrace.c" -#include "gator_fs.c" -#include "gator_pack.c" /****************************************************************************** * Misc ******************************************************************************/ -const struct gator_cpu gator_cpus[] = { +static const struct gator_cpu gator_cpus[] = { { .cpuid = ARM1136, .core_name = "ARM1136", @@ -277,51 +288,52 @@ const struct gator_cpu gator_cpus[] = { { .cpuid = CORTEX_A5, .core_name = "Cortex-A5", - .pmu_name = "ARMv7_Cortex_A5", - .pmnc_name = "ARM_Cortex-A5", + .pmnc_name = "ARMv7_Cortex_A5", .dt_name = "arm,cortex-a5", .pmnc_counters = 2, }, { .cpuid = CORTEX_A7, .core_name = "Cortex-A7", - .pmu_name = "ARMv7_Cortex_A7", - .pmnc_name = "ARM_Cortex-A7", + .pmnc_name = "ARMv7_Cortex_A7", .dt_name = "arm,cortex-a7", .pmnc_counters = 4, }, { .cpuid = CORTEX_A8, .core_name = "Cortex-A8", - .pmu_name = "ARMv7_Cortex_A8", - .pmnc_name = "ARM_Cortex-A8", + .pmnc_name = "ARMv7_Cortex_A8", .dt_name = "arm,cortex-a8", .pmnc_counters = 4, }, { .cpuid = CORTEX_A9, .core_name = "Cortex-A9", - .pmu_name = "ARMv7_Cortex_A9", - .pmnc_name = "ARM_Cortex-A9", + .pmnc_name = "ARMv7_Cortex_A9", .dt_name = "arm,cortex-a9", .pmnc_counters = 6, }, { .cpuid = CORTEX_A12, .core_name = "Cortex-A12", - .pmu_name = "ARMv7_Cortex_A12", - .pmnc_name = "ARM_Cortex-A12", + .pmnc_name = "ARMv7_Cortex_A12", .dt_name = "arm,cortex-a12", .pmnc_counters = 6, }, { .cpuid = CORTEX_A15, .core_name = "Cortex-A15", - .pmu_name = "ARMv7_Cortex_A15", - .pmnc_name = "ARM_Cortex-A15", + .pmnc_name = "ARMv7_Cortex_A15", .dt_name = "arm,cortex-a15", .pmnc_counters = 6, }, + { + .cpuid = CORTEX_A17, + .core_name = "Cortex-A17", + .pmnc_name = "ARMv7_Cortex_A17", + .dt_name = "arm,cortex-a17", + .pmnc_counters = 6, + }, { .cpuid = SCORPION, .core_name = "Scorpion", @@ -401,7 +413,7 @@ const struct gator_cpu *gator_find_cpu_by_pmu_name(const char *const name) for (i = 0; gator_cpus[i].cpuid != 0; ++i) { const struct gator_cpu *const gator_cpu = &gator_cpus[i]; - if (gator_cpu->pmu_name != NULL && strcmp(gator_cpu->pmu_name, name) == 0) { + if (gator_cpu->pmnc_name != NULL && strcmp(gator_cpu->pmnc_name, name) == 0) { return gator_cpu; } } @@ -431,10 +443,15 @@ static void gator_buffer_wake_up(unsigned long data) static int gator_buffer_wake_func(void *data) { - while (!gator_buffer_wake_stop) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - if (gator_buffer_wake_stop) { + for (;;) { + if (down_killable(&gator_buffer_wake_sem)) { + break; + } + + // Eat up any pending events + while (!down_trylock(&gator_buffer_wake_sem)); + + if (!gator_buffer_wake_run) { break; } @@ -463,173 +480,6 @@ static bool buffer_commit_ready(int *cpu, int *buftype) return false; } -/****************************************************************************** - * Buffer management - ******************************************************************************/ -static int buffer_bytes_available(int cpu, int buftype) -{ - int remaining, filled; - - filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype]; - if (filled < 0) { - filled += gator_buffer_size[buftype]; - } - - remaining = gator_buffer_size[buftype] - filled; - - if (per_cpu(buffer_space_available, cpu)[buftype]) { - // Give some extra room; also allows space to insert the overflow error packet - remaining -= 200; - } else { - // Hysteresis, prevents multiple overflow messages - remaining -= 2000; - } - - return remaining; -} - -static int contiguous_space_available(int cpu, int buftype) -{ - int remaining = buffer_bytes_available(cpu, buftype); - int contiguous = gator_buffer_size[buftype] - per_cpu(gator_buffer_write, cpu)[buftype]; - if (remaining < contiguous) - return remaining; - else - return contiguous; -} - -static bool buffer_check_space(int cpu, int buftype, int bytes) -{ - int remaining = buffer_bytes_available(cpu, buftype); - - if (remaining < bytes) { - per_cpu(buffer_space_available, cpu)[buftype] = false; - } else { - per_cpu(buffer_space_available, cpu)[buftype] = true; - } - - return per_cpu(buffer_space_available, cpu)[buftype]; -} - -static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len) -{ - int i; - u32 write = per_cpu(gator_buffer_write, cpu)[buftype]; - u32 mask = gator_buffer_mask[buftype]; - char *buffer = per_cpu(gator_buffer, cpu)[buftype]; - - for (i = 0; i < len; i++) { - buffer[write] = x[i]; - write = (write + 1) & mask; - } - - per_cpu(gator_buffer_write, cpu)[buftype] = write; -} - -static void gator_buffer_write_string(int cpu, int buftype, const char *x) -{ - int len = strlen(x); - gator_buffer_write_packed_int(cpu, buftype, len); - gator_buffer_write_bytes(cpu, buftype, x, len); -} - -static void gator_commit_buffer(int cpu, int buftype, u64 time) -{ - int type_length, commit, length, byte; - - if (!per_cpu(gator_buffer, cpu)[buftype]) - return; - - // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload - type_length = gator_response_type ? 1 : 0; - commit = per_cpu(gator_buffer_commit, cpu)[buftype]; - length = per_cpu(gator_buffer_write, cpu)[buftype] - commit; - if (length < 0) { - length += gator_buffer_size[buftype]; - } - length = length - type_length - sizeof(s32); - - if (length <= FRAME_HEADER_SIZE) { - // Nothing to write, only the frame header is present - return; - } - - for (byte = 0; byte < sizeof(s32); byte++) { - per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF; - } - - per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype]; - - if (gator_live_rate > 0) { - while (time > per_cpu(gator_buffer_commit_time, cpu)) { - per_cpu(gator_buffer_commit_time, cpu) += gator_live_rate; - } - } - - marshal_frame(cpu, buftype); - - // had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater - if (per_cpu(in_scheduler_context, cpu)) { -#ifndef CONFIG_PREEMPT_RT_FULL - // mod_timer can not be used in interrupt context in RT-Preempt full - mod_timer(&gator_buffer_wake_up_timer, jiffies + 1); -#endif - } else { - wake_up_process(gator_buffer_wake_thread); - } -} - -static void buffer_check(int cpu, int buftype, u64 time) -{ - int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype]; - if (filled < 0) { - filled += gator_buffer_size[buftype]; - } - if (filled >= ((gator_buffer_size[buftype] * 3) / 4)) { - gator_commit_buffer(cpu, buftype, time); - } -} - -static void gator_add_trace(int cpu, unsigned long address) -{ - off_t offset = 0; - unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset); - - if (cookie == NO_COOKIE || cookie == UNRESOLVED_COOKIE) { - offset = address; - } - - marshal_backtrace(offset & ~1, cookie); -} - -static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time) -{ - bool inKernel; - unsigned long exec_cookie; - - if (!regs) - return; - - inKernel = !user_mode(regs); - exec_cookie = get_exec_cookie(cpu, current); - - if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel, time)) - return; - - if (inKernel) { - kernel_backtrace(cpu, regs); - } else { - // Cookie+PC - gator_add_trace(cpu, PC_REG); - - // Backtrace - if (gator_backtrace_depth) - arm_backtrace_eabi(cpu, regs, gator_backtrace_depth); - } - - marshal_backtrace_footer(time); -} - /****************************************************************************** * hrtimer interrupt processing ******************************************************************************/ @@ -721,7 +571,8 @@ static void gator_timer_stop(void) } #if defined(__arm__) || defined(__aarch64__) -static void gator_send_core_name(int cpu, const u32 cpuid, const struct gator_cpu *const gator_cpu) { +static void gator_send_core_name(int cpu, const u32 cpuid, const struct gator_cpu *const gator_cpu) +{ const char *core_name = NULL; char core_name_buf[32]; @@ -788,7 +639,7 @@ static void gator_timer_online_dispatch(int cpu, bool migrate) #include "gator_iks.c" -int gator_timer_start(unsigned long sample_rate) +static int gator_timer_start(unsigned long sample_rate) { int cpu; @@ -944,7 +795,6 @@ static void gator_summary(void) struct timespec ts; char uname_buf[512]; void (*m2b)(struct timespec *ts); - unsigned long flags; snprintf(uname_buf, sizeof(uname_buf), "%s %s %s %s %s GNU/Linux", utsname()->sysname, utsname()->nodename, utsname()->release, utsname()->version, utsname()->machine); @@ -959,14 +809,14 @@ static void gator_summary(void) } uptime = timespec_to_ns(&ts); - // Disable interrupts as gator_get_time calls smp_processor_id to verify time is monotonic - local_irq_save(flags); + // 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 gator_monotonic_started = 0; gator_monotonic_started = gator_get_time(); - local_irq_restore(flags); marshal_summary(timestamp, uptime, gator_monotonic_started, uname_buf); + preempt_enable(); } int gator_events_install(struct gator_interface *interface) @@ -1019,7 +869,7 @@ static int gator_start(void) unsigned long cpu, i; struct gator_interface *gi; - gator_buffer_wake_stop = false; + gator_buffer_wake_run = true; if (IS_ERR(gator_buffer_wake_thread = kthread_run(gator_buffer_wake_func, NULL, "gator_bwake"))) { goto bwake_failure; } @@ -1094,8 +944,9 @@ cookies_failure: events_failure: gator_migrate_stop(); migrate_failure: - gator_buffer_wake_stop = true; - wake_up_process(gator_buffer_wake_thread); + gator_buffer_wake_run = false; + up(&gator_buffer_wake_sem); + gator_buffer_wake_thread = NULL; bwake_failure: return -1; @@ -1121,8 +972,9 @@ static void gator_stop(void) gator_migrate_stop(); - gator_buffer_wake_stop = true; - wake_up_process(gator_buffer_wake_thread); + gator_buffer_wake_run = false; + up(&gator_buffer_wake_sem); + gator_buffer_wake_thread = NULL; } /****************************************************************************** @@ -1417,7 +1269,7 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf, size_t return written > 0 ? written : -EFAULT; } -const struct file_operations gator_event_buffer_fops = { +static const struct file_operations gator_event_buffer_fops = { .open = userspace_buffer_open, .release = userspace_buffer_release, .read = userspace_buffer_read, @@ -1452,7 +1304,7 @@ static const struct file_operations depth_fops = { .write = depth_write }; -void gator_op_create_files(struct super_block *sb, struct dentry *root) +static void gator_op_create_files(struct super_block *sb, struct dentry *root) { struct dentry *dir; struct gator_interface *gi; diff --git a/drivers/gator/gator_marshaling.c b/drivers/gator/gator_marshaling.c index af80ff62e71..fd413ad1331 100644 --- a/drivers/gator/gator_marshaling.c +++ b/drivers/gator/gator_marshaling.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2012-2013. All rights reserved. + * Copyright (C) ARM Limited 2012-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -29,6 +29,7 @@ static void marshal_summary(long long timestamp, long long uptime, long long mon int cpu = 0; local_irq_save(flags); + gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_SUMMARY); gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY); gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp); gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime); @@ -52,8 +53,8 @@ static void marshal_summary(long long timestamp, long long uptime, long long mon #endif gator_buffer_write_string(cpu, SUMMARY_BUF, ""); // Commit the buffer now so it can be one of the first frames read by Streamline - gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time()); local_irq_restore(flags); + gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time()); } static bool marshal_cookie_header(const char *text) @@ -85,8 +86,8 @@ static void marshal_thread_name(int pid, char *name) gator_buffer_write_packed_int(cpu, NAME_BUF, pid); gator_buffer_write_string(cpu, NAME_BUF, name); } - buffer_check(cpu, NAME_BUF, time); local_irq_restore(flags); + buffer_check(cpu, NAME_BUF, time); } static void marshal_link(int cookie, int tgid, int pid) @@ -103,12 +104,12 @@ static void marshal_link(int cookie, int tgid, int pid) gator_buffer_write_packed_int(cpu, NAME_BUF, tgid); gator_buffer_write_packed_int(cpu, NAME_BUF, pid); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, NAME_BUF, time); - local_irq_restore(flags); } -static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel, u64 time) +static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time) { int cpu = get_physical_cpu(); if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) { @@ -122,14 +123,16 @@ static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inK gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie); gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid); gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid); - gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel); return true; } -static void marshal_backtrace(unsigned long address, int cookie) +static void marshal_backtrace(unsigned long address, int cookie, int in_kernel) { int cpu = get_physical_cpu(); + if (cookie == 0 && !in_kernel) { + cookie = UNRESOLVED_COOKIE; + } gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie); gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address); } @@ -224,9 +227,9 @@ static void marshal_event_single(int core, int key, int value) gator_buffer_write_packed_int(cpu, COUNTER_BUF, key); gator_buffer_write_packed_int(cpu, COUNTER_BUF, value); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, COUNTER_BUF, time); - local_irq_restore(flags); } #endif @@ -248,9 +251,9 @@ static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid) gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid); gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, GPU_TRACE_BUF, time); - local_irq_restore(flags); } static void marshal_sched_gpu_stop(int unit, int core) @@ -269,9 +272,9 @@ static void marshal_sched_gpu_stop(int unit, int core) gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit); gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, GPU_TRACE_BUF, time); - local_irq_restore(flags); } static void marshal_sched_trace_start(int tgid, int pid, int cookie) @@ -291,9 +294,9 @@ static void marshal_sched_trace_start(int tgid, int pid, int cookie) gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid); gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, SCHED_TRACE_BUF, time); - local_irq_restore(flags); } static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state) @@ -314,9 +317,9 @@ static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state) gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie); gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, SCHED_TRACE_BUF, time); - local_irq_restore(flags); } static void marshal_sched_trace_exit(int tgid, int pid) @@ -334,9 +337,9 @@ static void marshal_sched_trace_exit(int tgid, int pid) gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time); gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, SCHED_TRACE_BUF, time); - local_irq_restore(flags); } #if GATOR_CPU_FREQ_SUPPORT @@ -353,80 +356,26 @@ static void marshal_idle(int core, int state) gator_buffer_write_packed_int64(cpu, IDLE_BUF, time); gator_buffer_write_packed_int(cpu, IDLE_BUF, core); } + local_irq_restore(flags); // Check and commit; commit is set to occur once buffer is 3/4 full buffer_check(cpu, IDLE_BUF, time); - local_irq_restore(flags); } #endif -static void marshal_frame(int cpu, int buftype) -{ - int frame; - - if (!per_cpu(gator_buffer, cpu)[buftype]) { - return; - } - - switch (buftype) { - case SUMMARY_BUF: - frame = FRAME_SUMMARY; - break; - case BACKTRACE_BUF: - frame = FRAME_BACKTRACE; - break; - case NAME_BUF: - frame = FRAME_NAME; - break; - case COUNTER_BUF: - frame = FRAME_COUNTER; - break; - case BLOCK_COUNTER_BUF: - frame = FRAME_BLOCK_COUNTER; - break; - case ANNOTATE_BUF: - frame = FRAME_ANNOTATE; - break; - case SCHED_TRACE_BUF: - frame = FRAME_SCHED_TRACE; - break; - case GPU_TRACE_BUF: - frame = FRAME_GPU_TRACE; - break; - case IDLE_BUF: - frame = FRAME_IDLE; - break; - default: - frame = -1; - break; - } - - // add response type - if (gator_response_type > 0) { - gator_buffer_write_packed_int(cpu, buftype, gator_response_type); - } - - // leave space for 4-byte unpacked length - per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype]; - - // add frame type and core number - gator_buffer_write_packed_int(cpu, buftype, frame); - gator_buffer_write_packed_int(cpu, buftype, cpu); -} - #if defined(__arm__) || defined(__aarch64__) static void marshal_core_name(const int core, const int cpuid, const char *name) { int cpu = get_physical_cpu(); unsigned long flags; local_irq_save(flags); - if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) { - gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME); - gator_buffer_write_packed_int(cpu, NAME_BUF, core); - gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid); - gator_buffer_write_string(cpu, NAME_BUF, name); + if (buffer_check_space(cpu, SUMMARY_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) { + gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_CORE_NAME); + gator_buffer_write_packed_int(cpu, SUMMARY_BUF, core); + gator_buffer_write_packed_int(cpu, SUMMARY_BUF, cpuid); + gator_buffer_write_string(cpu, SUMMARY_BUF, name); } // Commit core names now so that they can show up in live - gator_commit_buffer(cpu, NAME_BUF, gator_get_time()); local_irq_restore(flags); + gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time()); } #endif diff --git a/drivers/gator/gator_pack.c b/drivers/gator/gator_pack.c deleted file mode 100644 index 2c082f283ad..00000000000 --- a/drivers/gator/gator_pack.c +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -static void gator_buffer_write_packed_int(int cpu, int buftype, int x) -{ - uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; - uint32_t mask = gator_buffer_mask[buftype]; - char *buffer = per_cpu(gator_buffer, cpu)[buftype]; - int packedBytes = 0; - int more = true; - while (more) { - // low order 7 bits of x - char b = x & 0x7f; - x >>= 7; - - if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) { - more = false; - } else { - b |= 0x80; - } - - buffer[(write + packedBytes) & mask] = b; - packedBytes++; - } - - per_cpu(gator_buffer_write, cpu)[buftype] = (write + packedBytes) & mask; -} - -static void gator_buffer_write_packed_int64(int cpu, int buftype, long long x) -{ - uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; - uint32_t mask = gator_buffer_mask[buftype]; - char *buffer = per_cpu(gator_buffer, cpu)[buftype]; - int packedBytes = 0; - int more = true; - while (more) { - // low order 7 bits of x - char b = x & 0x7f; - x >>= 7; - - if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) { - more = false; - } else { - b |= 0x80; - } - - buffer[(write + packedBytes) & mask] = b; - packedBytes++; - } - - per_cpu(gator_buffer_write, cpu)[buftype] = (write + packedBytes) & mask; -} diff --git a/drivers/gator/gator_trace_gpu.c b/drivers/gator/gator_trace_gpu.c index be135b4aac5..6332098e595 100644 --- a/drivers/gator/gator_trace_gpu.c +++ b/drivers/gator/gator_trace_gpu.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,8 +14,15 @@ #include #ifdef MALI_SUPPORT +#ifdef MALI_DIR_MIDGARD +/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/ +#include "mali_linux_trace.h" +#else +/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/ #include "linux/mali_linux_trace.h" #endif +#endif + #include "gator_trace_gpu.h" /* @@ -235,7 +242,7 @@ GATOR_DEFINE_PROBE(gpu_activity_stop, TP_PROTO(int gpu_unit, int gpu_core)) mali_gpu_stop(gpu_unit, gpu_core); } -int gator_trace_gpu_start(void) +static int gator_trace_gpu_start(void) { /* * Returns nonzero for installation failed @@ -271,7 +278,7 @@ int gator_trace_gpu_start(void) return 0; } -void gator_trace_gpu_stop(void) +static void gator_trace_gpu_stop(void) { #if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx) if (mali_timeline_trace_registered) { diff --git a/drivers/gator/gator_trace_gpu.h b/drivers/gator/gator_trace_gpu.h index bb0f42d290d..5113d459e24 100644 --- a/drivers/gator/gator_trace_gpu.h +++ b/drivers/gator/gator_trace_gpu.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/gator_trace_power.c b/drivers/gator/gator_trace_power.c index 272e05684ee..1895bb988c9 100644 --- a/drivers/gator/gator_trace_power.c +++ b/drivers/gator/gator_trace_power.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2011-2013. All rights reserved. + * Copyright (C) ARM Limited 2011-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -166,7 +166,7 @@ static void gator_trace_power_stop(void) } } -void gator_trace_power_init(void) +static void gator_trace_power_init(void) { int i; for (i = 0; i < POWER_TOTAL; i++) { @@ -197,7 +197,7 @@ static void gator_trace_power_stop(void) { } -void gator_trace_power_init(void) +static void gator_trace_power_init(void) { } #endif diff --git a/drivers/gator/gator_trace_sched.c b/drivers/gator/gator_trace_sched.c index 332b3f6ba96..52990e9d481 100644 --- a/drivers/gator/gator_trace_sched.c +++ b/drivers/gator/gator_trace_sched.c @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2010-2013. All rights reserved. + * Copyright (C) ARM Limited 2010-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,7 +22,6 @@ enum { static DEFINE_PER_CPU(uint64_t *, taskname_keys); static DEFINE_PER_CPU(int, collecting); -static DEFINE_PER_CPU(bool, in_scheduler_context); // this array is never read as the cpu wait charts are derived counters // the files are needed, nonetheless, to show that these counters are available @@ -52,7 +51,7 @@ static int sched_trace_create_files(struct super_block *sb, struct dentry *root) return 0; } -void emit_pid_name(struct task_struct *task) +static void emit_pid_name(struct task_struct *task) { bool found = false; char taskcomm[TASK_COMM_LEN + 3]; @@ -116,20 +115,21 @@ static void collect_counters(u64 time, struct task_struct *task) // Commit buffers on timeout if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF }; - unsigned long flags; int i; - local_irq_save(flags); for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { gator_commit_buffer(cpu, buftypes[i], time); } - local_irq_restore(flags); + // spinlocks are noops on uniprocessor machines and mutexes do not work in sched_switch context in + // RT-Preempt full, so disable proactive flushing of the annotate frame on uniprocessor machines. +#ifdef CONFIG_SMP // Try to preemptively flush the annotate buffer to reduce the chance of the buffer being full if (on_primary_core() && spin_trylock(&annotate_lock)) { gator_commit_buffer(0, ANNOTATE_BUF, time); spin_unlock(&annotate_lock); } +#endif } } } @@ -222,7 +222,7 @@ fail_sched_process_fork: return -1; } -int gator_trace_sched_start(void) +static int gator_trace_sched_start(void) { int cpu, size; @@ -237,7 +237,7 @@ int gator_trace_sched_start(void) return register_scheduler_tracepoints(); } -void gator_trace_sched_offline(void) +static void gator_trace_sched_offline(void) { trace_sched_insert_idle(); } @@ -250,7 +250,7 @@ static void unregister_scheduler_tracepoints(void) pr_debug("gator: unregistered tracepoints\n"); } -void gator_trace_sched_stop(void) +static void gator_trace_sched_stop(void) { int cpu; unregister_scheduler_tracepoints(); @@ -260,7 +260,7 @@ void gator_trace_sched_stop(void) } } -void gator_trace_sched_init(void) +static void gator_trace_sched_init(void) { int i; for (i = 0; i < CPU_WAIT_TOTAL; i++) { diff --git a/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h b/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h index 347a4fe404b..ff00d90cee7 100644 --- a/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h +++ b/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2013. All rights reserved. + * Copyright (C) ARM Limited 2013-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/mali/mali_utgard_profiling_gator_api.h b/drivers/gator/mali/mali_utgard_profiling_gator_api.h index 559647a76d2..43c57604288 100644 --- a/drivers/gator/mali/mali_utgard_profiling_gator_api.h +++ b/drivers/gator/mali/mali_utgard_profiling_gator_api.h @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2013. All rights reserved. + * Copyright (C) ARM Limited 2013-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/gator/mali_t6xx.mk b/drivers/gator/mali_t6xx.mk index 1a98c1c6a73..059d47aec91 100644 --- a/drivers/gator/mali_t6xx.mk +++ b/drivers/gator/mali_t6xx.mk @@ -10,8 +10,17 @@ EXTRA_CFLAGS += -DMALI_USE_UMP=1 \ -DMALI_NO_MALI=0 DDK_DIR ?= . +ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/t6xx),) KBASE_DIR = $(DDK_DIR)/drivers/gpu/arm/t6xx/kbase OSK_DIR = $(DDK_DIR)/drivers/gpu/arm/t6xx/kbase/osk +endif + +ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/midgard),) +KBASE_DIR = $(DDK_DIR)/drivers/gpu/arm/midgard +OSK_DIR = $(DDK_DIR)/drivers/gpu/arm/midgard/osk +EXTRA_CFLAGS += -DMALI_DIR_MIDGARD=1 +endif + UMP_DIR = $(DDK_DIR)/include/linux # Include directories in the DDK -- cgit v1.2.3