aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2014-04-10 09:02:02 +0100
committerJon Medhurst <tixy@linaro.org>2014-04-10 12:11:17 +0100
commit15ce78dafc08b1c5c3ec8f42070ae37160b5154c (patch)
treecdb25c6758ac3fe5ac6f9e151642a4779e2fc742 /drivers
parent34d9769988397a1edf93ad1966c167591ab29e79 (diff)
gator: Version 5.18
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gator/Kconfig39
-rw-r--r--drivers/gator/gator.h13
-rw-r--r--drivers/gator/gator_annotate.c2
-rw-r--r--drivers/gator/gator_annotate_kernel.c8
-rw-r--r--drivers/gator/gator_backtrace.c48
-rw-r--r--drivers/gator/gator_buffer.c168
-rw-r--r--drivers/gator/gator_buffer_write.c (renamed from drivers/gator/gator_pack.c)24
-rw-r--r--drivers/gator/gator_cookies.c82
-rw-r--r--drivers/gator/gator_events_armv6.c2
-rw-r--r--drivers/gator/gator_events_armv7.c18
-rw-r--r--drivers/gator/gator_events_block.c2
-rw-r--r--drivers/gator/gator_events_ccn-504.c2
-rw-r--r--drivers/gator/gator_events_irq.c2
-rw-r--r--drivers/gator/gator_events_l2c-310.c2
-rw-r--r--drivers/gator/gator_events_mali_4xx.c2
-rw-r--r--drivers/gator/gator_events_mali_4xx.h2
-rw-r--r--drivers/gator/gator_events_mali_common.c2
-rw-r--r--drivers/gator/gator_events_mali_common.h2
-rw-r--r--drivers/gator/gator_events_mali_t6xx.c8
-rw-r--r--drivers/gator/gator_events_mali_t6xx_hw.c10
-rw-r--r--drivers/gator/gator_events_mali_t6xx_hw_test.c2
-rw-r--r--drivers/gator/gator_events_meminfo.c28
-rw-r--r--drivers/gator/gator_events_mmapped.c2
-rw-r--r--drivers/gator/gator_events_net.c2
-rw-r--r--drivers/gator/gator_events_perf_pmu.c2
-rw-r--r--drivers/gator/gator_events_sched.c2
-rw-r--r--drivers/gator/gator_events_scorpion.c2
-rw-r--r--drivers/gator/gator_fs.c47
-rw-r--r--drivers/gator/gator_hrtimer_gator.c8
-rw-r--r--drivers/gator/gator_hrtimer_perf.c113
-rw-r--r--drivers/gator/gator_iks.c4
-rw-r--r--drivers/gator/gator_main.c286
-rw-r--r--drivers/gator/gator_marshaling.c97
-rw-r--r--drivers/gator/gator_trace_gpu.c13
-rw-r--r--drivers/gator/gator_trace_gpu.h2
-rw-r--r--drivers/gator/gator_trace_power.c6
-rw-r--r--drivers/gator/gator_trace_sched.c20
-rw-r--r--drivers/gator/mali/mali_mjollnir_profiling_gator_api.h2
-rw-r--r--drivers/gator/mali/mali_utgard_profiling_gator_api.h2
-rw-r--r--drivers/gator/mali_t6xx.mk9
40 files changed, 551 insertions, 536 deletions
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_pack.c b/drivers/gator/gator_buffer_write.c
index 2c082f283ad..b621ba93ee5 100644
--- a/drivers/gator/gator_pack.c
+++ b/drivers/gator/gator_buffer_write.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
@@ -56,3 +56,25 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, long long x)
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 <linux/slab.h>
#include <asm/io.h>
+#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 <asm/io.h>
/* 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 <linux/slab.h>
@@ -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,52 +288,53 @@ 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",
.pmnc_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;
}
@@ -464,173 +481,6 @@ static bool buffer_commit_ready(int *cpu, int *buftype)
}
/******************************************************************************
- * 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
******************************************************************************/
static void gator_timer_interrupt(void)
@@ -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_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 <linux/math64.h>
#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