aboutsummaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
Diffstat (limited to 'driver')
-rw-r--r--driver/Makefile2
-rw-r--r--driver/gator.h52
-rw-r--r--driver/gator_annotate.c17
-rw-r--r--driver/gator_annotate_kernel.c132
-rw-r--r--driver/gator_backtrace.c36
-rw-r--r--driver/gator_cookies.c105
-rw-r--r--driver/gator_events_armv6.c6
-rw-r--r--driver/gator_events_armv7.c18
-rw-r--r--driver/gator_events_block.c5
-rw-r--r--driver/gator_events_irq.c11
-rw-r--r--driver/gator_events_l2c-310.c18
-rw-r--r--driver/gator_events_mali_400.c1009
-rw-r--r--driver/gator_events_mali_common.c90
-rw-r--r--driver/gator_events_mali_common.h14
-rw-r--r--driver/gator_events_mali_t6xx.c716
-rw-r--r--driver/gator_events_mali_t6xx_hw.c1007
-rw-r--r--driver/gator_events_mali_t6xx_hw_test.c20
-rw-r--r--driver/gator_events_meminfo.c14
-rw-r--r--driver/gator_events_mmaped.c34
-rw-r--r--driver/gator_events_net.c9
-rw-r--r--driver/gator_events_perf_pmu.c77
-rw-r--r--driver/gator_events_sched.c1
-rw-r--r--driver/gator_events_scorpion.c218
-rw-r--r--driver/gator_fs.c58
-rw-r--r--driver/gator_main.c372
-rw-r--r--driver/gator_marshaling.c179
-rw-r--r--driver/gator_pack.c110
-rw-r--r--driver/gator_trace_gpu.c76
-rw-r--r--driver/gator_trace_gpu.h60
-rw-r--r--driver/gator_trace_power.c46
-rw-r--r--driver/gator_trace_sched.c24
31 files changed, 2335 insertions, 2201 deletions
diff --git a/driver/Makefile b/driver/Makefile
index 6cafecf..d22d29d 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -27,7 +27,7 @@ gator-y += gator_events_mali_common.o
EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT)
endif
-# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
+# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
GATOR_TEST ?= 0
EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST)
diff --git a/driver/gator.h b/driver/gator.h
index 5a40e17..9a4617b 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -15,7 +15,7 @@
#include <linux/list.h>
#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
-#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && defined(CONFIG_HW_PERF_EVENTS)
+#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && (!(defined(__arm__) || defined(__aarch64__)) || defined(CONFIG_HW_PERF_EVENTS))
#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT))
#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ)
@@ -33,22 +33,39 @@
#define SCORPIONMP 0x02d
#define KRAITSIM 0x049
#define KRAIT 0x04d
+#define KRAIT_S4_PRO 0x06f
+#define CORTEX_A53 0xd03
+#define CORTEX_A57 0xd07
#define AARCH64 0xd0f
+#define OTHER 0xfff
+
+#define MAXSIZE_CORE_NAME 32
+
+struct gator_cpu {
+ const int cpuid;
+ const char core_name[MAXSIZE_CORE_NAME];
+ const char * const pmnc_name;
+ const int pmnc_counters;
+ const int ccnt;
+};
+
+extern struct gator_cpu gator_cpus[];
/******************************************************************************
* Filesystem
******************************************************************************/
int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops, int perm);
+ char const *name,
+ const struct file_operations *fops, int perm);
-struct dentry *gatorfs_mkdir(struct super_block *sb,
- struct dentry *root, char const *name);
+struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root,
+ char const *name);
int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val);
+ char const *name, unsigned long *val);
int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val);
+ char const *name, unsigned long *val);
void gator_op_create_files(struct super_block *sb, struct dentry *root);
@@ -77,15 +94,16 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root);
* Events
******************************************************************************/
struct gator_interface {
- int (*create_files)(struct super_block *sb, struct dentry *root);
- int (*start)(void);
- void (*stop)(void);
- int (*online)(int** buffer);
- int (*offline)(int** buffer);
- void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
- void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
- int (*read)(int **buffer);
- int (*read64)(long long **buffer);
+ void (*shutdown)(void); // Complementary function to init
+ int (*create_files)(struct super_block *sb, struct dentry *root);
+ int (*start)(void);
+ void (*stop)(void); // Complementary function to start
+ int (*online)(int **buffer);
+ int (*offline)(int **buffer);
+ void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
+ void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
+ int (*read)(int **buffer);
+ int (*read64)(long long **buffer);
struct list_head list;
};
@@ -96,8 +114,8 @@ struct gator_interface {
int gator_events_install(struct gator_interface *interface);
int gator_events_get_key(void);
-extern u32 gator_cpuid(void);
+u32 gator_cpuid(void);
-void gator_backtrace_handler(struct pt_regs * const regs);
+void gator_backtrace_handler(struct pt_regs *const regs);
#endif // GATOR_H_
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index 928e252..42f9951 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -44,8 +44,9 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
return -EINVAL;
}
- // Annotation is not supported in interrupt context
+ // Annotations are not supported in interrupt context
if (in_interrupt()) {
+ printk(KERN_WARNING "gator: Annotations are not supported in interrupt context\n");
return -EINVAL;
}
@@ -58,7 +59,8 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
goto annotate_write_out;
}
- cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
+ // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
+ cpu = 0;
if (current == NULL) {
pid = 0;
@@ -129,18 +131,21 @@ static int annotate_release(struct inode *inode, struct file *file)
uint32_t pid = current->pid;
gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
- gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
- gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
+ gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
+ gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
}
+ // Check and commit; commit is set to occur once buffer is 3/4 full
+ buffer_check(cpu, ANNOTATE_BUF);
+
spin_unlock(&annotate_lock);
return 0;
}
static const struct file_operations annotate_fops = {
- .write = annotate_write,
- .release = annotate_release
+ .write = annotate_write,
+ .release = annotate_release
};
static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index bc68fa8..67d2d6c 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -8,11 +8,13 @@
*/
#define ESCAPE_CODE 0x1c
-#define STRING_ANNOTATION 0x03
+#define STRING_ANNOTATION 0x06
+#define NAME_CHANNEL_ANNOTATION 0x07
+#define NAME_GROUP_ANNOTATION 0x08
#define VISUAL_ANNOTATION 0x04
#define MARKER_ANNOTATION 0x05
-static void kannotate_write(const char* ptr, unsigned int size)
+static void kannotate_write(const char *ptr, unsigned int size)
{
int retval;
int pos = 0;
@@ -27,91 +29,129 @@ static void kannotate_write(const char* ptr, unsigned int size)
}
}
-static void gator_annotate_code(char code)
+void gator_annotate_channel(int channel, const char *str)
{
- int header = ESCAPE_CODE | (code << 8);
- kannotate_write((char*)&header, sizeof(header));
+ int str_size = strlen(str) & 0xffff;
+ long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16) | ((long long)str_size << 48);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
}
-static void gator_annotate_code_str(char code, const char* string)
-{
- int str_size = strlen(string) & 0xffff;
- int header = ESCAPE_CODE | (code << 8) | (str_size << 16);
- kannotate_write((char*)&header, sizeof(header));
- kannotate_write(string, str_size);
-}
+EXPORT_SYMBOL(gator_annotate_channel);
-static void gator_annotate_code_color(char code, int color)
+void gator_annotate(const char *str)
{
- long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32));
- kannotate_write((char*)&header, sizeof(header));
+ gator_annotate_channel(0, str);
}
-static void gator_annotate_code_color_str(char code, int color, const char* string)
+EXPORT_SYMBOL(gator_annotate);
+
+void gator_annotate_channel_color(int channel, int color, const char *str)
{
- int str_size = (strlen(string) + 4) & 0xffff;
- long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32);
- kannotate_write((char*)&header, sizeof(header));
- kannotate_write(string, str_size - 4);
+ int str_size = (strlen(str) + 4) & 0xffff;
+ char header[12];
+ header[0] = ESCAPE_CODE;
+ header[1] = STRING_ANNOTATION;
+ *(u32 *)(&header[2]) = channel;
+ *(u16 *)(&header[6]) = str_size;
+ *(u32 *)(&header[8]) = color;
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size - 4);
}
-// String annotation
-void gator_annotate(const char* string)
+EXPORT_SYMBOL(gator_annotate_channel_color);
+
+void gator_annotate_color(int color, const char *str)
{
- gator_annotate_code_str(STRING_ANNOTATION, string);
+ gator_annotate_channel_color(0, color, str);
}
-EXPORT_SYMBOL(gator_annotate);
-// String annotation with color
-void gator_annotate_color(int color, const char* string)
+EXPORT_SYMBOL(gator_annotate_color);
+
+void gator_annotate_channel_end(int channel)
{
- gator_annotate_code_color_str(STRING_ANNOTATION, color, string);
+ long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16);
+ kannotate_write((char *)&header, sizeof(header));
}
-EXPORT_SYMBOL(gator_annotate_color);
-// Terminate an annotation
+EXPORT_SYMBOL(gator_annotate_channel_end);
+
void gator_annotate_end(void)
{
- gator_annotate_code(STRING_ANNOTATION);
+ gator_annotate_channel_end(0);
}
+
EXPORT_SYMBOL(gator_annotate_end);
-// Image annotation with optional string
-void gator_annotate_visual(const char* data, unsigned int length, const char* string)
+void gator_annotate_name_channel(int channel, int group, const char* str)
+{
+ int str_size = strlen(str) & 0xffff;
+ char header[12];
+ header[0] = ESCAPE_CODE;
+ header[1] = NAME_CHANNEL_ANNOTATION;
+ *(u32 *)(&header[2]) = channel;
+ *(u32 *)(&header[6]) = group;
+ *(u16 *)(&header[10]) = str_size;
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
+}
+
+EXPORT_SYMBOL(gator_annotate_name_channel);
+
+void gator_annotate_name_group(int group, const char* str)
+{
+ int str_size = strlen(str) & 0xffff;
+ long long header = ESCAPE_CODE | (NAME_GROUP_ANNOTATION << 8) | (group << 16) | ((long long)str_size << 48);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
+}
+
+EXPORT_SYMBOL(gator_annotate_name_group);
+
+void gator_annotate_visual(const char *data, unsigned int length, const char *str)
{
- int str_size = strlen(string) & 0xffff;
+ int str_size = strlen(str) & 0xffff;
int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16);
- kannotate_write((char*)&visual_annotation, sizeof(visual_annotation));
- kannotate_write(string, str_size);
- kannotate_write((char*)&length, sizeof(length));
+ kannotate_write((char *)&visual_annotation, sizeof(visual_annotation));
+ kannotate_write(str, str_size);
+ kannotate_write((char *)&length, sizeof(length));
kannotate_write(data, length);
}
+
EXPORT_SYMBOL(gator_annotate_visual);
-// Marker annotation
void gator_annotate_marker(void)
{
- gator_annotate_code(MARKER_ANNOTATION);
+ int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8);
+ kannotate_write((char *)&header, sizeof(header));
}
+
EXPORT_SYMBOL(gator_annotate_marker);
-// Marker annotation with a string
-void gator_annotate_marker_str(const char* string)
+void gator_annotate_marker_str(const char *str)
{
- gator_annotate_code_str(MARKER_ANNOTATION, string);
+ int str_size = strlen(str) & 0xffff;
+ int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
}
+
EXPORT_SYMBOL(gator_annotate_marker_str);
-// Marker annotation with a color
void gator_annotate_marker_color(int color)
{
- gator_annotate_code_color(MARKER_ANNOTATION, color);
+ long long header = (ESCAPE_CODE | (MARKER_ANNOTATION << 8) | 0x00040000 | ((long long)color << 32));
+ kannotate_write((char *)&header, sizeof(header));
}
+
EXPORT_SYMBOL(gator_annotate_marker_color);
-// Marker annotation with a string and color
-void gator_annotate_marker_color_str(int color, const char* string)
+void gator_annotate_marker_color_str(int color, const char *str)
{
- gator_annotate_code_color_str(MARKER_ANNOTATION, color, string);
+ int str_size = (strlen(str) + 4) & 0xffff;
+ long long header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16) | ((long long)color << 32);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size - 4);
}
+
EXPORT_SYMBOL(gator_annotate_marker_color_str);
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 2173d8a..e6125b3 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -11,20 +11,28 @@
* EABI backtrace stores {fp,lr} on the stack.
*/
struct frame_tail_eabi {
- unsigned long fp; // points to prev_lr
+ unsigned long fp; // points to prev_lr
unsigned long lr;
};
-static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth)
+static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
{
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
struct frame_tail_eabi *tail;
struct frame_tail_eabi *next;
struct frame_tail_eabi *ptrtail;
struct frame_tail_eabi buftail;
+#if defined(__arm__)
unsigned long fp = regs->ARM_fp;
unsigned long sp = regs->ARM_sp;
unsigned long lr = regs->ARM_lr;
+ const int frame_offset = 4;
+#else
+ unsigned long fp = regs->regs[29];
+ unsigned long sp = regs->sp;
+ unsigned long lr = regs->regs[30];
+ const int frame_offset = 0;
+#endif
int is_user_mode = user_mode(regs);
if (!is_user_mode) {
@@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
return;
}
- tail = (struct frame_tail_eabi *)(fp - 4);
+ tail = (struct frame_tail_eabi *)(fp - frame_offset);
- while (depth-- && tail && !((unsigned long) tail & 3)) {
+ while (depth-- && tail && !((unsigned long)tail & 3)) {
/* Also check accessibility of one struct frame_tail beyond */
if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi)))
return;
@@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
gator_add_trace(cpu, lr);
/* frame pointers should progress back up the stack, towards higher addresses */
- next = (struct frame_tail_eabi *)(lr - 4);
+ next = (struct frame_tail_eabi *)(lr - frame_offset);
if (tail >= next || lr == 0) {
fp = ptrtail[0].fp;
- next = (struct frame_tail_eabi *)(fp - 4);
+ next = (struct frame_tail_eabi *)(fp - frame_offset);
/* check tail is valid */
if (tail >= next || fp == 0) {
return;
@@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
#endif
}
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
static int report_trace(struct stackframe *frame, void *d)
{
struct module *mod;
@@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d)
if (*depth) {
mod = __module_address(addr);
if (mod) {
- cookie = get_cookie(cpu, current, NULL, mod, true);
+ cookie = get_cookie(cpu, current, mod->name, false);
addr = addr - (unsigned long)mod->module_core;
}
marshal_backtrace(addr & ~1, cookie);
@@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d)
// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile
// #define GATOR_KERNEL_STACK_UNWINDING
-static void kernel_backtrace(int cpu, struct pt_regs * const regs)
+static void kernel_backtrace(int cpu, struct pt_regs *const regs)
{
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
#ifdef GATOR_KERNEL_STACK_UNWINDING
int depth = gator_backtrace_depth;
#else
@@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs)
struct stackframe frame;
if (depth == 0)
depth = 1;
+#if defined(__arm__)
frame.fp = regs->ARM_fp;
frame.sp = regs->ARM_sp;
frame.lr = regs->ARM_lr;
frame.pc = regs->ARM_pc;
+#else
+ frame.fp = regs->regs[29];
+ frame.sp = regs->sp;
+ frame.pc = regs->pc;
+#endif
walk_stackframe(&frame, report_trace, &depth);
#else
marshal_backtrace(PC_REG & ~1, NO_COOKIE);
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index 21dc4eb..bb401bb 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -7,7 +7,7 @@
*
*/
-#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
+#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
#define TRANSLATE_SIZE 256
#define MAX_COLLISIONS 2
@@ -20,28 +20,29 @@ 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(void **, translate_buffer);
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt);
+static inline 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 struct timer_list app_process_wake_up_timer;
static void app_process_wake_up_handler(unsigned long unused_data);
-static uint32_t cookiemap_code(uint64_t value64) {
+static uint32_t cookiemap_code(uint64_t value64)
+{
uint32_t value = (uint32_t)((value64 >> 32) + value64);
uint32_t cookiecode = (value >> 24) & 0xff;
cookiecode = cookiecode * 31 + ((value >> 16) & 0xff);
cookiecode = cookiecode * 31 + ((value >> 8) & 0xff);
cookiecode = cookiecode * 31 + ((value >> 0) & 0xff);
- cookiecode &= (COOKIEMAP_ENTRIES-1);
+ cookiecode &= (COOKIEMAP_ENTRIES - 1);
return cookiecode * MAX_COLLISIONS;
}
-static uint32_t gator_chksum_crc32(char *data)
+static uint32_t gator_chksum_crc32(const char *data)
{
register unsigned long crc;
- unsigned char *block = data;
+ const unsigned char *block = data;
int i, length = strlen(data);
crc = 0xFFFFFFFF;
@@ -57,7 +58,8 @@ static uint32_t gator_chksum_crc32(char *data)
* Pre: [0][1][v][3]..[n-1]
* Post: [v][0][1][3]..[n-1]
*/
-static uint32_t cookiemap_exists(uint64_t key) {
+static uint32_t cookiemap_exists(uint64_t key)
+{
unsigned long x, flags, retval = 0;
int cpu = smp_processor_id();
uint32_t cookiecode = cookiemap_code(key);
@@ -70,8 +72,8 @@ static uint32_t cookiemap_exists(uint64_t key) {
if (keys[x] == key) {
uint32_t value = values[x];
for (; x > 0; x--) {
- keys[x] = keys[x-1];
- values[x] = values[x-1];
+ keys[x] = keys[x - 1];
+ values[x] = values[x - 1];
}
keys[0] = key;
values[0] = value;
@@ -89,30 +91,31 @@ static uint32_t cookiemap_exists(uint64_t key) {
* Pre: [0][1][2][3]..[n-1]
* Post: [v][0][1][2]..[n-2]
*/
-static void cookiemap_add(uint64_t key, uint32_t value) {
+static void cookiemap_add(uint64_t key, uint32_t value)
+{
int cpu = smp_processor_id();
int cookiecode = cookiemap_code(key);
uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]);
uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]);
int x;
- for (x = MAX_COLLISIONS-1; x > 0; x--) {
- keys[x] = keys[x-1];
- values[x] = values[x-1];
+ for (x = MAX_COLLISIONS - 1; x > 0; x--) {
+ keys[x] = keys[x - 1];
+ values[x] = values[x - 1];
}
keys[0] = key;
values[0] = value;
}
-static void translate_buffer_write_ptr(int cpu, void * x)
+static void translate_buffer_write_ptr(int cpu, void *x)
{
per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
}
-static void * translate_buffer_read_ptr(int cpu)
+static void *translate_buffer_read_ptr(int cpu)
{
- void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
+ void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
return value;
}
@@ -120,9 +123,9 @@ static void * translate_buffer_read_ptr(int cpu)
static void wq_cookie_handler(struct work_struct *unused)
{
struct task_struct *task;
- struct vm_area_struct *vma;
+ char *text;
int cpu = smp_processor_id();
- unsigned int cookie, commit;
+ unsigned int commit;
mutex_lock(&start_mutex);
@@ -130,8 +133,8 @@ static void wq_cookie_handler(struct work_struct *unused)
commit = per_cpu(translate_buffer_write, cpu);
while (per_cpu(translate_buffer_read, cpu) != commit) {
task = (struct task_struct *)translate_buffer_read_ptr(cpu);
- vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu);
- cookie = get_cookie(cpu, task, vma, NULL, false);
+ text = (char *)translate_buffer_read_ptr(cpu);
+ get_cookie(cpu, task, text, true);
}
}
@@ -145,7 +148,7 @@ static void app_process_wake_up_handler(unsigned long unused_data)
}
// Retrieve full name from proc/pid/cmdline for java processes on Android
-static int translate_app_process(char** text, int cpu, struct task_struct * task, struct vm_area_struct *vma, bool in_interrupt)
+static int translate_app_process(const char **text, int cpu, struct task_struct *task, bool from_wq)
{
void *maddr;
unsigned int len;
@@ -154,12 +157,12 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
struct page *page = NULL;
struct vm_area_struct *page_vma;
int bytes, offset, retval = 0, ptr;
- char * buf = per_cpu(translate_text, cpu);
+ char *buf = per_cpu(translate_text, cpu);
// Push work into a work queue if in atomic context as the kernel functions below might sleep
// Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems
// inconsistent during a context switch between android/linux versions
- if (in_interrupt) {
+ if (!from_wq) {
// Check if already in buffer
ptr = per_cpu(translate_buffer_read, cpu);
while (ptr != per_cpu(translate_buffer_write, cpu)) {
@@ -169,7 +172,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
}
translate_buffer_write_ptr(cpu, (void *)task);
- translate_buffer_write_ptr(cpu, (void *)vma);
+ translate_buffer_write_ptr(cpu, (void *)*text);
mod_timer(&app_process_wake_up_timer, jiffies + 1);
goto out;
@@ -192,7 +195,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
goto outsem;
maddr = kmap(page);
- offset = addr & (PAGE_SIZE-1);
+ offset = addr & (PAGE_SIZE - 1);
bytes = len;
if (bytes > PAGE_SIZE - offset)
bytes = PAGE_SIZE - offset;
@@ -222,29 +225,10 @@ out:
return retval;
}
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt)
+static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
{
unsigned long flags, cookie;
- struct path *path;
uint64_t key;
- char *text;
-
- if (mod) {
- text = mod->name;
- } else {
- if (vma && vma->vm_file) {
- path = &vma->vm_file->f_path;
- } else if (task && task->mm && task->mm->exe_file) {
- path = &task->mm->exe_file->f_path;
- } else {
- return INVALID_COOKIE;
- }
- if (!path || !path->dentry) {
- return INVALID_COOKIE;
- }
-
- text = (char*)path->dentry->d_name.name;
- }
key = gator_chksum_crc32(text);
key = (key << 32) | (uint32_t)task->tgid;
@@ -254,8 +238,8 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
return cookie;
}
- if (strcmp(text, "app_process") == 0 && !mod) {
- if (!translate_app_process(&text, cpu, task, vma, in_interrupt))
+ if (strcmp(text, "app_process") == 0) {
+ if (!translate_app_process(&text, cpu, task, from_wq))
return INVALID_COOKIE;
}
@@ -276,16 +260,19 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
static int get_exec_cookie(int cpu, struct task_struct *task)
{
- unsigned long cookie = NO_COOKIE;
struct mm_struct *mm = task->mm;
+ const char *text;
// kernel threads have no address space
if (!mm)
- return cookie;
+ return NO_COOKIE;
- cookie = get_cookie(cpu, task, NULL, NULL, true);
+ if (task && task->mm && task->mm->exe_file) {
+ text = task->mm->exe_file->f_path.dentry->d_name.name;
+ return get_cookie(cpu, task, text, false);
+ }
- return cookie;
+ return INVALID_COOKIE;
}
static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset)
@@ -293,6 +280,7 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
unsigned long cookie = NO_COOKIE;
struct mm_struct *mm = task->mm;
struct vm_area_struct *vma;
+ const char *text;
if (!mm)
return cookie;
@@ -302,7 +290,8 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
continue;
if (vma->vm_file) {
- cookie = get_cookie(cpu, task, vma, NULL, true);
+ text = vma->vm_file->f_path.dentry->d_name.name;
+ cookie = get_cookie(cpu, task, text, false);
*offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
} else {
/* must be an anonymous map */
@@ -323,14 +312,14 @@ static int cookies_initialize(void)
uint32_t crc, poly;
int i, j, cpu, size, err = 0;
- int translate_buffer_size = 512; // must be a power of 2
+ int translate_buffer_size = 512; // must be a power of 2
translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
for_each_present_cpu(cpu) {
per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t);
- per_cpu(cookie_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(cookie_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(cookie_keys, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -338,14 +327,14 @@ static int cookies_initialize(void)
memset(per_cpu(cookie_keys, cpu), 0, size);
size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t);
- per_cpu(cookie_values, cpu) = (uint32_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(cookie_values, cpu) = (uint32_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(cookie_values, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
}
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) = (void **)kmalloc(translate_buffer_size, GFP_KERNEL);
if (!per_cpu(translate_buffer, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -363,7 +352,7 @@ static int cookies_initialize(void)
// build CRC32 table
poly = 0x04c11db7;
- gator_crc32_table = (uint32_t*)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
+ gator_crc32_table = (uint32_t *)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
for (i = 0; i < 256; i++) {
crc = i;
for (j = 8; j > 0; j--) {
diff --git a/driver/gator_events_armv6.c b/driver/gator_events_armv6.c
index 5f989ba..ee36dd0 100644
--- a/driver/gator_events_armv6.c
+++ b/driver/gator_events_armv6.c
@@ -93,7 +93,7 @@ int gator_events_armv6_create_files(struct super_block *sb, struct dentry *root)
return 0;
}
-static int gator_events_armv6_online(int** buffer)
+static int gator_events_armv6_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
u32 pmnc;
@@ -104,7 +104,7 @@ static int gator_events_armv6_online(int** buffer)
/* initialize PMNC, reset overflow, D bit, C bit and P bit. */
armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
- PMCR_C | PMCR_P);
+ PMCR_C | PMCR_P);
/* configure control register */
for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
@@ -141,7 +141,7 @@ static int gator_events_armv6_online(int** buffer)
return len;
}
-static int gator_events_armv6_offline(int** buffer)
+static int gator_events_armv6_offline(int **buffer)
{
unsigned int cnt;
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 590421d..212b17b 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -22,7 +22,7 @@
#define PMNC_E (1 << 0) /* Enable all counters */
#define PMNC_P (1 << 1) /* Reset all counters */
#define PMNC_C (1 << 2) /* Cycle counter reset */
-#define PMNC_MASK 0x3f /* Mask for writable bits */
+#define PMNC_MASK 0x3f /* Mask for writable bits */
// ccnt reg
#define CCNT_REG (1 << 31)
@@ -63,7 +63,7 @@ inline u32 armv7_ccnt_read(u32 reset_value)
local_irq_save(flags);
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read
- asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval));// new value
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval)); // new value
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
local_irq_restore(flags);
@@ -82,7 +82,7 @@ inline u32 armv7_cntn_read(unsigned int cnt, u32 reset_value)
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select
asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read
- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval));// new value
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval)); // new value
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
local_irq_restore(flags);
@@ -143,7 +143,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
if (i == 0) {
snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i-1);
+ snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1);
}
dir = gatorfs_mkdir(sb, root, buf);
if (!dir) {
@@ -159,7 +159,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
return 0;
}
-static int gator_events_armv7_online(int** buffer)
+static int gator_events_armv7_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
@@ -214,11 +214,11 @@ static int gator_events_armv7_online(int** buffer)
return len;
}
-static int gator_events_armv7_offline(int** buffer)
+static int gator_events_armv7_offline(int **buffer)
{
- // disbale all counters, including PMCCNTR; overflow IRQs will not be signaled
+ // disable all counters, including PMCCNTR; overflow IRQs will not be signaled
armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
-
+
return 0;
}
@@ -298,7 +298,7 @@ int gator_events_armv7_init(void)
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = CCNT; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index b18c3ca..f512b13 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -119,7 +119,7 @@ static int gator_events_block_read(int **buffer)
if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) {
atomic_sub(value, &blockCnt[BLOCK_RQ_WR]);
blockGet[len++] = block_rq_wr_key;
- blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
+ blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
blockGet[len++] = block_rq_wr_key;
blockGet[len++] = value;
data += value;
@@ -127,7 +127,7 @@ static int gator_events_block_read(int **buffer)
if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) {
atomic_sub(value, &blockCnt[BLOCK_RQ_RD]);
blockGet[len++] = block_rq_rd_key;
- blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
+ blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
blockGet[len++] = block_rq_rd_key;
blockGet[len++] = value;
data += value;
@@ -156,4 +156,5 @@ int gator_events_block_init(void)
return gator_events_install(&gator_events_block_interface);
}
+
gator_events_init(gator_events_block_init);
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 435bc86..1221372 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -21,8 +21,8 @@ static ulong softirq_key;
static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt);
static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet);
-GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq,
- struct irqaction *action, int ret))
+GATOR_DEFINE_PROBE(irq_handler_exit,
+ TP_PROTO(int irq, struct irqaction *action, int ret))
{
unsigned long flags;
@@ -71,10 +71,10 @@ static int gator_events_irq_create_files(struct super_block *sb, struct dentry *
return 0;
}
-static int gator_events_irq_online(int** buffer)
+static int gator_events_irq_online(int **buffer)
{
int len = 0, cpu = smp_processor_id();
- unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
+ unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
// synchronization with the irq_exit functions is not necessary as the values are being reset
if (hardirq_enabled) {
@@ -136,7 +136,7 @@ static void gator_events_irq_stop(void)
static int gator_events_irq_read(int **buffer)
{
- unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
+ unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
int len, value;
int cpu = smp_processor_id();
@@ -185,4 +185,5 @@ int gator_events_irq_init(void)
return gator_events_install(&gator_events_irq_interface);
}
+
gator_events_init(gator_events_irq_init);
diff --git a/driver/gator_events_l2c-310.c b/driver/gator_events_l2c-310.c
index bd1c48a..197af04 100644
--- a/driver/gator_events_l2c-310.c
+++ b/driver/gator_events_l2c-310.c
@@ -26,8 +26,6 @@ static int l2c310_buffer[L2C310_COUNTERS_NUM * 2];
static void __iomem *l2c310_base;
-
-
static void gator_events_l2c310_reset_counters(void)
{
u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL);
@@ -37,9 +35,8 @@ static void gator_events_l2c310_reset_counters(void)
writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL);
}
-
static int gator_events_l2c310_create_files(struct super_block *sb,
- struct dentry *root)
+ struct dentry *root)
{
int i;
@@ -52,11 +49,11 @@ static int gator_events_l2c310_create_files(struct super_block *sb,
if (WARN_ON(!dir))
return -1;
gatorfs_create_ulong(sb, dir, "enabled",
- &l2c310_counters[i].enabled);
+ &l2c310_counters[i].enabled);
gatorfs_create_ulong(sb, dir, "event",
- &l2c310_counters[i].event);
+ &l2c310_counters[i].event);
gatorfs_create_ro_ulong(sb, dir, "key",
- &l2c310_counters[i].key);
+ &l2c310_counters[i].key);
}
return 0;
@@ -73,7 +70,7 @@ static int gator_events_l2c310_start(void)
/* Counter event sources */
for (i = 0; i < L2C310_COUNTERS_NUM; i++)
writel((l2c310_counters[i].event & 0xf) << 2,
- l2c310_base + l2x0_event_cntx_cfg[i]);
+ l2c310_base + l2x0_event_cntx_cfg[i]);
gator_events_l2c310_reset_counters();
@@ -105,10 +102,10 @@ static int gator_events_l2c310_read(int **buffer)
if (l2c310_counters[i].enabled) {
l2c310_buffer[len++] = l2c310_counters[i].key;
l2c310_buffer[len++] = readl(l2c310_base +
- l2x0_event_cntx_val[i]);
+ l2x0_event_cntx_val[i]);
}
}
-
+
/* l2c310 counters are saturating, not wrapping in case of overflow */
gator_events_l2c310_reset_counters();
@@ -176,4 +173,5 @@ int gator_events_l2c310_init(void)
return gator_events_install(&gator_events_l2c310_interface);
}
+
gator_events_init(gator_events_l2c310_init);
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c
index a44cd8e..34a73c8 100644
--- a/driver/gator_events_mali_400.c
+++ b/driver/gator_events_mali_400.c
@@ -17,14 +17,6 @@
#include "gator_events_mali_common.h"
#include "gator_events_mali_400.h"
-#if !defined(GATOR_MALI_INTERFACE_STYLE)
-/*
- * At the moment, we only have users with the old style interface, so
- * make our life easier by making it the default...
- */
-#define GATOR_MALI_INTERFACE_STYLE (2)
-#endif
-
/*
* There are (currently) three different variants of the comms between gator and Mali:
* 1 (deprecated): No software counter support
@@ -60,81 +52,81 @@
#define NUM_FP_UNITS (4)
enum counters {
- /* Timeline activity */
- ACTIVITY_VP = 0,
- ACTIVITY_FP0,
- ACTIVITY_FP1,
- ACTIVITY_FP2,
- ACTIVITY_FP3,
-
- /* L2 cache counters */
- COUNTER_L2_C0,
- COUNTER_L2_C1,
-
- /* Vertex processor counters */
- COUNTER_VP_C0,
- COUNTER_VP_C1,
-
- /* Fragment processor counters */
- COUNTER_FP0_C0,
- COUNTER_FP0_C1,
- COUNTER_FP1_C0,
- COUNTER_FP1_C1,
- COUNTER_FP2_C0,
- COUNTER_FP2_C1,
- COUNTER_FP3_C0,
- COUNTER_FP3_C1,
-
- /* EGL Software Counters */
- COUNTER_EGL_BLIT_TIME,
-
- /* GLES Software Counters */
- COUNTER_GLES_DRAW_ELEMENTS_CALLS,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_ARRAYS_CALLS,
- COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_POINTS,
- COUNTER_GLES_DRAW_LINES,
- COUNTER_GLES_DRAW_LINE_LOOP,
- COUNTER_GLES_DRAW_LINE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLES,
- COUNTER_GLES_DRAW_TRIANGLE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLE_FAN,
- COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
- COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
- COUNTER_GLES_UPLOAD_TEXTURE_TIME,
- COUNTER_GLES_UPLOAD_VBO_TIME,
- COUNTER_GLES_NUM_FLUSHES,
- COUNTER_GLES_NUM_VSHADERS_GENERATED,
- COUNTER_GLES_NUM_FSHADERS_GENERATED,
- COUNTER_GLES_VSHADER_GEN_TIME,
- COUNTER_GLES_FSHADER_GEN_TIME,
- COUNTER_GLES_INPUT_TRIANGLES,
- COUNTER_GLES_VXCACHE_HIT,
- COUNTER_GLES_VXCACHE_MISS,
- COUNTER_GLES_VXCACHE_COLLISION,
- COUNTER_GLES_CULLED_TRIANGLES,
- COUNTER_GLES_CULLED_LINES,
- COUNTER_GLES_BACKFACE_TRIANGLES,
- COUNTER_GLES_GBCLIP_TRIANGLES,
- COUNTER_GLES_GBCLIP_LINES,
- COUNTER_GLES_TRIANGLES_DRAWN,
- COUNTER_GLES_DRAWCALL_TIME,
- COUNTER_GLES_TRIANGLES_COUNT,
- COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
- COUNTER_GLES_STRIP_TRIANGLES_COUNT,
- COUNTER_GLES_FAN_TRIANGLES_COUNT,
- COUNTER_GLES_LINES_COUNT,
- COUNTER_GLES_INDEPENDENT_LINES_COUNT,
- COUNTER_GLES_STRIP_LINES_COUNT,
- COUNTER_GLES_LOOP_LINES_COUNT,
-
- COUNTER_FILMSTRIP,
- COUNTER_FREQUENCY,
- COUNTER_VOLTAGE,
-
- NUMBER_OF_EVENTS
+ /* Timeline activity */
+ ACTIVITY_VP = 0,
+ ACTIVITY_FP0,
+ ACTIVITY_FP1,
+ ACTIVITY_FP2,
+ ACTIVITY_FP3,
+
+ /* L2 cache counters */
+ COUNTER_L2_C0,
+ COUNTER_L2_C1,
+
+ /* Vertex processor counters */
+ COUNTER_VP_C0,
+ COUNTER_VP_C1,
+
+ /* Fragment processor counters */
+ COUNTER_FP0_C0,
+ COUNTER_FP0_C1,
+ COUNTER_FP1_C0,
+ COUNTER_FP1_C1,
+ COUNTER_FP2_C0,
+ COUNTER_FP2_C1,
+ COUNTER_FP3_C0,
+ COUNTER_FP3_C1,
+
+ /* EGL Software Counters */
+ COUNTER_EGL_BLIT_TIME,
+
+ /* GLES Software Counters */
+ COUNTER_GLES_DRAW_ELEMENTS_CALLS,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_ARRAYS_CALLS,
+ COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_POINTS,
+ COUNTER_GLES_DRAW_LINES,
+ COUNTER_GLES_DRAW_LINE_LOOP,
+ COUNTER_GLES_DRAW_LINE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLES,
+ COUNTER_GLES_DRAW_TRIANGLE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLE_FAN,
+ COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
+ COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
+ COUNTER_GLES_UPLOAD_TEXTURE_TIME,
+ COUNTER_GLES_UPLOAD_VBO_TIME,
+ COUNTER_GLES_NUM_FLUSHES,
+ COUNTER_GLES_NUM_VSHADERS_GENERATED,
+ COUNTER_GLES_NUM_FSHADERS_GENERATED,
+ COUNTER_GLES_VSHADER_GEN_TIME,
+ COUNTER_GLES_FSHADER_GEN_TIME,
+ COUNTER_GLES_INPUT_TRIANGLES,
+ COUNTER_GLES_VXCACHE_HIT,
+ COUNTER_GLES_VXCACHE_MISS,
+ COUNTER_GLES_VXCACHE_COLLISION,
+ COUNTER_GLES_CULLED_TRIANGLES,
+ COUNTER_GLES_CULLED_LINES,
+ COUNTER_GLES_BACKFACE_TRIANGLES,
+ COUNTER_GLES_GBCLIP_TRIANGLES,
+ COUNTER_GLES_GBCLIP_LINES,
+ COUNTER_GLES_TRIANGLES_DRAWN,
+ COUNTER_GLES_DRAWCALL_TIME,
+ COUNTER_GLES_TRIANGLES_COUNT,
+ COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
+ COUNTER_GLES_STRIP_TRIANGLES_COUNT,
+ COUNTER_GLES_FAN_TRIANGLES_COUNT,
+ COUNTER_GLES_LINES_COUNT,
+ COUNTER_GLES_INDEPENDENT_LINES_COUNT,
+ COUNTER_GLES_STRIP_LINES_COUNT,
+ COUNTER_GLES_LOOP_LINES_COUNT,
+
+ COUNTER_FILMSTRIP,
+ COUNTER_FREQUENCY,
+ COUNTER_VOLTAGE,
+
+ NUMBER_OF_EVENTS
};
#define FIRST_ACTIVITY_EVENT ACTIVITY_VP
@@ -161,7 +153,7 @@ static unsigned long counter_key[NUMBER_OF_EVENTS];
/* The data we have recorded */
static u32 counter_data[NUMBER_OF_EVENTS];
/* The address to sample (or 0 if samples are sent to us) */
-static u32* counter_address[NUMBER_OF_EVENTS];
+static u32 *counter_address[NUMBER_OF_EVENTS];
/* An array used to return the data we recorded
* as key,value pairs hence the *2
@@ -177,13 +169,12 @@ static int trace_registered;
*/
static u32 get_difference(u32 start, u32 end)
{
- if (start - end >= 0)
- {
- return start - end;
- }
+ if (start - end >= 0) {
+ return start - end;
+ }
- // Mali counters are unsigned 32 bit values that wrap.
- return (4294967295u - end) + start;
+ // Mali counters are unsigned 32 bit values that wrap.
+ return (4294967295u - end) + start;
}
/**
@@ -191,8 +182,8 @@ static u32 get_difference(u32 start, u32 end)
*/
static inline int is_activity_counter(unsigned int event_id)
{
- return (event_id >= FIRST_ACTIVITY_EVENT &&
- event_id <= LAST_ACTIVITY_EVENT);
+ return (event_id >= FIRST_ACTIVITY_EVENT &&
+ event_id <= LAST_ACTIVITY_EVENT);
}
/**
@@ -200,7 +191,7 @@ static inline int is_activity_counter(unsigned int event_id)
*/
static inline int is_hw_counter(unsigned int event_id)
{
- return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
+ return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
}
#if GATOR_MALI_INTERFACE_STYLE == 2
@@ -209,7 +200,7 @@ static inline int is_hw_counter(unsigned int event_id)
*/
static inline int is_sw_counter(unsigned int event_id)
{
- return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
+ return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
}
#endif
@@ -217,209 +208,204 @@ static inline int is_sw_counter(unsigned int event_id)
/*
* The Mali DDK uses s64 types to contain software counter values, but gator
* can only use a maximum of 32 bits. This function scales a software counter
- * to an appopriate range.
+ * to an appropriate range.
*/
static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
{
- u32 scaled_value;
-
- switch (event_id) {
- case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
- case COUNTER_GLES_UPLOAD_VBO_TIME:
- scaled_value = (u32)div_s64(value, 1000000);
- break;
- default:
- scaled_value = (u32)value;
- break;
- }
-
- return scaled_value;
+ u32 scaled_value;
+
+ switch (event_id) {
+ case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
+ case COUNTER_GLES_UPLOAD_VBO_TIME:
+ scaled_value = (u32)div_s64(value, 1000000);
+ break;
+ default:
+ scaled_value = (u32)value;
+ break;
+ }
+
+ return scaled_value;
}
#endif
/* Probe for continuously sampled counter */
-#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
-GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr))
+#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
+GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr))
{
- /* Turning on too many pr_debug statements in frequently called functions
- * can cause stability and/or performance problems
- */
- //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
- if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
- counter_address[event_id] = addr;
- }
+ /* Turning on too many pr_debug statements in frequently called functions
+ * can cause stability and/or performance problems
+ */
+ //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
+ if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
+ counter_address[event_id] = addr;
+ }
}
#endif
/* Probe for hardware counter events */
GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
{
- /* Turning on too many pr_debug statements in frequently called functions
- * can cause stability and/or performance problems
- */
- //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
- if (is_hw_counter(event_id)) {
- counter_data[event_id] = value;
- }
+ /* Turning on too many pr_debug statements in frequently called functions
+ * can cause stability and/or performance problems
+ */
+ //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
+ if (is_hw_counter(event_id)) {
+ counter_data[event_id] = value;
+ }
}
#if GATOR_MALI_INTERFACE_STYLE == 2
GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
{
- if (is_sw_counter(event_id)) {
- counter_data[event_id] = scale_sw_counter_value(event_id, value);
- }
+ if (is_sw_counter(event_id)) {
+ counter_data[event_id] = scale_sw_counter_value(event_id, value);
+ }
}
#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
-
#if GATOR_MALI_INTERFACE_STYLE == 3
-GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters))
+GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
{
- u32 i;
-
- /* Copy over the values for those counters which are enabled. */
- for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
- {
- if(counter_enabled[i])
- {
- counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
- }
- }
+ u32 i;
+
+ /* Copy over the values for those counters which are enabled. */
+ for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
+ }
+ }
}
#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */
-static int create_files(struct super_block *sb, struct dentry *root) {
- struct dentry *dir;
- int event;
- int n_fp = NUM_FP_UNITS;
-
- const char* mali_name = gator_mali_get_mali_name();
-
- /*
- * Create the filesystem entries for vertex processor, fragement processor
- * and L2 cache timeline and hardware counters. Software counters get
- * special handling after this block.
- */
- for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++)
- {
- char buf[40];
-
- /*
- * We can skip this event if it's for a non-existent fragment
- * processor.
- */
- if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) ||
- (((event - COUNTER_FP0_C0)/2 >= n_fp)))
- {
- continue;
- }
-
- /* Otherwise, set up the filesystem entry for this event. */
- switch (event) {
- case ACTIVITY_VP:
- snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
- break;
- case ACTIVITY_FP0:
- case ACTIVITY_FP1:
- case ACTIVITY_FP2:
- case ACTIVITY_FP3:
- snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
- mali_name, event - ACTIVITY_FP0);
- break;
- case COUNTER_L2_C0:
- case COUNTER_L2_C1:
- snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d",
- mali_name, event - COUNTER_L2_C0);
- break;
- case COUNTER_VP_C0:
- case COUNTER_VP_C1:
- snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d",
- mali_name, event - COUNTER_VP_C0);
- break;
- case COUNTER_FP0_C0:
- case COUNTER_FP0_C1:
- case COUNTER_FP1_C0:
- case COUNTER_FP1_C1:
- case COUNTER_FP2_C0:
- case COUNTER_FP2_C1:
- case COUNTER_FP3_C0:
- case COUNTER_FP3_C1:
- snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", mali_name,
- (event - COUNTER_FP0_C0) / 2, (event - COUNTER_FP0_C0) % 2);
- break;
- default:
- printk("gator: trying to create file for non-existent counter (%d)\n", event);
- continue;
- }
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
-
- /* Only create an event node for counters that can change what they count */
- if (event >= COUNTER_L2_C0) {
- gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
- }
-
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- /* Now set up the software counter entries */
- for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++)
- {
- char buf[40];
-
- snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- /* Now set up the special counter entries */
- for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++)
- {
- char buf[40];
-
- switch(event) {
- case COUNTER_FILMSTRIP:
- snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
- break;
-
- case COUNTER_FREQUENCY:
- snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name);
- break;
-
- case COUNTER_VOLTAGE:
- snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name);
- break;
-
- default:
- break;
- }
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- return 0;
+static int create_files(struct super_block *sb, struct dentry *root)
+{
+ struct dentry *dir;
+ int event;
+ int n_fp = NUM_FP_UNITS;
+
+ const char *mali_name = gator_mali_get_mali_name();
+
+ /*
+ * Create the filesystem entries for vertex processor, fragment processor
+ * and L2 cache timeline and hardware counters. Software counters get
+ * special handling after this block.
+ */
+ for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) {
+ char buf[40];
+
+ /*
+ * We can skip this event if it's for a non-existent fragment
+ * processor.
+ */
+ if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0))
+ || (((event - COUNTER_FP0_C0) / 2 >= n_fp))) {
+ continue;
+ }
+
+ /* Otherwise, set up the filesystem entry for this event. */
+ switch (event) {
+ case ACTIVITY_VP:
+ snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
+ break;
+ case ACTIVITY_FP0:
+ case ACTIVITY_FP1:
+ case ACTIVITY_FP2:
+ case ACTIVITY_FP3:
+ snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
+ mali_name, event - ACTIVITY_FP0);
+ break;
+ case COUNTER_L2_C0:
+ case COUNTER_L2_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d",
+ mali_name, event - COUNTER_L2_C0);
+ break;
+ case COUNTER_VP_C0:
+ case COUNTER_VP_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d",
+ mali_name, event - COUNTER_VP_C0);
+ break;
+ case COUNTER_FP0_C0:
+ case COUNTER_FP0_C1:
+ case COUNTER_FP1_C0:
+ case COUNTER_FP1_C1:
+ case COUNTER_FP2_C0:
+ case COUNTER_FP2_C1:
+ case COUNTER_FP3_C0:
+ case COUNTER_FP3_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d",
+ mali_name, (event - COUNTER_FP0_C0) / 2,
+ (event - COUNTER_FP0_C0) % 2);
+ break;
+ default:
+ printk("gator: trying to create file for non-existent counter (%d)\n", event);
+ continue;
+ }
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+
+ /* Only create an event node for counters that can change what they count */
+ if (event >= COUNTER_L2_C0) {
+ gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
+ }
+
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ /* Now set up the software counter entries */
+ for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) {
+ char buf[40];
+
+ snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ /* Now set up the special counter entries */
+ for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) {
+ char buf[40];
+
+ switch (event) {
+ case COUNTER_FILMSTRIP:
+ snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
+ break;
+
+ case COUNTER_FREQUENCY:
+ snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name);
+ break;
+
+ case COUNTER_VOLTAGE:
+ snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name);
+ break;
+
+ default:
+ break;
+ }
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ return 0;
}
/*
@@ -434,312 +420,311 @@ static mali_profiling_get_counters_type *mali_get_counters = NULL;
*/
static int is_any_sw_counter_enabled(void)
{
- unsigned int i;
+ unsigned int i;
- for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
- {
- if (counter_enabled[i])
- {
- return 1; /* At least one counter is enabled */
- }
- }
+ for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ return 1; /* At least one counter is enabled */
+ }
+ }
- return 0; /* No s/w counters enabled */
+ return 0; /* No s/w counters enabled */
}
-static void mali_counter_initialize(void)
+static void mali_counter_initialize(void)
{
- /* If a Mali driver is present and exporting the appropriate symbol
- * then we can request the HW counters (of which there are only 2)
- * be configured to count the desired events
- */
- mali_profiling_set_event_type *mali_set_hw_event;
- mali_osk_fb_control_set_type *mali_set_fb_event;
- mali_profiling_control_type *mali_control;
-
- mali_set_hw_event = symbol_get(_mali_profiling_set_event);
-
- if (mali_set_hw_event) {
- int i;
-
- pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event);
-
- for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
- if (counter_enabled[i]) {
- mali_set_hw_event(i, counter_event[i]);
- } else {
- mali_set_hw_event(i, 0xFFFFFFFF);
- }
- }
-
- symbol_put(_mali_profiling_set_event);
- } else {
- printk("gator: mali online _mali_profiling_set_event symbol not found\n");
- }
-
- mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
-
- if (mali_set_fb_event) {
- pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
-
- mali_set_fb_event(0,(counter_enabled[COUNTER_FILMSTRIP]?1:0));
-
- symbol_put(_mali_osk_fb_control_set);
- } else {
- printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
- }
-
- /* Generic control interface for Mali DDK. */
- mali_control = symbol_get(_mali_profiling_control);
- if (mali_control) {
- /* The event attribute in the XML file keeps the actual frame rate. */
- unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
- unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
-
- pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
-
- mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled()?1:0));
- mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP]?1:0));
- mali_control(FBDUMP_CONTROL_RATE, rate);
- mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
-
- pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP]?1:0), rate);
-
- symbol_put(_mali_profiling_control);
- } else {
- printk("gator: mali online _mali_profiling_control symbol not found\n");
- }
-
- mali_get_counters = symbol_get(_mali_profiling_get_counters);
- if (mali_get_counters){
- pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
- counter_prev[COUNTER_L2_C0] = 0;
- counter_prev[COUNTER_L2_C1] = 0;
- }
- else{
- pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined");
- }
+ /* If a Mali driver is present and exporting the appropriate symbol
+ * then we can request the HW counters (of which there are only 2)
+ * be configured to count the desired events
+ */
+ mali_profiling_set_event_type *mali_set_hw_event;
+ mali_osk_fb_control_set_type *mali_set_fb_event;
+ mali_profiling_control_type *mali_control;
+
+ mali_set_hw_event = symbol_get(_mali_profiling_set_event);
+
+ if (mali_set_hw_event) {
+ int i;
+
+ pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
+
+ for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ mali_set_hw_event(i, counter_event[i]);
+ } else {
+ mali_set_hw_event(i, 0xFFFFFFFF);
+ }
+ }
+
+ symbol_put(_mali_profiling_set_event);
+ } else {
+ printk("gator: mali online _mali_profiling_set_event symbol not found\n");
+ }
+
+ mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
+
+ if (mali_set_fb_event) {
+ pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
+
+ mali_set_fb_event(0, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
+
+ symbol_put(_mali_osk_fb_control_set);
+ } else {
+ printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
+ }
+
+ /* Generic control interface for Mali DDK. */
+ mali_control = symbol_get(_mali_profiling_control);
+ if (mali_control) {
+ /* The event attribute in the XML file keeps the actual frame rate. */
+ unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
+ unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
+
+ pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
+
+ mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled() ? 1 : 0));
+ mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
+ mali_control(FBDUMP_CONTROL_RATE, rate);
+ mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
+
+ pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0), rate);
+
+ symbol_put(_mali_profiling_control);
+ } else {
+ printk("gator: mali online _mali_profiling_control symbol not found\n");
+ }
+
+ mali_get_counters = symbol_get(_mali_profiling_get_counters);
+ if (mali_get_counters) {
+ pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
+ counter_prev[COUNTER_L2_C0] = 0;
+ counter_prev[COUNTER_L2_C1] = 0;
+ } else {
+ pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined");
+ }
}
-static void mali_counter_deinitialize(void)
+static void mali_counter_deinitialize(void)
{
- mali_profiling_set_event_type *mali_set_hw_event;
- mali_osk_fb_control_set_type *mali_set_fb_event;
- mali_profiling_control_type *mali_control;
+ mali_profiling_set_event_type *mali_set_hw_event;
+ mali_osk_fb_control_set_type *mali_set_fb_event;
+ mali_profiling_control_type *mali_control;
- mali_set_hw_event = symbol_get(_mali_profiling_set_event);
+ mali_set_hw_event = symbol_get(_mali_profiling_set_event);
- if (mali_set_hw_event) {
- int i;
-
- pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event);
- for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
- mali_set_hw_event(i, 0xFFFFFFFF);
- }
-
- symbol_put(_mali_profiling_set_event);
- } else {
- printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
- }
+ if (mali_set_hw_event) {
+ int i;
- mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
+ pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
+ for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
+ mali_set_hw_event(i, 0xFFFFFFFF);
+ }
- if (mali_set_fb_event) {
- pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
+ symbol_put(_mali_profiling_set_event);
+ } else {
+ printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
+ }
- mali_set_fb_event(0,0);
+ mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
- symbol_put(_mali_osk_fb_control_set);
- } else {
- printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
- }
+ if (mali_set_fb_event) {
+ pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
- /* Generic control interface for Mali DDK. */
- mali_control = symbol_get(_mali_profiling_control);
+ mali_set_fb_event(0, 0);
- if (mali_control) {
- pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event);
+ symbol_put(_mali_osk_fb_control_set);
+ } else {
+ printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
+ }
- /* Reset the DDK state - disable counter collection */
- mali_control(SW_EVENTS_ENABLE, 0);
+ /* Generic control interface for Mali DDK. */
+ mali_control = symbol_get(_mali_profiling_control);
- mali_control(FBDUMP_CONTROL_ENABLE, 0);
+ if (mali_control) {
+ pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event);
- symbol_put(_mali_profiling_control);
- } else {
- printk("gator: mali offline _mali_profiling_control symbol not found\n");
- }
+ /* Reset the DDK state - disable counter collection */
+ mali_control(SW_EVENTS_ENABLE, 0);
- if (mali_get_counters){
- symbol_put(_mali_profiling_get_counters);
- }
+ mali_control(FBDUMP_CONTROL_ENABLE, 0);
+
+ symbol_put(_mali_profiling_control);
+ } else {
+ printk("gator: mali offline _mali_profiling_control symbol not found\n");
+ }
+
+ if (mali_get_counters) {
+ symbol_put(_mali_profiling_get_counters);
+ }
}
-static int start(void) {
- // register tracepoints
- if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
- printk("gator: mali_hw_counter tracepoint failed to activate\n");
- return -1;
- }
+static int start(void)
+{
+ // register tracepoints
+ if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
+ printk("gator: mali_hw_counter tracepoint failed to activate\n");
+ return -1;
+ }
#if GATOR_MALI_INTERFACE_STYLE == 1
- /* None. */
+ /* None. */
#elif GATOR_MALI_INTERFACE_STYLE == 2
- /* For patched Mali driver. */
- if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
- printk("gator: mali_sw_counter tracepoint failed to activate\n");
- return -1;
- }
+ /* For patched Mali driver. */
+ if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
+ printk("gator: mali_sw_counter tracepoint failed to activate\n");
+ return -1;
+ }
#elif GATOR_MALI_INTERFACE_STYLE == 3
/* For Mali drivers with built-in support. */
- if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
- printk("gator: mali_sw_counters tracepoint failed to activate\n");
- return -1;
- }
+ if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
+ printk("gator: mali_sw_counters tracepoint failed to activate\n");
+ return -1;
+ }
#else
#error Unknown GATOR_MALI_INTERFACE_STYLE option.
#endif
- trace_registered = 1;
+ trace_registered = 1;
- mali_counter_initialize();
- return 0;
+ mali_counter_initialize();
+ return 0;
}
-static void stop(void) {
- unsigned int cnt;
+static void stop(void)
+{
+ unsigned int cnt;
- pr_debug("gator: mali stop\n");
+ pr_debug("gator: mali stop\n");
- if (trace_registered) {
- GATOR_UNREGISTER_TRACE(mali_hw_counter);
+ if (trace_registered) {
+ GATOR_UNREGISTER_TRACE(mali_hw_counter);
#if GATOR_MALI_INTERFACE_STYLE == 1
- /* None. */
+ /* None. */
#elif GATOR_MALI_INTERFACE_STYLE == 2
- /* For patched Mali driver. */
- GATOR_UNREGISTER_TRACE(mali_sw_counter);
+ /* For patched Mali driver. */
+ GATOR_UNREGISTER_TRACE(mali_sw_counter);
#elif GATOR_MALI_INTERFACE_STYLE == 3
- /* For Mali drivers with built-in support. */
- GATOR_UNREGISTER_TRACE(mali_sw_counters);
+ /* For Mali drivers with built-in support. */
+ GATOR_UNREGISTER_TRACE(mali_sw_counters);
#else
#error Unknown GATOR_MALI_INTERFACE_STYLE option.
#endif
- pr_debug("gator: mali timeline tracepoint deactivated\n");
-
- trace_registered = 0;
- }
+ pr_debug("gator: mali timeline tracepoint deactivated\n");
- for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
- counter_enabled[cnt] = 0;
- counter_event[cnt] = 0;
- counter_address[cnt] = NULL;
- }
+ trace_registered = 0;
+ }
- mali_counter_deinitialize();
+ for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
+ counter_enabled[cnt] = 0;
+ counter_event[cnt] = 0;
+ counter_address[cnt] = NULL;
+ }
+
+ mali_counter_deinitialize();
}
-static int read(int **buffer) {
- int cnt, len = 0;
-
- if (smp_processor_id()) return 0;
-
- // Read the L2 C0 and C1 here.
- if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1] ) {
- u32 src0 = 0;
- u32 val0 = 0;
- u32 src1 = 0;
- u32 val1 = 0;
-
- // Poke the driver to get the counter values
- if (mali_get_counters){
- mali_get_counters(&src0, &val0, &src1, &val1);
- }
-
- if (counter_enabled[COUNTER_L2_C0])
- {
- // Calculate and save src0's counter val0
- counter_dump[len++] = counter_key[COUNTER_L2_C0];
- counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
- }
-
- if (counter_enabled[COUNTER_L2_C1])
- {
- // Calculate and save src1's counter val1
- counter_dump[len++] = counter_key[COUNTER_L2_C1];
- counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
- }
-
- // Save the previous values for the counters.
- counter_prev[COUNTER_L2_C0] = val0;
- counter_prev[COUNTER_L2_C1] = val1;
- }
-
- // Process other (non-timeline) counters.
- for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
-
- counter_data[cnt] = 0;
- }
- }
-
- /*
- * Add in the voltage and frequency counters if enabled. Note that, since these are
- * actually passed as events, the counter value should not be cleared.
- */
- cnt = COUNTER_FREQUENCY;
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
- }
-
- cnt = COUNTER_VOLTAGE;
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
- }
-
-
- if (buffer) {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+static int read(int **buffer)
+{
+ int cnt, len = 0;
+
+ if (smp_processor_id())
+ return 0;
+
+ // Read the L2 C0 and C1 here.
+ if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1]) {
+ u32 src0 = 0;
+ u32 val0 = 0;
+ u32 src1 = 0;
+ u32 val1 = 0;
+
+ // Poke the driver to get the counter values
+ if (mali_get_counters) {
+ mali_get_counters(&src0, &val0, &src1, &val1);
+ }
+
+ if (counter_enabled[COUNTER_L2_C0]) {
+ // Calculate and save src0's counter val0
+ counter_dump[len++] = counter_key[COUNTER_L2_C0];
+ counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
+ }
+
+ if (counter_enabled[COUNTER_L2_C1]) {
+ // Calculate and save src1's counter val1
+ counter_dump[len++] = counter_key[COUNTER_L2_C1];
+ counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
+ }
+
+ // Save the previous values for the counters.
+ counter_prev[COUNTER_L2_C0] = val0;
+ counter_prev[COUNTER_L2_C1] = val1;
+ }
+
+ // Process other (non-timeline) counters.
+ for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+
+ counter_data[cnt] = 0;
+ }
+ }
+
+ /*
+ * Add in the voltage and frequency counters if enabled. Note that, since these are
+ * actually passed as events, the counter value should not be cleared.
+ */
+ cnt = COUNTER_FREQUENCY;
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+ }
+
+ cnt = COUNTER_VOLTAGE;
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+ }
+
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static struct gator_interface gator_events_mali_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read,
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read,
};
-extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv) {
+extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv)
+{
counter_data[COUNTER_FREQUENCY] = frequency_mhz;
counter_data[COUNTER_VOLTAGE] = voltage_mv;
}
int gator_events_mali_init(void)
{
- unsigned int cnt;
+ unsigned int cnt;
- pr_debug("gator: mali init\n");
+ pr_debug("gator: mali init\n");
- for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
- counter_enabled[cnt] = 0;
- counter_event[cnt] = 0;
- counter_key[cnt] = gator_events_get_key();
- counter_address[cnt] = NULL;
- counter_data[cnt] = 0;
- }
+ for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
+ counter_enabled[cnt] = 0;
+ counter_event[cnt] = 0;
+ counter_key[cnt] = gator_events_get_key();
+ counter_address[cnt] = NULL;
+ counter_data[cnt] = 0;
+ }
- trace_registered = 0;
+ trace_registered = 0;
- return gator_events_install(&gator_events_mali_interface);
+ return gator_events_install(&gator_events_mali_interface);
}
gator_events_init(gator_events_mali_init);
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index 62e441c..2186eee 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -10,69 +10,65 @@
static u32 gator_mali_get_id(void)
{
- return MALI_SUPPORT;
+ return MALI_SUPPORT;
}
-extern const char* gator_mali_get_mali_name(void)
+extern const char *gator_mali_get_mali_name(void)
{
- u32 id = gator_mali_get_id();
+ u32 id = gator_mali_get_id();
- switch (id) {
- case MALI_T6xx:
- return "Mali-T6xx";
- case MALI_400:
- return "Mali-400";
- default:
- pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
- return "Mali-Unknown";
- }
+ switch (id) {
+ case MALI_T6xx:
+ return "Mali-T6xx";
+ case MALI_400:
+ return "Mali-400";
+ default:
+ pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
+ return "Mali-Unknown";
+ }
}
-extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter)
+extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter)
{
- int err;
- char buf[255];
- struct dentry *dir;
+ int err;
+ char buf[255];
+ struct dentry *dir;
- /* If the counter name is empty ignore it*/
- if (strlen(event_name) != 0)
- {
- /* Set up the filesystem entry for this event. */
- snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
+ /* If the counter name is empty ignore it */
+ if (strlen(event_name) != 0) {
+ /* Set up the filesystem entry for this event. */
+ snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
- dir = gatorfs_mkdir(sb, root, buf);
+ dir = gatorfs_mkdir(sb, root, buf);
- if (dir == NULL)
- {
- pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf);
- return -1;
- }
+ if (dir == NULL) {
+ pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf);
+ return -1;
+ }
- err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
- if (err != 0)
- {
- pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf);
- return -1;
- }
- err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
- if (err != 0)
- {
- pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf);
- return -1;
- }
- }
+ err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
+ if (err != 0) {
+ pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf);
+ return -1;
+ }
+ err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
+ if (err != 0) {
+ pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf);
+ return -1;
+ }
+ }
- return 0;
+ return 0;
}
extern void gator_mali_initialise_counters(mali_counter counters[], unsigned int n_counters)
{
- unsigned int cnt;
+ unsigned int cnt;
- for (cnt = 0; cnt < n_counters; cnt++) {
- mali_counter *counter = &counters[cnt];
+ for (cnt = 0; cnt < n_counters; cnt++) {
+ mali_counter *counter = &counters[cnt];
- counter->key = gator_events_get_key();
- counter->enabled = 0;
- }
+ counter->key = gator_events_get_key();
+ counter->enabled = 0;
+ }
}
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index 2c9457f..8e33edf 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -35,8 +35,8 @@
* Runtime state information for a counter.
*/
typedef struct {
- unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */
- unsigned long enabled; /* counter enable state */
+ unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */
+ unsigned long enabled; /* counter enable state */
} mali_counter;
/*
@@ -45,7 +45,7 @@ typedef struct {
typedef void mali_profiling_set_event_type(unsigned int, unsigned int);
typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int);
typedef void mali_profiling_control_type(unsigned int, unsigned int);
-typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+typedef void mali_profiling_get_counters_type(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
/*
* Driver entry points for functions called directly by gator.
@@ -53,14 +53,14 @@ typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsi
extern void _mali_profiling_set_event(unsigned int, unsigned int);
extern void _mali_osk_fb_control_set(unsigned int, unsigned int);
extern void _mali_profiling_control(unsigned int, unsigned int);
-extern void _mali_profiling_get_counters(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+extern void _mali_profiling_get_counters(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
/**
* Returns a name which identifies the GPU type (eg Mali-400, Mali-T6xx).
*
* @return The name as a constant string.
*/
-extern const char* gator_mali_get_mali_name(void);
+extern const char *gator_mali_get_mali_name(void);
/**
* Creates a filesystem entry under /dev/gator relating to the specified event name and key, and
@@ -75,10 +75,10 @@ extern const char* gator_mali_get_mali_name(void);
*
* @return 0 if entry point was created, non-zero if not.
*/
-extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter);
+extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter);
/**
- * Initialises the counter array.
+ * Initializes the counter array.
*
* @param keys The array of counters
* @param n_counters The number of entries in each of the arrays.
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c
index f8f868e..1b3a53d 100644
--- a/driver/gator_events_mali_t6xx.c
+++ b/driver/gator_events_mali_t6xx.c
@@ -17,7 +17,6 @@
#include "linux/mali_linux_trace.h"
-
#include "gator_events_mali_common.h"
/*
@@ -27,7 +26,6 @@
#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx
#endif
-
/* Counters for Mali-T6xx:
*
* - Timeline events
@@ -43,72 +41,66 @@
*/
/* Timeline (start/stop) activity */
-static const char* timeline_event_names [] =
-{
- "PM_SHADER_0",
- "PM_SHADER_1",
- "PM_SHADER_2",
- "PM_SHADER_3",
- "PM_SHADER_4",
- "PM_SHADER_5",
- "PM_SHADER_6",
- "PM_SHADER_7",
- "PM_TILER_0",
- "PM_L2_0",
- "PM_L2_1",
- "MMU_AS_0",
- "MMU_AS_1",
- "MMU_AS_2",
- "MMU_AS_3"
+static const char *timeline_event_names[] = {
+ "PM_SHADER_0",
+ "PM_SHADER_1",
+ "PM_SHADER_2",
+ "PM_SHADER_3",
+ "PM_SHADER_4",
+ "PM_SHADER_5",
+ "PM_SHADER_6",
+ "PM_SHADER_7",
+ "PM_TILER_0",
+ "PM_L2_0",
+ "PM_L2_1",
+ "MMU_AS_0",
+ "MMU_AS_1",
+ "MMU_AS_2",
+ "MMU_AS_3"
};
-enum
-{
- PM_SHADER_0 = 0,
- PM_SHADER_1,
- PM_SHADER_2,
- PM_SHADER_3,
- PM_SHADER_4,
- PM_SHADER_5,
- PM_SHADER_6,
- PM_SHADER_7,
- PM_TILER_0,
- PM_L2_0,
- PM_L2_1,
- MMU_AS_0,
- MMU_AS_1,
- MMU_AS_2,
- MMU_AS_3
+enum {
+ PM_SHADER_0 = 0,
+ PM_SHADER_1,
+ PM_SHADER_2,
+ PM_SHADER_3,
+ PM_SHADER_4,
+ PM_SHADER_5,
+ PM_SHADER_6,
+ PM_SHADER_7,
+ PM_TILER_0,
+ PM_L2_0,
+ PM_L2_1,
+ MMU_AS_0,
+ MMU_AS_1,
+ MMU_AS_2,
+ MMU_AS_3
};
/* The number of shader blocks in the enum above */
#define NUM_PM_SHADER (8)
/* Software Counters */
-static const char* software_counter_names [] =
-{
- "MMU_PAGE_FAULT_0",
- "MMU_PAGE_FAULT_1",
- "MMU_PAGE_FAULT_2",
- "MMU_PAGE_FAULT_3"
+static const char *software_counter_names[] = {
+ "MMU_PAGE_FAULT_0",
+ "MMU_PAGE_FAULT_1",
+ "MMU_PAGE_FAULT_2",
+ "MMU_PAGE_FAULT_3"
};
-enum
-{
- MMU_PAGE_FAULT_0 = 0,
- MMU_PAGE_FAULT_1,
- MMU_PAGE_FAULT_2,
- MMU_PAGE_FAULT_3
+enum {
+ MMU_PAGE_FAULT_0 = 0,
+ MMU_PAGE_FAULT_1,
+ MMU_PAGE_FAULT_2,
+ MMU_PAGE_FAULT_3
};
/* Software Counters */
-static const char* accumulators_names [] =
-{
- "TOTAL_ALLOC_PAGES"
+static const char *accumulators_names[] = {
+ "TOTAL_ALLOC_PAGES"
};
-enum
-{
- TOTAL_ALLOC_PAGES = 0
+enum {
+ TOTAL_ALLOC_PAGES = 0
};
#define FIRST_TIMELINE_EVENT (0)
@@ -153,49 +145,46 @@ static struct timespec prev_timestamp;
*/
static inline long get_duration_us(const struct timespec *start, const struct timespec *end)
{
- long event_duration_us = (end->tv_nsec - start->tv_nsec)/1000;
- event_duration_us += (end->tv_sec - start->tv_sec) * 1000000;
+ long event_duration_us = (end->tv_nsec - start->tv_nsec) / 1000;
+ event_duration_us += (end->tv_sec - start->tv_sec) * 1000000;
- return event_duration_us;
+ return event_duration_us;
}
static void record_timeline_event(unsigned int timeline_index, unsigned int type)
{
- struct timespec event_timestamp;
- struct timespec *event_start = &timeline_event_starttime[timeline_index];
-
- switch(type)
- {
- case ACTIVITY_START:
- /* Get the event time... */
- getnstimeofday(&event_timestamp);
-
- /* Remember the start time if the activity is not already started */
- if(event_start->tv_sec == 0)
- {
- *event_start = event_timestamp; /* Structure copy */
- }
- break;
-
- case ACTIVITY_STOP:
- /* if the counter was started... */
- if(event_start->tv_sec != 0)
- {
- /* Get the event time... */
- getnstimeofday(&event_timestamp);
-
- /* Accumulate the duration in us */
- timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp);
-
- /* Reset the start time to indicate the activity is stopped. */
- event_start->tv_sec = 0;
- }
- break;
-
- default:
- /* Other activity events are ignored. */
- break;
- }
+ struct timespec event_timestamp;
+ struct timespec *event_start = &timeline_event_starttime[timeline_index];
+
+ switch (type) {
+ case ACTIVITY_START:
+ /* Get the event time... */
+ getnstimeofday(&event_timestamp);
+
+ /* Remember the start time if the activity is not already started */
+ if (event_start->tv_sec == 0) {
+ *event_start = event_timestamp; /* Structure copy */
+ }
+ break;
+
+ case ACTIVITY_STOP:
+ /* if the counter was started... */
+ if (event_start->tv_sec != 0) {
+ /* Get the event time... */
+ getnstimeofday(&event_timestamp);
+
+ /* Accumulate the duration in us */
+ timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp);
+
+ /* Reset the start time to indicate the activity is stopped. */
+ event_start->tv_sec = 0;
+ }
+ break;
+
+ default:
+ /* Other activity events are ignored. */
+ break;
+ }
}
/*
@@ -204,68 +193,62 @@ static void record_timeline_event(unsigned int timeline_index, unsigned int type
GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long long value))
{
-#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */
-#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */
-#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
+#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */
+#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */
+#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
#define BIT_AT(value, pos) ((value >> pos) & 1)
- static unsigned long long previous_shader_bitmask = 0;
- static unsigned long long previous_tiler_bitmask = 0;
- static unsigned long long previous_l2_bitmask = 0;
-
- switch (event_id)
- {
- case SHADER_PRESENT_LO:
- {
- unsigned long long changed_bitmask = previous_shader_bitmask ^ value;
- int pos;
-
- for (pos = 0; pos < NUM_PM_SHADER; ++pos)
- {
- if (BIT_AT(changed_bitmask, pos))
- {
- record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP);
- }
- }
-
- previous_shader_bitmask = value;
- break;
- }
-
- case TILER_PRESENT_LO:
- {
- unsigned long long changed = previous_tiler_bitmask ^ value;
-
- if (BIT_AT(changed, 0))
- {
- record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
- }
-
- previous_tiler_bitmask = value;
- break;
- }
-
- case L2_PRESENT_LO:
- {
- unsigned long long changed = previous_l2_bitmask ^ value;
-
- if (BIT_AT(changed, 0))
- {
- record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
- }
- if (BIT_AT(changed, 4))
- {
- record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP);
- }
-
- previous_l2_bitmask = value;
- break;
- }
-
- default:
- /* No other blocks are supported at present */
- break;
- }
+ static unsigned long long previous_shader_bitmask = 0;
+ static unsigned long long previous_tiler_bitmask = 0;
+ static unsigned long long previous_l2_bitmask = 0;
+
+ switch (event_id) {
+ case SHADER_PRESENT_LO:
+ {
+ unsigned long long changed_bitmask = previous_shader_bitmask ^ value;
+ int pos;
+
+ for (pos = 0; pos < NUM_PM_SHADER; ++pos) {
+ if (BIT_AT(changed_bitmask, pos)) {
+ record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+ }
+
+ previous_shader_bitmask = value;
+ break;
+ }
+
+ case TILER_PRESENT_LO:
+ {
+ unsigned long long changed = previous_tiler_bitmask ^ value;
+
+ if (BIT_AT(changed, 0)) {
+ record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+
+ previous_tiler_bitmask = value;
+ break;
+ }
+
+ case L2_PRESENT_LO:
+ {
+ unsigned long long changed = previous_l2_bitmask ^ value;
+
+ if (BIT_AT(changed, 0)) {
+ record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+ if (BIT_AT(changed, 4)) {
+ record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+
+ previous_l2_bitmask = value;
+ break;
+ }
+
+ default:
+ /* No other blocks are supported at present */
+ break;
+ }
#undef SHADER_PRESENT_LO
#undef TILER_PRESENT_LO
@@ -275,278 +258,255 @@ GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long
GATOR_DEFINE_PROBE(mali_page_fault_insert_pages, TP_PROTO(int event_id, unsigned long value))
{
- /* We add to the previous since we may receive many tracepoints in one sample period */
- sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value;
+ /* We add to the previous since we may receive many tracepoints in one sample period */
+ sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value;
}
GATOR_DEFINE_PROBE(mali_mmu_as_in_use, TP_PROTO(int event_id))
{
- record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START);
+ record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START);
}
GATOR_DEFINE_PROBE(mali_mmu_as_released, TP_PROTO(int event_id))
{
- record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP);
+ record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP);
}
GATOR_DEFINE_PROBE(mali_total_alloc_pages_change, TP_PROTO(long long int event_id))
{
- accumulators_data[TOTAL_ALLOC_PAGES] = event_id;
+ accumulators_data[TOTAL_ALLOC_PAGES] = event_id;
}
static int create_files(struct super_block *sb, struct dentry *root)
{
- int event;
- /*
- * Create the filesystem for all events
- */
- int counter_index = 0;
- const char* mali_name = gator_mali_get_mali_name();
-
- for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++)
- {
- if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
- counter_index = 0;
- for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++)
- {
- if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
- counter_index = 0;
- for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++)
- {
- if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
-
- return 0;
+ int event;
+ /*
+ * Create the filesystem for all events
+ */
+ int counter_index = 0;
+ const char *mali_name = gator_mali_get_mali_name();
+
+ for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) {
+ if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+ counter_index = 0;
+ for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++) {
+ if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+ counter_index = 0;
+ for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++) {
+ if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+
+ return 0;
}
static int register_tracepoints(void)
{
- if (GATOR_REGISTER_TRACE(mali_pm_status))
- {
- pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages))
- {
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use))
- {
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_mmu_as_released))
- {
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change))
- {
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n");
- return 0;
- }
-
- pr_debug("gator: Mali-T6xx: start\n");
- pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status);
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
-
- return 1;
+ if (GATOR_REGISTER_TRACE(mali_pm_status)) {
+ pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages)) {
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use)) {
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_mmu_as_released)) {
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change)) {
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n");
+ return 0;
+ }
+
+ pr_debug("gator: Mali-T6xx: start\n");
+ pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status);
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
+
+ return 1;
}
static int start(void)
{
- unsigned int cnt;
-
- /* Clean all data for the next capture */
- for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++)
- {
- timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0;
- timeline_data[cnt] = 0;
- }
-
- for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++)
- {
- sw_counter_data[cnt] = 0;
- }
-
- for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++)
- {
- accumulators_data[cnt] = 0;
- }
-
- /* Register tracepoints */
- if (register_tracepoints() == 0)
- {
- return -1;
- }
-
- /*
- * Set the first timestamp for calculating the sample interval. The first interval could be quite long,
- * since it will be the time between 'start' and the first 'read'.
- * This means that timeline values will be divided by a big number for the first sample.
- */
- getnstimeofday(&prev_timestamp);
-
- return 0;
+ unsigned int cnt;
+
+ /* Clean all data for the next capture */
+ for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++) {
+ timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0;
+ timeline_data[cnt] = 0;
+ }
+
+ for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++) {
+ sw_counter_data[cnt] = 0;
+ }
+
+ for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++) {
+ accumulators_data[cnt] = 0;
+ }
+
+ /* Register tracepoints */
+ if (register_tracepoints() == 0) {
+ return -1;
+ }
+
+ /*
+ * Set the first timestamp for calculating the sample interval. The first interval could be quite long,
+ * since it will be the time between 'start' and the first 'read'.
+ * This means that timeline values will be divided by a big number for the first sample.
+ */
+ getnstimeofday(&prev_timestamp);
+
+ return 0;
}
static void stop(void)
{
- pr_debug("gator: Mali-T6xx: stop\n");
+ pr_debug("gator: Mali-T6xx: stop\n");
- /*
- * It is safe to unregister traces even if they were not successfully
- * registered, so no need to check.
- */
- GATOR_UNREGISTER_TRACE(mali_pm_status);
- pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n");
+ /*
+ * It is safe to unregister traces even if they were not successfully
+ * registered, so no need to check.
+ */
+ GATOR_UNREGISTER_TRACE(mali_pm_status);
+ pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages);
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages);
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_mmu_as_released);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_mmu_as_released);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change);
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change);
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n");
}
static int read(int **buffer)
{
- int cnt;
- int len = 0;
- long sample_interval_us = 0;
- struct timespec read_timestamp;
-
- if (smp_processor_id()!=0)
- {
- return 0;
- }
-
- /* Get the start of this sample period. */
- getnstimeofday(&read_timestamp);
-
- /*
- * Calculate the sample interval if the previous sample time is valid.
- * We use tv_sec since it will not be 0.
- */
- if(prev_timestamp.tv_sec != 0) {
- sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp);
- }
-
- /* Structure copy. Update the previous timestamp. */
- prev_timestamp = read_timestamp;
-
- /*
- * Report the timeline counters (ACTIVITY_START/STOP)
- */
- for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++)
- {
- mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_TIMELINE_EVENT;
- unsigned int value;
-
- /* If the activity is still running, reset its start time to the start of this sample period
- * to correct the count. Add the time up to the end of the sample onto the count. */
- if(timeline_event_starttime[index].tv_sec != 0) {
- const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp);
- timeline_data[index] += event_duration;
- timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */
- }
-
- if(sample_interval_us != 0) {
- /* Convert the counter to a percent-of-sample value */
- value = (timeline_data[index] * 100) / sample_interval_us;
- } else {
- pr_debug("gator: Mali-T6xx: setting value to zero\n");
- value = 0;
- }
-
- /* Clear the counter value ready for the next sample. */
- timeline_data[index] = 0;
-
- counter_dump[len++] = counter->key;
- counter_dump[len++] = value;
- }
- }
-
- /* Report the software counters */
- for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_SOFTWARE_COUNTER;
- counter_dump[len++] = counter->key;
- counter_dump[len++] = sw_counter_data[index];
- /* Set the value to zero for the next time */
- sw_counter_data[index] = 0;
- }
- }
-
- /* Report the accumulators */
- for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_ACCUMULATOR;
- counter_dump[len++] = counter->key;
- counter_dump[len++] = accumulators_data[index];
- /* Do not zero the accumulator */
- }
- }
-
- /* Update the buffer */
- if (buffer)
- {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+ int cnt;
+ int len = 0;
+ long sample_interval_us = 0;
+ struct timespec read_timestamp;
+
+ if (smp_processor_id() != 0) {
+ return 0;
+ }
+
+ /* Get the start of this sample period. */
+ getnstimeofday(&read_timestamp);
+
+ /*
+ * Calculate the sample interval if the previous sample time is valid.
+ * We use tv_sec since it will not be 0.
+ */
+ if (prev_timestamp.tv_sec != 0) {
+ sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp);
+ }
+
+ /* Structure copy. Update the previous timestamp. */
+ prev_timestamp = read_timestamp;
+
+ /*
+ * Report the timeline counters (ACTIVITY_START/STOP)
+ */
+ for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) {
+ mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_TIMELINE_EVENT;
+ unsigned int value;
+
+ /* If the activity is still running, reset its start time to the start of this sample period
+ * to correct the count. Add the time up to the end of the sample onto the count. */
+ if (timeline_event_starttime[index].tv_sec != 0) {
+ const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp);
+ timeline_data[index] += event_duration;
+ timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */
+ }
+
+ if (sample_interval_us != 0) {
+ /* Convert the counter to a percent-of-sample value */
+ value = (timeline_data[index] * 100) / sample_interval_us;
+ } else {
+ pr_debug("gator: Mali-T6xx: setting value to zero\n");
+ value = 0;
+ }
+
+ /* Clear the counter value ready for the next sample. */
+ timeline_data[index] = 0;
+
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = value;
+ }
+ }
+
+ /* Report the software counters */
+ for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_SOFTWARE_COUNTER;
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = sw_counter_data[index];
+ /* Set the value to zero for the next time */
+ sw_counter_data[index] = 0;
+ }
+ }
+
+ /* Report the accumulators */
+ for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_ACCUMULATOR;
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = accumulators_data[index];
+ /* Do not zero the accumulator */
+ }
+ }
+
+ /* Update the buffer */
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static struct gator_interface gator_events_mali_t6xx_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read
};
extern int gator_events_mali_t6xx_init(void)
{
- pr_debug("gator: Mali-T6xx: sw_counters init\n");
+ pr_debug("gator: Mali-T6xx: sw_counters init\n");
- gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS);
+ gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS);
- return gator_events_install(&gator_events_mali_t6xx_interface);
+ return gator_events_install(&gator_events_mali_t6xx_interface);
}
gator_events_init(gator_events_mali_t6xx_init);
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c
index 854d02d..72498c8 100644
--- a/driver/gator_events_mali_t6xx_hw.c
+++ b/driver/gator_events_mali_t6xx_hw.c
@@ -26,7 +26,7 @@
* Mali-T6xx
*/
typedef struct kbase_device *kbase_find_device_type(int);
-typedef kbase_context *kbase_create_context_type(kbase_device*);
+typedef kbase_context *kbase_create_context_type(kbase_device *);
typedef void kbase_destroy_context_type(kbase_context *);
typedef void *kbase_va_alloc_type(kbase_context *, u32);
typedef void kbase_va_free_type(kbase_context *, void *);
@@ -36,32 +36,41 @@ typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *);
typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *);
typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *);
-static kbase_find_device_type * kbase_find_device_symbol;
-static kbase_create_context_type * kbase_create_context_symbol;
-static kbase_va_alloc_type * kbase_va_alloc_symbol;
-static kbase_instr_hwcnt_enable_type * kbase_instr_hwcnt_enable_symbol;
-static kbase_instr_hwcnt_clear_type * kbase_instr_hwcnt_clear_symbol;
-static kbase_instr_hwcnt_dump_irq_type * kbase_instr_hwcnt_dump_irq_symbol;
-static kbase_instr_hwcnt_dump_complete_type * kbase_instr_hwcnt_dump_complete_symbol;
-static kbase_instr_hwcnt_disable_type * kbase_instr_hwcnt_disable_symbol;
-static kbase_va_free_type * kbase_va_free_symbol;
-static kbase_destroy_context_type * kbase_destroy_context_symbol;
-
-/** The interval between reads, in ns. */
-static const int READ_INTERVAL_NSEC = 1000000;
-
+static kbase_find_device_type *kbase_find_device_symbol;
+static kbase_create_context_type *kbase_create_context_symbol;
+static kbase_va_alloc_type *kbase_va_alloc_symbol;
+static kbase_instr_hwcnt_enable_type *kbase_instr_hwcnt_enable_symbol;
+static kbase_instr_hwcnt_clear_type *kbase_instr_hwcnt_clear_symbol;
+static kbase_instr_hwcnt_dump_irq_type *kbase_instr_hwcnt_dump_irq_symbol;
+static kbase_instr_hwcnt_dump_complete_type *kbase_instr_hwcnt_dump_complete_symbol;
+static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol;
+static kbase_va_free_type *kbase_va_free_symbol;
+static kbase_destroy_context_type *kbase_destroy_context_symbol;
+
+/** The interval between reads, in ns.
+ *
+ * Earlier we introduced
+ * a 'hold off for 1ms after last read' to resolve MIDBASE-2178 and MALINE-724.
+ * However, the 1ms hold off is too long if no context switches occur as there is a race
+ * between this value and the tick of the read clock in gator which is also 1ms. If we 'miss' the
+ * current read, the counter values are effectively 'spread' over 2ms and the values seen are half
+ * what they should be (since Streamline averages over sample time). In the presence of context switches
+ * this spread can vary and markedly affect the counters. Currently there is no 'proper' solution to
+ * this, but empirically we have found that reducing the minimum read interval to 950us causes the
+ * counts to be much more stable.
+ */
+static const int READ_INTERVAL_NSEC = 950000;
#if GATOR_TEST
#include "gator_events_mali_t6xx_hw_test.c"
#endif
/* Blocks for HW counters */
-enum
-{
- JM_BLOCK = 0,
- TILER_BLOCK,
- SHADER_BLOCK,
- MMU_BLOCK
+enum {
+ JM_BLOCK = 0,
+ TILER_BLOCK,
+ SHADER_BLOCK,
+ MMU_BLOCK
};
/* Counters for Mali-T6xx:
@@ -75,271 +84,270 @@ enum
*/
/* Hardware Counters */
-static const char* const hardware_counter_names [] =
-{
- /* Job Manager */
- "",
- "",
- "",
- "",
- "MESSAGES_SENT",
- "MESSAGES_RECEIVED",
- "GPU_ACTIVE", /* 6 */
- "IRQ_ACTIVE",
- "JS0_JOBS",
- "JS0_TASKS",
- "JS0_ACTIVE",
- "",
- "JS0_WAIT_READ",
- "JS0_WAIT_ISSUE",
- "JS0_WAIT_DEPEND",
- "JS0_WAIT_FINISH",
- "JS1_JOBS",
- "JS1_TASKS",
- "JS1_ACTIVE",
- "",
- "JS1_WAIT_READ",
- "JS1_WAIT_ISSUE",
- "JS1_WAIT_DEPEND",
- "JS1_WAIT_FINISH",
- "JS2_JOBS",
- "JS2_TASKS",
- "JS2_ACTIVE",
- "",
- "JS2_WAIT_READ",
- "JS2_WAIT_ISSUE",
- "JS2_WAIT_DEPEND",
- "JS2_WAIT_FINISH",
- "JS3_JOBS",
- "JS3_TASKS",
- "JS3_ACTIVE",
- "",
- "JS3_WAIT_READ",
- "JS3_WAIT_ISSUE",
- "JS3_WAIT_DEPEND",
- "JS3_WAIT_FINISH",
- "JS4_JOBS",
- "JS4_TASKS",
- "JS4_ACTIVE",
- "",
- "JS4_WAIT_READ",
- "JS4_WAIT_ISSUE",
- "JS4_WAIT_DEPEND",
- "JS4_WAIT_FINISH",
- "JS5_JOBS",
- "JS5_TASKS",
- "JS5_ACTIVE",
- "",
- "JS5_WAIT_READ",
- "JS5_WAIT_ISSUE",
- "JS5_WAIT_DEPEND",
- "JS5_WAIT_FINISH",
- "JS6_JOBS",
- "JS6_TASKS",
- "JS6_ACTIVE",
- "",
- "JS6_WAIT_READ",
- "JS6_WAIT_ISSUE",
- "JS6_WAIT_DEPEND",
- "JS6_WAIT_FINISH",
-
- /*Tiler*/
- "",
- "",
- "",
- "JOBS_PROCESSED",
- "TRIANGLES",
- "QUADS",
- "POLYGONS",
- "POINTS",
- "LINES",
- "VCACHE_HIT",
- "VCACHE_MISS",
- "FRONT_FACING",
- "BACK_FACING",
- "PRIM_VISIBLE",
- "PRIM_CULLED",
- "PRIM_CLIPPED",
- "LEVEL0",
- "LEVEL1",
- "LEVEL2",
- "LEVEL3",
- "LEVEL4",
- "LEVEL5",
- "LEVEL6",
- "LEVEL7",
- "COMMAND_1",
- "COMMAND_2",
- "COMMAND_3",
- "COMMAND_4",
- "COMMAND_4_7",
- "COMMAND_8_15",
- "COMMAND_16_63",
- "COMMAND_64",
- "COMPRESS_IN",
- "COMPRESS_OUT",
- "COMPRESS_FLUSH",
- "TIMESTAMPS",
- "PCACHE_HIT",
- "PCACHE_MISS",
- "PCACHE_LINE",
- "PCACHE_STALL",
- "WRBUF_HIT",
- "WRBUF_MISS",
- "WRBUF_LINE",
- "WRBUF_PARTIAL",
- "WRBUF_STALL",
- "ACTIVE",
- "LOADING_DESC",
- "INDEX_WAIT",
- "INDEX_RANGE_WAIT",
- "VERTEX_WAIT",
- "PCACHE_WAIT",
- "WRBUF_WAIT",
- "BUS_READ",
- "BUS_WRITE",
- "",
- "",
- "",
- "",
- "",
- "UTLB_STALL",
- "UTLB_REPLAY_MISS",
- "UTLB_REPLAY_FULL",
- "UTLB_NEW_MISS",
- "UTLB_HIT",
-
- /* Shader Core */
- "",
- "",
- "",
- "SHADER_CORE_ACTIVE",
- "FRAG_ACTIVE",
- "FRAG_PRIMATIVES",
- "FRAG_PRIMATIVES_DROPPED",
- "FRAG_CYCLE_DESC",
- "FRAG_CYCLES_PLR",
- "FRAG_CYCLES_VERT",
- "FRAG_CYCLES_TRISETUP",
- "FRAG_CYCLES_RAST",
- "FRAG_THREADS",
- "FRAG_DUMMY_THREADS",
- "FRAG_QUADS_RAST",
- "FRAG_QUADS_EZS_TEST",
- "FRAG_QUADS_EZS_KILLED",
- "FRAG_QUADS_LZS_TEST",
- "FRAG_QUADS_LZS_KILLED",
- "FRAG_CYCLE_NO_TILE",
- "FRAG_NUM_TILES",
- "FRAG_TRANS_ELIM",
- "COMPUTE_ACTIVE",
- "COMPUTE_TASKS",
- "COMPUTE_THREADS",
- "COMPUTE_CYCLES_DESC",
- "TRIPIPE_ACTIVE",
- "ARITH_WORDS",
- "ARITH_CYCLES_REG",
- "ARITH_CYCLES_L0",
- "ARITH_FRAG_DEPEND",
- "LS_WORDS",
- "LS_ISSUES",
- "LS_RESTARTS",
- "LS_REISSUES_MISS",
- "LS_REISSUES_VD",
- "LS_REISSUE_ATTRIB_MISS",
- "LS_NO_WB",
- "TEX_WORDS",
- "TEX_BUBBLES",
- "TEX_WORDS_L0",
- "TEX_WORDS_DESC",
- "TEX_THREADS",
- "TEX_RECIRC_FMISS",
- "TEX_RECIRC_DESC",
- "TEX_RECIRC_MULTI",
- "TEX_RECIRC_PMISS",
- "TEX_RECIRC_CONF",
- "LSC_READ_HITS",
- "LSC_READ_MISSES",
- "LSC_WRITE_HITS",
- "LSC_WRITE_MISSES",
- "LSC_ATOMIC_HITS",
- "LSC_ATOMIC_MISSES",
- "LSC_LINE_FETCHES",
- "LSC_DIRTY_LINE",
- "LSC_SNOOPS",
- "AXI_TLB_STALL",
- "AXI_TLB_MIESS",
- "AXI_TLB_TRANSACTION",
- "LS_TLB_MISS",
- "LS_TLB_HIT",
- "AXI_BEATS_READ",
- "AXI_BEATS_WRITTEN",
-
- /*L2 and MMU */
- "",
- "",
- "",
- "",
- "MMU_TABLE_WALK",
- "MMU_REPLAY_MISS",
- "MMU_REPLAY_FULL",
- "MMU_NEW_MISS",
- "MMU_HIT",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "UTLB_STALL",
- "UTLB_REPLAY_MISS",
- "UTLB_REPLAY_FULL",
- "UTLB_NEW_MISS",
- "UTLB_HIT",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "L2_WRITE_BEATS",
- "L2_READ_BEATS",
- "L2_ANY_LOOKUP",
- "L2_READ_LOOKUP",
- "L2_SREAD_LOOKUP",
- "L2_READ_REPLAY",
- "L2_READ_SNOOP",
- "L2_READ_HIT",
- "L2_CLEAN_MISS",
- "L2_WRITE_LOOKUP",
- "L2_SWRITE_LOOKUP",
- "L2_WRITE_REPLAY",
- "L2_WRITE_SNOOP",
- "L2_WRITE_HIT",
- "L2_EXT_READ_FULL",
- "L2_EXT_READ_HALF",
- "L2_EXT_WRITE_FULL",
- "L2_EXT_WRITE_HALF",
- "L2_EXT_READ",
- "L2_EXT_READ_LINE",
- "L2_EXT_WRITE",
- "L2_EXT_WRITE_LINE",
- "L2_EXT_WRITE_SMALL",
- "L2_EXT_BARRIER",
- "L2_EXT_AR_STALL",
- "L2_EXT_R_BUF_FULL",
- "L2_EXT_RD_BUF_FULL",
- "L2_EXT_R_RAW",
- "L2_EXT_W_STALL",
- "L2_EXT_W_BUF_FULL",
- "L2_EXT_R_W_HAZARD",
- "L2_TAG_HAZARD",
- "L2_SNOOP_FULL",
- "L2_REPLAY_FULL"
+static const char *const hardware_counter_names[] = {
+ /* Job Manager */
+ "",
+ "",
+ "",
+ "",
+ "MESSAGES_SENT",
+ "MESSAGES_RECEIVED",
+ "GPU_ACTIVE", /* 6 */
+ "IRQ_ACTIVE",
+ "JS0_JOBS",
+ "JS0_TASKS",
+ "JS0_ACTIVE",
+ "",
+ "JS0_WAIT_READ",
+ "JS0_WAIT_ISSUE",
+ "JS0_WAIT_DEPEND",
+ "JS0_WAIT_FINISH",
+ "JS1_JOBS",
+ "JS1_TASKS",
+ "JS1_ACTIVE",
+ "",
+ "JS1_WAIT_READ",
+ "JS1_WAIT_ISSUE",
+ "JS1_WAIT_DEPEND",
+ "JS1_WAIT_FINISH",
+ "JS2_JOBS",
+ "JS2_TASKS",
+ "JS2_ACTIVE",
+ "",
+ "JS2_WAIT_READ",
+ "JS2_WAIT_ISSUE",
+ "JS2_WAIT_DEPEND",
+ "JS2_WAIT_FINISH",
+ "JS3_JOBS",
+ "JS3_TASKS",
+ "JS3_ACTIVE",
+ "",
+ "JS3_WAIT_READ",
+ "JS3_WAIT_ISSUE",
+ "JS3_WAIT_DEPEND",
+ "JS3_WAIT_FINISH",
+ "JS4_JOBS",
+ "JS4_TASKS",
+ "JS4_ACTIVE",
+ "",
+ "JS4_WAIT_READ",
+ "JS4_WAIT_ISSUE",
+ "JS4_WAIT_DEPEND",
+ "JS4_WAIT_FINISH",
+ "JS5_JOBS",
+ "JS5_TASKS",
+ "JS5_ACTIVE",
+ "",
+ "JS5_WAIT_READ",
+ "JS5_WAIT_ISSUE",
+ "JS5_WAIT_DEPEND",
+ "JS5_WAIT_FINISH",
+ "JS6_JOBS",
+ "JS6_TASKS",
+ "JS6_ACTIVE",
+ "",
+ "JS6_WAIT_READ",
+ "JS6_WAIT_ISSUE",
+ "JS6_WAIT_DEPEND",
+ "JS6_WAIT_FINISH",
+
+ /*Tiler */
+ "",
+ "",
+ "",
+ "JOBS_PROCESSED",
+ "TRIANGLES",
+ "QUADS",
+ "POLYGONS",
+ "POINTS",
+ "LINES",
+ "VCACHE_HIT",
+ "VCACHE_MISS",
+ "FRONT_FACING",
+ "BACK_FACING",
+ "PRIM_VISIBLE",
+ "PRIM_CULLED",
+ "PRIM_CLIPPED",
+ "LEVEL0",
+ "LEVEL1",
+ "LEVEL2",
+ "LEVEL3",
+ "LEVEL4",
+ "LEVEL5",
+ "LEVEL6",
+ "LEVEL7",
+ "COMMAND_1",
+ "COMMAND_2",
+ "COMMAND_3",
+ "COMMAND_4",
+ "COMMAND_4_7",
+ "COMMAND_8_15",
+ "COMMAND_16_63",
+ "COMMAND_64",
+ "COMPRESS_IN",
+ "COMPRESS_OUT",
+ "COMPRESS_FLUSH",
+ "TIMESTAMPS",
+ "PCACHE_HIT",
+ "PCACHE_MISS",
+ "PCACHE_LINE",
+ "PCACHE_STALL",
+ "WRBUF_HIT",
+ "WRBUF_MISS",
+ "WRBUF_LINE",
+ "WRBUF_PARTIAL",
+ "WRBUF_STALL",
+ "ACTIVE",
+ "LOADING_DESC",
+ "INDEX_WAIT",
+ "INDEX_RANGE_WAIT",
+ "VERTEX_WAIT",
+ "PCACHE_WAIT",
+ "WRBUF_WAIT",
+ "BUS_READ",
+ "BUS_WRITE",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "UTLB_STALL",
+ "UTLB_REPLAY_MISS",
+ "UTLB_REPLAY_FULL",
+ "UTLB_NEW_MISS",
+ "UTLB_HIT",
+
+ /* Shader Core */
+ "",
+ "",
+ "",
+ "SHADER_CORE_ACTIVE",
+ "FRAG_ACTIVE",
+ "FRAG_PRIMATIVES",
+ "FRAG_PRIMATIVES_DROPPED",
+ "FRAG_CYCLE_DESC",
+ "FRAG_CYCLES_PLR",
+ "FRAG_CYCLES_VERT",
+ "FRAG_CYCLES_TRISETUP",
+ "FRAG_CYCLES_RAST",
+ "FRAG_THREADS",
+ "FRAG_DUMMY_THREADS",
+ "FRAG_QUADS_RAST",
+ "FRAG_QUADS_EZS_TEST",
+ "FRAG_QUADS_EZS_KILLED",
+ "FRAG_QUADS_LZS_TEST",
+ "FRAG_QUADS_LZS_KILLED",
+ "FRAG_CYCLE_NO_TILE",
+ "FRAG_NUM_TILES",
+ "FRAG_TRANS_ELIM",
+ "COMPUTE_ACTIVE",
+ "COMPUTE_TASKS",
+ "COMPUTE_THREADS",
+ "COMPUTE_CYCLES_DESC",
+ "TRIPIPE_ACTIVE",
+ "ARITH_WORDS",
+ "ARITH_CYCLES_REG",
+ "ARITH_CYCLES_L0",
+ "ARITH_FRAG_DEPEND",
+ "LS_WORDS",
+ "LS_ISSUES",
+ "LS_RESTARTS",
+ "LS_REISSUES_MISS",
+ "LS_REISSUES_VD",
+ "LS_REISSUE_ATTRIB_MISS",
+ "LS_NO_WB",
+ "TEX_WORDS",
+ "TEX_BUBBLES",
+ "TEX_WORDS_L0",
+ "TEX_WORDS_DESC",
+ "TEX_THREADS",
+ "TEX_RECIRC_FMISS",
+ "TEX_RECIRC_DESC",
+ "TEX_RECIRC_MULTI",
+ "TEX_RECIRC_PMISS",
+ "TEX_RECIRC_CONF",
+ "LSC_READ_HITS",
+ "LSC_READ_MISSES",
+ "LSC_WRITE_HITS",
+ "LSC_WRITE_MISSES",
+ "LSC_ATOMIC_HITS",
+ "LSC_ATOMIC_MISSES",
+ "LSC_LINE_FETCHES",
+ "LSC_DIRTY_LINE",
+ "LSC_SNOOPS",
+ "AXI_TLB_STALL",
+ "AXI_TLB_MIESS",
+ "AXI_TLB_TRANSACTION",
+ "LS_TLB_MISS",
+ "LS_TLB_HIT",
+ "AXI_BEATS_READ",
+ "AXI_BEATS_WRITTEN",
+
+ /*L2 and MMU */
+ "",
+ "",
+ "",
+ "",
+ "MMU_TABLE_WALK",
+ "MMU_REPLAY_MISS",
+ "MMU_REPLAY_FULL",
+ "MMU_NEW_MISS",
+ "MMU_HIT",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "UTLB_STALL",
+ "UTLB_REPLAY_MISS",
+ "UTLB_REPLAY_FULL",
+ "UTLB_NEW_MISS",
+ "UTLB_HIT",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "L2_WRITE_BEATS",
+ "L2_READ_BEATS",
+ "L2_ANY_LOOKUP",
+ "L2_READ_LOOKUP",
+ "L2_SREAD_LOOKUP",
+ "L2_READ_REPLAY",
+ "L2_READ_SNOOP",
+ "L2_READ_HIT",
+ "L2_CLEAN_MISS",
+ "L2_WRITE_LOOKUP",
+ "L2_SWRITE_LOOKUP",
+ "L2_WRITE_REPLAY",
+ "L2_WRITE_SNOOP",
+ "L2_WRITE_HIT",
+ "L2_EXT_READ_FULL",
+ "L2_EXT_READ_HALF",
+ "L2_EXT_WRITE_FULL",
+ "L2_EXT_WRITE_HALF",
+ "L2_EXT_READ",
+ "L2_EXT_READ_LINE",
+ "L2_EXT_WRITE",
+ "L2_EXT_WRITE_LINE",
+ "L2_EXT_WRITE_SMALL",
+ "L2_EXT_BARRIER",
+ "L2_EXT_AR_STALL",
+ "L2_EXT_R_BUF_FULL",
+ "L2_EXT_RD_BUF_FULL",
+ "L2_EXT_R_RAW",
+ "L2_EXT_W_STALL",
+ "L2_EXT_W_BUF_FULL",
+ "L2_EXT_R_W_HAZARD",
+ "L2_TAG_HAZARD",
+ "L2_SNOOP_FULL",
+ "L2_REPLAY_FULL"
};
#define NUMBER_OF_HARDWARE_COUNTERS (sizeof(hardware_counter_names) / sizeof(hardware_counter_names[0]))
@@ -392,8 +400,8 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
#define SYMBOL_CLEANUP(FUNCTION) \
if(FUNCTION ## _symbol) \
{ \
- symbol_put(FUNCTION); \
- FUNCTION ## _symbol = NULL; \
+ symbol_put(FUNCTION); \
+ FUNCTION ## _symbol = NULL; \
}
/**
@@ -442,17 +450,15 @@ static void clean_symbols(void)
*
* Note that this function has been separated out here to allow it to be tested.
*/
-static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns)
+static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns)
{
/* If the current ns count rolls over a second, roll the next read time too. */
- if(current_time->tv_sec != *prev_time_s)
- {
+ if (current_time->tv_sec != *prev_time_s) {
*next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC;
}
/* Abort the read if the next read time has not arrived. */
- if(current_time->tv_nsec < *next_read_time_ns)
- {
+ if (current_time->tv_nsec < *next_read_time_ns) {
return 0;
}
@@ -465,154 +471,146 @@ static int is_read_scheduled(const struct timespec *current_time, u32* prev_time
static int start(void)
{
- kbase_uk_hwcnt_setup setup;
- mali_error err;
- int cnt;
- u16 bitmask[] = {0, 0, 0, 0};
-
- /* Setup HW counters */
- num_hardware_counters_enabled = 0;
-
- if(NUMBER_OF_HARDWARE_COUNTERS != 256)
- {
- pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS);
- }
-
- /* Calculate enable bitmasks based on counters_enabled array */
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- int block = GET_HW_BLOCK(cnt);
- int enable_bit = GET_COUNTER_OFFSET(cnt) / 4;
- bitmask[block] |= (1 << enable_bit);
- pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt);
- num_hardware_counters_enabled++;
- }
- }
-
- /* Create a kbase context for HW counters */
- if (num_hardware_counters_enabled > 0)
- {
- if(init_symbols() > 0)
- {
- clean_symbols();
- /* No Mali driver code entrypoints found - not a fault. */
- return 0;
- }
-
- kbdevice = kbase_find_device_symbol(-1);
-
- /* If we already got a context, fail */
- if (kbcontext) {
- pr_debug("gator: Mali-T6xx: error context already present\n");
- goto out;
- }
-
- /* kbcontext will only be valid after all the Mali symbols are loaded successfully */
- kbcontext = kbase_create_context_symbol(kbdevice);
- if (!kbcontext)
- {
- pr_debug("gator: Mali-T6xx: error creating kbase context\n");
- goto out;
- }
-
- /*
- * The amount of memory needed to store the dump (bytes)
- * DUMP_SIZE = number of core groups
- * * number of blocks (always 8 for midgard)
- * * number of counters per block (always 64 for midgard)
- * * number of bytes per counter (always 4 in midgard)
- * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4
- */
- kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048);
- if (!kernel_dump_buffer)
- {
- pr_debug("gator: Mali-T6xx: error trying to allocate va\n");
- goto destroy_context;
- }
-
- setup.dump_buffer = (uintptr_t)kernel_dump_buffer;
- setup.jm_bm = bitmask[JM_BLOCK];
- setup.tiler_bm = bitmask[TILER_BLOCK];
- setup.shader_bm = bitmask[SHADER_BLOCK];
- setup.mmu_l2_bm = bitmask[MMU_BLOCK];
- /* These counters do not exist on Mali-T60x */
- setup.l3_cache_bm = 0;
-
- /* Use kbase API to enable hardware counters and provide dump buffer */
- err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup);
- if (err != MALI_ERROR_NONE)
- {
- pr_debug("gator: Mali-T6xx: can't setup hardware counters\n");
- goto free_buffer;
- }
- pr_debug("gator: Mali-T6xx: hardware counters enabled\n");
- kbase_instr_hwcnt_clear_symbol(kbcontext);
- pr_debug("gator: Mali-T6xx: hardware counters cleared \n");
-
- kbase_device_busy = false;
- }
-
- return 0;
-
- free_buffer:
+ kbase_uk_hwcnt_setup setup;
+ mali_error err;
+ int cnt;
+ u16 bitmask[] = { 0, 0, 0, 0 };
+
+ /* Setup HW counters */
+ num_hardware_counters_enabled = 0;
+
+ if (NUMBER_OF_HARDWARE_COUNTERS != 256) {
+ pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS);
+ }
+
+ /* Calculate enable bitmasks based on counters_enabled array */
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ int block = GET_HW_BLOCK(cnt);
+ int enable_bit = GET_COUNTER_OFFSET(cnt) / 4;
+ bitmask[block] |= (1 << enable_bit);
+ pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt);
+ num_hardware_counters_enabled++;
+ }
+ }
+
+ /* Create a kbase context for HW counters */
+ if (num_hardware_counters_enabled > 0) {
+ if (init_symbols() > 0) {
+ clean_symbols();
+ /* No Mali driver code entrypoints found - not a fault. */
+ return 0;
+ }
+
+ kbdevice = kbase_find_device_symbol(-1);
+
+ /* If we already got a context, fail */
+ if (kbcontext) {
+ pr_debug("gator: Mali-T6xx: error context already present\n");
+ goto out;
+ }
+
+ /* kbcontext will only be valid after all the Mali symbols are loaded successfully */
+ kbcontext = kbase_create_context_symbol(kbdevice);
+ if (!kbcontext) {
+ pr_debug("gator: Mali-T6xx: error creating kbase context\n");
+ goto out;
+ }
+
+ /*
+ * The amount of memory needed to store the dump (bytes)
+ * DUMP_SIZE = number of core groups
+ * * number of blocks (always 8 for midgard)
+ * * number of counters per block (always 64 for midgard)
+ * * number of bytes per counter (always 4 in midgard)
+ * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4
+ */
+ kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048);
+ if (!kernel_dump_buffer) {
+ pr_debug("gator: Mali-T6xx: error trying to allocate va\n");
+ goto destroy_context;
+ }
+
+ setup.dump_buffer = (uintptr_t)kernel_dump_buffer;
+ setup.jm_bm = bitmask[JM_BLOCK];
+ setup.tiler_bm = bitmask[TILER_BLOCK];
+ setup.shader_bm = bitmask[SHADER_BLOCK];
+ setup.mmu_l2_bm = bitmask[MMU_BLOCK];
+ /* These counters do not exist on Mali-T60x */
+ setup.l3_cache_bm = 0;
+
+ /* Use kbase API to enable hardware counters and provide dump buffer */
+ err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup);
+ if (err != MALI_ERROR_NONE) {
+ pr_debug("gator: Mali-T6xx: can't setup hardware counters\n");
+ goto free_buffer;
+ }
+ pr_debug("gator: Mali-T6xx: hardware counters enabled\n");
+ kbase_instr_hwcnt_clear_symbol(kbcontext);
+ pr_debug("gator: Mali-T6xx: hardware counters cleared \n");
+
+ kbase_device_busy = false;
+ }
+
+ return 0;
+
+free_buffer:
kbase_va_free_symbol(kbcontext, kernel_dump_buffer);
- destroy_context:
+destroy_context:
kbase_destroy_context_symbol(kbcontext);
- out:
+out:
clean_symbols();
- return -1;
+ return -1;
}
-static void stop(void) {
- unsigned int cnt;
- kbase_context *temp_kbcontext;
+static void stop(void)
+{
+ unsigned int cnt;
+ kbase_context *temp_kbcontext;
- pr_debug("gator: Mali-T6xx: stop\n");
+ pr_debug("gator: Mali-T6xx: stop\n");
- /* Set all counters as disabled */
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
- counters[cnt].enabled = 0;
- }
+ /* Set all counters as disabled */
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ counters[cnt].enabled = 0;
+ }
- /* Destroy the context for HW counters */
- if (num_hardware_counters_enabled > 0 && kbcontext != NULL)
- {
- /*
- * Set the global variable to NULL before destroying it, because
- * other function will check this before using it.
- */
- temp_kbcontext = kbcontext;
- kbcontext = NULL;
+ /* Destroy the context for HW counters */
+ if (num_hardware_counters_enabled > 0 && kbcontext != NULL) {
+ /*
+ * Set the global variable to NULL before destroying it, because
+ * other function will check this before using it.
+ */
+ temp_kbcontext = kbcontext;
+ kbcontext = NULL;
- kbase_instr_hwcnt_disable_symbol(temp_kbcontext);
- kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer);
- kbase_destroy_context_symbol(temp_kbcontext);
+ kbase_instr_hwcnt_disable_symbol(temp_kbcontext);
+ kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer);
+ kbase_destroy_context_symbol(temp_kbcontext);
- pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
+ pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
- clean_symbols();
- }
+ clean_symbols();
+ }
}
-static int read(int **buffer) {
- int cnt;
- int len = 0;
- u32 value = 0;
- mali_bool success;
+static int read(int **buffer)
+{
+ int cnt;
+ int len = 0;
+ u32 value = 0;
+ mali_bool success;
struct timespec current_time;
static u32 prev_time_s = 0;
static s32 next_read_time_ns = 0;
- if (smp_processor_id()!=0)
- {
- return 0;
- }
+ if (smp_processor_id() != 0) {
+ return 0;
+ }
getnstimeofday(&current_time);
@@ -620,114 +618,105 @@ static int read(int **buffer) {
* Discard reads unless a respectable time has passed. This reduces the load on the GPU without sacrificing
* accuracy on the Streamline display.
*/
- if(!is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns))
- {
+ if (!is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns)) {
return 0;
}
- /*
- * Report the HW counters
- * Only process hardware counters if at least one of the hardware counters is enabled.
- */
- if (num_hardware_counters_enabled > 0)
- {
- const unsigned int vithar_blocks[] = {
- 0x700, /* VITHAR_JOB_MANAGER, Block 0 */
- 0x400, /* VITHAR_TILER, Block 1 */
- 0x000, /* VITHAR_SHADER_CORE, Block 2 */
- 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */
- };
-
- if (!kbcontext)
- {
- return -1;
- }
-
- /* Mali symbols can be called safely since a kbcontext is valid */
- if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE)
- {
- kbase_device_busy = false;
-
- if (success == MALI_TRUE)
- {
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int block = GET_HW_BLOCK(cnt);
- const int counter_offset = GET_COUNTER_OFFSET(cnt);
- const u32 *counter_block = (u32 *)((uintptr_t)kernel_dump_buffer + vithar_blocks[block]);
- const u32 *counter_address = counter_block + counter_offset;
-
- value = *counter_address;
-
- if(block == SHADER_BLOCK){
- /* (counter_address + 0x000) has already been accounted-for above. */
- value += *(counter_address + 0x100);
- value += *(counter_address + 0x200);
- value += *(counter_address + 0x300);
- }
-
- counter_dump[len++] = counter->key;
- counter_dump[len++] = value;
- }
- }
- }
- }
-
- if (! kbase_device_busy)
- {
- kbase_device_busy = true;
- kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
- }
- }
-
- /* Update the buffer */
- if (buffer) {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+ /*
+ * Report the HW counters
+ * Only process hardware counters if at least one of the hardware counters is enabled.
+ */
+ if (num_hardware_counters_enabled > 0) {
+ const unsigned int vithar_blocks[] = {
+ 0x700, /* VITHAR_JOB_MANAGER, Block 0 */
+ 0x400, /* VITHAR_TILER, Block 1 */
+ 0x000, /* VITHAR_SHADER_CORE, Block 2 */
+ 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */
+ };
+
+ if (!kbcontext) {
+ return -1;
+ }
+
+ /* Mali symbols can be called safely since a kbcontext is valid */
+ if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) {
+ kbase_device_busy = false;
+
+ if (success == MALI_TRUE) {
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int block = GET_HW_BLOCK(cnt);
+ const int counter_offset = GET_COUNTER_OFFSET(cnt);
+ const u32 *counter_block = (u32 *) ((uintptr_t)kernel_dump_buffer + vithar_blocks[block]);
+ const u32 *counter_address = counter_block + counter_offset;
+
+ value = *counter_address;
+
+ if (block == SHADER_BLOCK) {
+ /* (counter_address + 0x000) has already been accounted-for above. */
+ value += *(counter_address + 0x100);
+ value += *(counter_address + 0x200);
+ value += *(counter_address + 0x300);
+ }
+
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = value;
+ }
+ }
+ }
+ }
+
+ if (!kbase_device_busy) {
+ kbase_device_busy = true;
+ kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
+ }
+ }
+
+ /* Update the buffer */
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static int create_files(struct super_block *sb, struct dentry *root)
{
- unsigned int event;
- /*
- * Create the filesystem for all events
- */
- int counter_index = 0;
- const char* mali_name = gator_mali_get_mali_name();
-
- for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++)
- {
- if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event]) != 0)
- return -1;
- counter_index++;
- }
-
- return 0;
+ unsigned int event;
+ /*
+ * Create the filesystem for all events
+ */
+ int counter_index = 0;
+ const char *mali_name = gator_mali_get_mali_name();
+
+ for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++) {
+ if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event]) != 0)
+ return -1;
+ counter_index++;
+ }
+
+ return 0;
}
static struct gator_interface gator_events_mali_t6xx_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read
};
int gator_events_mali_t6xx_hw_init(void)
{
- pr_debug("gator: Mali-T6xx: sw_counters init\n");
+ pr_debug("gator: Mali-T6xx: sw_counters init\n");
#if GATOR_TEST
test_all_is_read_scheduled();
#endif
- gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
+ gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
- return gator_events_install(&gator_events_mali_t6xx_interface);
+ return gator_events_install(&gator_events_mali_t6xx_interface);
}
gator_events_init(gator_events_mali_t6xx_hw_init);
diff --git a/driver/gator_events_mali_t6xx_hw_test.c b/driver/gator_events_mali_t6xx_hw_test.c
index 2a35e77..eb77110 100644
--- a/driver/gator_events_mali_t6xx_hw_test.c
+++ b/driver/gator_events_mali_t6xx_hw_test.c
@@ -11,7 +11,7 @@
* Test functions for mali_t600_hw code.
*/
-static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns);
+static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns);
static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int expected_result, s32 expected_next_ns)
{
@@ -22,14 +22,12 @@ static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int ex
current_time.tv_sec = s;
current_time.tv_nsec = ns;
- if(is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns) != expected_result)
- {
+ if (is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns) != expected_result) {
printk("Failed do_read(%u, %u, %u, %d): expected %d\n", s, ns, prev_s, next_ns, expected_result);
return 0;
}
- if(next_read_time_ns != expected_next_ns)
- {
+ if (next_read_time_ns != expected_next_ns) {
printk("Failed: next_read_ns expected=%d, actual=%d\n", expected_next_ns, next_read_time_ns);
return 0;
}
@@ -44,14 +42,14 @@ static void test_all_is_read_scheduled(void)
printk("gator: running tests on %s\n", __FILE__);
- n_tests_passed += test_is_read_scheduled(0,0,0,0, 1, READ_INTERVAL_NSEC); /* Null time */
- n_tests_passed += test_is_read_scheduled(100,1000,0,0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */
+ n_tests_passed += test_is_read_scheduled(0, 0, 0, 0, 1, READ_INTERVAL_NSEC); /* Null time */
+ n_tests_passed += test_is_read_scheduled(100, 1000, 0, 0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */
- n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500);
- n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC);
- n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC);
+ n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500);
+ n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC);
+ n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC);
- n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC);
+ n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC);
printk("gator: %d tests passed\n", n_tests_passed);
}
diff --git a/driver/gator_events_meminfo.c b/driver/gator_events_meminfo.c
index b962641..fd063b2 100644
--- a/driver/gator_events_meminfo.c
+++ b/driver/gator_events_meminfo.c
@@ -31,22 +31,25 @@ static struct timer_list meminfo_wake_up_timer;
static void meminfo_wake_up_handler(unsigned long unused_data);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
-GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order)) {
+GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order))
#else
-GATOR_DEFINE_PROBE(mm_page_free, TP_PROTO(struct page *page, unsigned int order)) {
+GATOR_DEFINE_PROBE(mm_page_free, TP_PROTO(struct page *page, unsigned int order))
#endif
+{
mem_event++;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
-GATOR_DEFINE_PROBE(mm_pagevec_free, TP_PROTO(struct page *page, int cold)) {
+GATOR_DEFINE_PROBE(mm_pagevec_free, TP_PROTO(struct page *page, int cold))
#else
-GATOR_DEFINE_PROBE(mm_page_free_batched, TP_PROTO(struct page *page, int cold)) {
+GATOR_DEFINE_PROBE(mm_page_free_batched, TP_PROTO(struct page *page, int cold))
#endif
+{
mem_event++;
}
-GATOR_DEFINE_PROBE(mm_page_alloc, TP_PROTO(struct page *page, unsigned int order, gfp_t gfp_flags, int migratetype)) {
+GATOR_DEFINE_PROBE(mm_page_alloc, TP_PROTO(struct page *page, unsigned int order, gfp_t gfp_flags, int migratetype))
+{
mem_event++;
}
@@ -233,4 +236,5 @@ int gator_events_meminfo_init(void)
return gator_events_install(&gator_events_meminfo_interface);
}
+
gator_events_init(gator_events_meminfo_init);
diff --git a/driver/gator_events_mmaped.c b/driver/gator_events_mmaped.c
index 1be6e66..c4cb44f 100644
--- a/driver/gator_events_mmaped.c
+++ b/driver/gator_events_mmaped.c
@@ -45,7 +45,7 @@ static s64 prev_time;
/* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/events */
static int gator_events_mmaped_create_files(struct super_block *sb,
- struct dentry *root)
+ struct dentry *root)
{
int i;
@@ -58,11 +58,11 @@ static int gator_events_mmaped_create_files(struct super_block *sb,
if (WARN_ON(!dir))
return -1;
gatorfs_create_ulong(sb, dir, "enabled",
- &mmaped_counters[i].enabled);
+ &mmaped_counters[i].enabled);
gatorfs_create_ulong(sb, dir, "event",
- &mmaped_counters[i].event);
+ &mmaped_counters[i].event);
gatorfs_create_ro_ulong(sb, dir, "key",
- &mmaped_counters[i].key);
+ &mmaped_counters[i].key);
}
return 0;
@@ -73,7 +73,7 @@ static int gator_events_mmaped_start(void)
#ifdef TODO
for (i = 0; i < MMAPED_COUNTERS_NUM; i++)
writel(mmaped_counters[i].event,
- mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
+ mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
writel(ENABLED, COUNTERS_CONTROL_OFFSET);
#endif
@@ -102,7 +102,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
int result = 0;
switch (counter) {
- case 0: /* sort-of-sine */
+ case 0: /* sort-of-sine */
{
static int t = 0;
int x;
@@ -123,7 +123,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
result = 1922 - result;
}
break;
- case 1: /* triangle */
+ case 1: /* triangle */
{
static int v, d = 1;
@@ -139,7 +139,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
result = v;
}
break;
- case 2: /* PWM signal */
+ case 2: /* PWM signal */
{
static int t, dc, x;
@@ -149,7 +149,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
if (x / 1000000 != (x + delta_in_us) / 1000000)
dc = (dc + 100000) % 1000000;
x += delta_in_us;
-
+
result = t < dc ? 0 : 10;
}
break;
@@ -173,7 +173,7 @@ static int gator_events_mmaped_read(int **buffer)
if (smp_processor_id())
return 0;
-#ifndef TODO
+#ifndef TODO
getnstimeofday(&ts);
time = timespec_to_ns(&ts);
delta_in_us = (int)(time - prev_time) / 1000;
@@ -184,15 +184,16 @@ static int gator_events_mmaped_read(int **buffer)
if (mmaped_counters[i].enabled) {
mmaped_buffer[len++] = mmaped_counters[i].key;
#ifdef TODO
- mmaped_buffer[len++] = readl(mmaped_base +
- COUNTERS_VALUE_OFFSET[i]);
+ mmaped_buffer[len++] =
+ readl(mmaped_base + COUNTERS_VALUE_OFFSET[i]);
#else
- mmaped_buffer[len++] = mmaped_simulate(
- mmaped_counters[i].event, delta_in_us);
+ mmaped_buffer[len++] =
+ mmaped_simulate(mmaped_counters[i].event,
+ delta_in_us);
#endif
}
}
-
+
if (buffer)
*buffer = mmaped_buffer;
@@ -214,7 +215,7 @@ int __init gator_events_mmaped_init(void)
#ifdef TODO
mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K);
if (!mmaped_base)
- return -ENOMEM;
+ return -ENOMEM;
#endif
for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
@@ -224,4 +225,5 @@ int __init gator_events_mmaped_init(void)
return gator_events_install(&gator_events_mmaped_interface);
}
+
gator_events_init(gator_events_mmaped_init);
diff --git a/driver/gator_events_net.c b/driver/gator_events_net.c
index 31cc3ef..b6ce06a 100644
--- a/driver/gator_events_net.c
+++ b/driver/gator_events_net.c
@@ -26,7 +26,8 @@ static int netGet[TOTALNET * 4];
static struct timer_list net_wake_up_timer;
// Must be run in process context as the kernel function dev_get_stats() can sleep
-static void get_network_stats(struct work_struct *wsptr) {
+static void get_network_stats(struct work_struct *wsptr)
+{
int rx = 0, tx = 0;
struct net_device *dev;
@@ -43,6 +44,7 @@ static void get_network_stats(struct work_struct *wsptr) {
rx_total = rx;
tx_total = tx;
}
+
DECLARE_WORK(wq_get_stats, get_network_stats);
static void net_wake_up_handler(unsigned long unused_data)
@@ -129,7 +131,7 @@ static int gator_events_net_read(int **buffer)
if (netrx_enabled && last_rx_delta != rx_delta) {
last_rx_delta = rx_delta;
netGet[len++] = netrx_key;
- netGet[len++] = 0; // indicates to Streamline that rx_delta bytes were transmitted now, not since the last message
+ netGet[len++] = 0; // indicates to Streamline that rx_delta bytes were transmitted now, not since the last message
netGet[len++] = netrx_key;
netGet[len++] = rx_delta;
}
@@ -137,7 +139,7 @@ static int gator_events_net_read(int **buffer)
if (nettx_enabled && last_tx_delta != tx_delta) {
last_tx_delta = tx_delta;
netGet[len++] = nettx_key;
- netGet[len++] = 0; // indicates to Streamline that tx_delta bytes were transmitted now, not since the last message
+ netGet[len++] = 0; // indicates to Streamline that tx_delta bytes were transmitted now, not since the last message
netGet[len++] = nettx_key;
netGet[len++] = tx_delta;
}
@@ -165,4 +167,5 @@ int gator_events_net_init(void)
return gator_events_install(&gator_events_net_interface);
}
+
gator_events_init(gator_events_net_init);
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c
index e025155..ce3a40f 100644
--- a/driver/gator_events_perf_pmu.c
+++ b/driver/gator_events_perf_pmu.c
@@ -45,7 +45,7 @@ static int gator_events_perf_pmu_create_files(struct super_block *sb, struct den
if (i == 0) {
snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "%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) {
@@ -80,13 +80,13 @@ static void dummy_handler(struct perf_event *event, struct perf_sample_data *dat
// Required as perf_event_create_kernel_counter() requires an overflow handler, even though all we do is poll
}
-static int gator_events_perf_pmu_online(int** buffer)
+static int gator_events_perf_pmu_online(int **buffer)
{
int cnt, len = 0, cpu = smp_processor_id();
// read the counters and toss the invalid data, return zero instead
for (cnt = 0; cnt < pmnc_counters; cnt++) {
- struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
+ struct perf_event *ev = per_cpu(pevent, cpu)[cnt];
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
ev->pmu->read(ev);
per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -140,7 +140,7 @@ static void gator_events_perf_pmu_online_dispatch(int cpu)
static void gator_events_perf_pmu_offline_dispatch(int cpu)
{
int cnt;
- struct perf_event * pe;
+ struct perf_event *pe;
for (cnt = 0; cnt < pmnc_counters; cnt++) {
pe = NULL;
@@ -177,7 +177,7 @@ static int gator_events_perf_pmu_start(void)
for_each_present_cpu(cpu) {
for (cnt = 0; cnt < pmnc_counters; cnt++) {
per_cpu(pevent, cpu)[cnt] = NULL;
- if (!pmnc_enabled[cnt]) // Skip disabled counters
+ if (!pmnc_enabled[cnt]) // Skip disabled counters
continue;
per_cpu(perfPrev, cpu)[cnt] = 0;
@@ -233,7 +233,7 @@ static int gator_events_perf_pmu_read(int **buffer)
int cpu = smp_processor_id();
for (cnt = 0; cnt < pmnc_counters; cnt++) {
- struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
+ struct perf_event *ev = per_cpu(pevent, cpu)[cnt];
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
ev->pmu->read(ev);
per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -268,62 +268,21 @@ static struct gator_interface gator_events_perf_pmu_interface = {
int gator_events_perf_pmu_init(void)
{
unsigned int cnt;
-
- switch (gator_cpuid()) {
- case ARM1136:
- case ARM1156:
- case ARM1176:
- pmnc_name = "ARM_ARM11";
- pmnc_counters = 3;
- ccnt = 2;
- break;
- case ARM11MPCORE:
- pmnc_name = "ARM_ARM11MPCore";
- pmnc_counters = 3;
- break;
- case CORTEX_A5:
- pmnc_name = "ARM_Cortex-A5";
- pmnc_counters = 2;
- break;
- case CORTEX_A7:
- pmnc_name = "ARM_Cortex-A7";
- pmnc_counters = 4;
- break;
- case CORTEX_A8:
- pmnc_name = "ARM_Cortex-A8";
- pmnc_counters = 4;
- break;
- case CORTEX_A9:
- pmnc_name = "ARM_Cortex-A9";
- pmnc_counters = 6;
- break;
- case CORTEX_A15:
- pmnc_name = "ARM_Cortex-A15";
- pmnc_counters = 6;
- break;
- case SCORPION:
- pmnc_name = "Scorpion";
- pmnc_counters = 4;
- break;
- case SCORPIONMP:
- pmnc_name = "ScorpionMP";
- pmnc_counters = 4;
- break;
- case KRAITSIM:
- case KRAIT:
- pmnc_name = "Krait";
- pmnc_counters = 4;
- break;
- case AARCH64:
- pmnc_name = "ARM_AArch64";
- // Copied from A15, get the correct number
- pmnc_counters = 6;
- break;
- default:
+ const u32 cpuid = gator_cpuid();
+
+ for (cnt = 0; gator_cpus[cnt].cpuid != 0; ++cnt) {
+ if (gator_cpus[cnt].cpuid == cpuid) {
+ pmnc_name = gator_cpus[cnt].pmnc_name;
+ pmnc_counters = gator_cpus[cnt].pmnc_counters;
+ ccnt = gator_cpus[cnt].ccnt;
+ break;
+ }
+ }
+ if (gator_cpus[cnt].cpuid == 0) {
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = 0; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_sched.c b/driver/gator_events_sched.c
index 9bed364..ba6744d 100644
--- a/driver/gator_events_sched.c
+++ b/driver/gator_events_sched.c
@@ -111,4 +111,5 @@ int gator_events_sched_init(void)
return gator_events_install(&gator_events_sched_interface);
}
+
gator_events_init(gator_events_sched_init);
diff --git a/driver/gator_events_scorpion.c b/driver/gator_events_scorpion.c
index ed0d8de..5ffc63a 100644
--- a/driver/gator_events_scorpion.c
+++ b/driver/gator_events_scorpion.c
@@ -20,8 +20,8 @@ static int pmnc_counters;
#define PMNC_C (1 << 2) /* Cycle counter reset */
#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
#define PMNC_X (1 << 4) /* Export to ETM */
-#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
-#define PMNC_MASK 0x3f /* Mask for writable bits */
+#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug */
+#define PMNC_MASK 0x3f /* Mask for writable bits */
// ccnt reg
#define CCNT_REG (1 << 31)
@@ -37,95 +37,95 @@ static unsigned long pmnc_key[CNTMAX];
static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt);
enum scorpion_perf_types {
- SCORPION_ICACHE_EXPL_INV = 0x4c,
- SCORPION_ICACHE_MISS = 0x4d,
- SCORPION_ICACHE_ACCESS = 0x4e,
- SCORPION_ICACHE_CACHEREQ_L2 = 0x4f,
- SCORPION_ICACHE_NOCACHE_L2 = 0x50,
- SCORPION_HIQUP_NOPED = 0x51,
- SCORPION_DATA_ABORT = 0x52,
- SCORPION_IRQ = 0x53,
- SCORPION_FIQ = 0x54,
- SCORPION_ALL_EXCPT = 0x55,
- SCORPION_UNDEF = 0x56,
- SCORPION_SVC = 0x57,
- SCORPION_SMC = 0x58,
- SCORPION_PREFETCH_ABORT = 0x59,
- SCORPION_INDEX_CHECK = 0x5a,
- SCORPION_NULL_CHECK = 0x5b,
- SCORPION_EXPL_ICIALLU = 0x5c,
- SCORPION_IMPL_ICIALLU = 0x5d,
- SCORPION_NONICIALLU_BTAC_INV = 0x5e,
- SCORPION_ICIMVAU_IMPL_ICIALLU = 0x5f,
- SCORPION_SPIPE_ONLY_CYCLES = 0x60,
- SCORPION_XPIPE_ONLY_CYCLES = 0x61,
- SCORPION_DUAL_CYCLES = 0x62,
- SCORPION_DISPATCH_ANY_CYCLES = 0x63,
- SCORPION_FIFO_FULLBLK_CMT = 0x64,
- SCORPION_FAIL_COND_INST = 0x65,
- SCORPION_PASS_COND_INST = 0x66,
- SCORPION_ALLOW_VU_CLK = 0x67,
- SCORPION_VU_IDLE = 0x68,
- SCORPION_ALLOW_L2_CLK = 0x69,
- SCORPION_L2_IDLE = 0x6a,
- SCORPION_DTLB_IMPL_INV_SCTLR_DACR = 0x6b,
- SCORPION_DTLB_EXPL_INV = 0x6c,
- SCORPION_DTLB_MISS = 0x6d,
- SCORPION_DTLB_ACCESS = 0x6e,
- SCORPION_ITLB_MISS = 0x6f,
- SCORPION_ITLB_IMPL_INV = 0x70,
- SCORPION_ITLB_EXPL_INV = 0x71,
- SCORPION_UTLB_D_MISS = 0x72,
- SCORPION_UTLB_D_ACCESS = 0x73,
- SCORPION_UTLB_I_MISS = 0x74,
- SCORPION_UTLB_I_ACCESS = 0x75,
- SCORPION_UTLB_INV_ASID = 0x76,
- SCORPION_UTLB_INV_MVA = 0x77,
- SCORPION_UTLB_INV_ALL = 0x78,
- SCORPION_S2_HOLD_RDQ_UNAVAIL = 0x79,
- SCORPION_S2_HOLD = 0x7a,
- SCORPION_S2_HOLD_DEV_OP = 0x7b,
- SCORPION_S2_HOLD_ORDER = 0x7c,
- SCORPION_S2_HOLD_BARRIER = 0x7d,
- SCORPION_VIU_DUAL_CYCLE = 0x7e,
- SCORPION_VIU_SINGLE_CYCLE = 0x7f,
- SCORPION_VX_PIPE_WAR_STALL_CYCLES = 0x80,
- SCORPION_VX_PIPE_WAW_STALL_CYCLES = 0x81,
- SCORPION_VX_PIPE_RAW_STALL_CYCLES = 0x82,
- SCORPION_VX_PIPE_LOAD_USE_STALL = 0x83,
- SCORPION_VS_PIPE_WAR_STALL_CYCLES = 0x84,
- SCORPION_VS_PIPE_WAW_STALL_CYCLES = 0x85,
- SCORPION_VS_PIPE_RAW_STALL_CYCLES = 0x86,
- SCORPION_EXCEPTIONS_INV_OPERATION = 0x87,
- SCORPION_EXCEPTIONS_DIV_BY_ZERO = 0x88,
- SCORPION_COND_INST_FAIL_VX_PIPE = 0x89,
- SCORPION_COND_INST_FAIL_VS_PIPE = 0x8a,
- SCORPION_EXCEPTIONS_OVERFLOW = 0x8b,
- SCORPION_EXCEPTIONS_UNDERFLOW = 0x8c,
- SCORPION_EXCEPTIONS_DENORM = 0x8d,
+ SCORPION_ICACHE_EXPL_INV = 0x4c,
+ SCORPION_ICACHE_MISS = 0x4d,
+ SCORPION_ICACHE_ACCESS = 0x4e,
+ SCORPION_ICACHE_CACHEREQ_L2 = 0x4f,
+ SCORPION_ICACHE_NOCACHE_L2 = 0x50,
+ SCORPION_HIQUP_NOPED = 0x51,
+ SCORPION_DATA_ABORT = 0x52,
+ SCORPION_IRQ = 0x53,
+ SCORPION_FIQ = 0x54,
+ SCORPION_ALL_EXCPT = 0x55,
+ SCORPION_UNDEF = 0x56,
+ SCORPION_SVC = 0x57,
+ SCORPION_SMC = 0x58,
+ SCORPION_PREFETCH_ABORT = 0x59,
+ SCORPION_INDEX_CHECK = 0x5a,
+ SCORPION_NULL_CHECK = 0x5b,
+ SCORPION_EXPL_ICIALLU = 0x5c,
+ SCORPION_IMPL_ICIALLU = 0x5d,
+ SCORPION_NONICIALLU_BTAC_INV = 0x5e,
+ SCORPION_ICIMVAU_IMPL_ICIALLU = 0x5f,
+ SCORPION_SPIPE_ONLY_CYCLES = 0x60,
+ SCORPION_XPIPE_ONLY_CYCLES = 0x61,
+ SCORPION_DUAL_CYCLES = 0x62,
+ SCORPION_DISPATCH_ANY_CYCLES = 0x63,
+ SCORPION_FIFO_FULLBLK_CMT = 0x64,
+ SCORPION_FAIL_COND_INST = 0x65,
+ SCORPION_PASS_COND_INST = 0x66,
+ SCORPION_ALLOW_VU_CLK = 0x67,
+ SCORPION_VU_IDLE = 0x68,
+ SCORPION_ALLOW_L2_CLK = 0x69,
+ SCORPION_L2_IDLE = 0x6a,
+ SCORPION_DTLB_IMPL_INV_SCTLR_DACR = 0x6b,
+ SCORPION_DTLB_EXPL_INV = 0x6c,
+ SCORPION_DTLB_MISS = 0x6d,
+ SCORPION_DTLB_ACCESS = 0x6e,
+ SCORPION_ITLB_MISS = 0x6f,
+ SCORPION_ITLB_IMPL_INV = 0x70,
+ SCORPION_ITLB_EXPL_INV = 0x71,
+ SCORPION_UTLB_D_MISS = 0x72,
+ SCORPION_UTLB_D_ACCESS = 0x73,
+ SCORPION_UTLB_I_MISS = 0x74,
+ SCORPION_UTLB_I_ACCESS = 0x75,
+ SCORPION_UTLB_INV_ASID = 0x76,
+ SCORPION_UTLB_INV_MVA = 0x77,
+ SCORPION_UTLB_INV_ALL = 0x78,
+ SCORPION_S2_HOLD_RDQ_UNAVAIL = 0x79,
+ SCORPION_S2_HOLD = 0x7a,
+ SCORPION_S2_HOLD_DEV_OP = 0x7b,
+ SCORPION_S2_HOLD_ORDER = 0x7c,
+ SCORPION_S2_HOLD_BARRIER = 0x7d,
+ SCORPION_VIU_DUAL_CYCLE = 0x7e,
+ SCORPION_VIU_SINGLE_CYCLE = 0x7f,
+ SCORPION_VX_PIPE_WAR_STALL_CYCLES = 0x80,
+ SCORPION_VX_PIPE_WAW_STALL_CYCLES = 0x81,
+ SCORPION_VX_PIPE_RAW_STALL_CYCLES = 0x82,
+ SCORPION_VX_PIPE_LOAD_USE_STALL = 0x83,
+ SCORPION_VS_PIPE_WAR_STALL_CYCLES = 0x84,
+ SCORPION_VS_PIPE_WAW_STALL_CYCLES = 0x85,
+ SCORPION_VS_PIPE_RAW_STALL_CYCLES = 0x86,
+ SCORPION_EXCEPTIONS_INV_OPERATION = 0x87,
+ SCORPION_EXCEPTIONS_DIV_BY_ZERO = 0x88,
+ SCORPION_COND_INST_FAIL_VX_PIPE = 0x89,
+ SCORPION_COND_INST_FAIL_VS_PIPE = 0x8a,
+ SCORPION_EXCEPTIONS_OVERFLOW = 0x8b,
+ SCORPION_EXCEPTIONS_UNDERFLOW = 0x8c,
+ SCORPION_EXCEPTIONS_DENORM = 0x8d,
#ifdef CONFIG_ARCH_MSM_SCORPIONMP
- SCORPIONMP_NUM_BARRIERS = 0x8e,
- SCORPIONMP_BARRIER_CYCLES = 0x8f,
+ SCORPIONMP_NUM_BARRIERS = 0x8e,
+ SCORPIONMP_BARRIER_CYCLES = 0x8f,
#else
- SCORPION_BANK_AB_HIT = 0x8e,
- SCORPION_BANK_AB_ACCESS = 0x8f,
- SCORPION_BANK_CD_HIT = 0x90,
- SCORPION_BANK_CD_ACCESS = 0x91,
- SCORPION_BANK_AB_DSIDE_HIT = 0x92,
- SCORPION_BANK_AB_DSIDE_ACCESS = 0x93,
- SCORPION_BANK_CD_DSIDE_HIT = 0x94,
- SCORPION_BANK_CD_DSIDE_ACCESS = 0x95,
- SCORPION_BANK_AB_ISIDE_HIT = 0x96,
- SCORPION_BANK_AB_ISIDE_ACCESS = 0x97,
- SCORPION_BANK_CD_ISIDE_HIT = 0x98,
- SCORPION_BANK_CD_ISIDE_ACCESS = 0x99,
- SCORPION_ISIDE_RD_WAIT = 0x9a,
- SCORPION_DSIDE_RD_WAIT = 0x9b,
- SCORPION_BANK_BYPASS_WRITE = 0x9c,
- SCORPION_BANK_AB_NON_CASTOUT = 0x9d,
- SCORPION_BANK_AB_L2_CASTOUT = 0x9e,
- SCORPION_BANK_CD_NON_CASTOUT = 0x9f,
- SCORPION_BANK_CD_L2_CASTOUT = 0xa0,
+ SCORPION_BANK_AB_HIT = 0x8e,
+ SCORPION_BANK_AB_ACCESS = 0x8f,
+ SCORPION_BANK_CD_HIT = 0x90,
+ SCORPION_BANK_CD_ACCESS = 0x91,
+ SCORPION_BANK_AB_DSIDE_HIT = 0x92,
+ SCORPION_BANK_AB_DSIDE_ACCESS = 0x93,
+ SCORPION_BANK_CD_DSIDE_HIT = 0x94,
+ SCORPION_BANK_CD_DSIDE_ACCESS = 0x95,
+ SCORPION_BANK_AB_ISIDE_HIT = 0x96,
+ SCORPION_BANK_AB_ISIDE_ACCESS = 0x97,
+ SCORPION_BANK_CD_ISIDE_HIT = 0x98,
+ SCORPION_BANK_CD_ISIDE_ACCESS = 0x99,
+ SCORPION_ISIDE_RD_WAIT = 0x9a,
+ SCORPION_DSIDE_RD_WAIT = 0x9b,
+ SCORPION_BANK_BYPASS_WRITE = 0x9c,
+ SCORPION_BANK_AB_NON_CASTOUT = 0x9d,
+ SCORPION_BANK_AB_L2_CASTOUT = 0x9e,
+ SCORPION_BANK_CD_NON_CASTOUT = 0x9f,
+ SCORPION_BANK_CD_L2_CASTOUT = 0xa0,
#endif
MSM_MAX_EVT
};
@@ -209,8 +209,8 @@ static const struct scorp_evt sc_evt[] = {
{SCORPION_EXCEPTIONS_DENORM, 0x8c000000, 4, 0x5f},
#ifdef CONFIG_ARCH_MSM_SCORPIONMP
- {SCORPIONMP_NUM_BARRIERS, 0x80000e00, 3, 0x59},
- {SCORPIONMP_BARRIER_CYCLES, 0x800e0000, 3, 0x5a},
+ {SCORPIONMP_NUM_BARRIERS, 0x80000e00, 3, 0x59},
+ {SCORPIONMP_BARRIER_CYCLES, 0x800e0000, 3, 0x5a},
#else
{SCORPION_BANK_AB_HIT, 0x80000001, 3, 0x58},
{SCORPION_BANK_AB_ACCESS, 0x80000100, 3, 0x59},
@@ -375,8 +375,8 @@ static void scorpion_write_vlpm(u32 val)
}
struct scorpion_access_funcs {
- u32 (*read) (void);
- void (*write) (u32);
+ u32(*read)(void);
+ void (*write)(u32);
};
struct scorpion_access_funcs scor_func[] = {
@@ -395,7 +395,7 @@ static void scorpion_pre_vlpm(void)
u32 venum_new_val;
u32 fp_new_val;
- /* CPACR Enable CP10 access*/
+ /* CPACR Enable CP10 access */
asm volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (venum_orig_val));
venum_new_val = venum_orig_val | 0x00300000;
asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_new_val));
@@ -407,9 +407,9 @@ static void scorpion_pre_vlpm(void)
static void scorpion_post_vlpm(void)
{
- /* Restore FPEXC*/
+ /* Restore FPEXC */
asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_orig_val));
- /* Restore CPACR*/
+ /* Restore CPACR */
asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_orig_val));
}
@@ -464,7 +464,8 @@ static inline void scorpion_pmnc_write_evtsel(unsigned int cnt, u32 val)
u32 zero = 0;
struct scorp_evt evtinfo;
// extract evtinfo.grp and evtinfo.tevt_type_act from val
- if (get_scorpion_evtinfo(val, &evtinfo) == 0) return;
+ if (get_scorpion_evtinfo(val, &evtinfo) == 0)
+ return;
asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (evtinfo.evt_type_act));
asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (zero));
scorpion_evt_setup(evtinfo.grp, val);
@@ -482,7 +483,7 @@ static void scorpion_pmnc_reset_counter(unsigned int cnt)
asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
if (pmnc_enabled[cnt] != 0)
- scorpion_pmnc_enable_counter(cnt);
+ scorpion_pmnc_enable_counter(cnt);
} else if (cnt >= CNTMAX) {
pr_err("gator: CPU%u resetting wrong PMNC counter %d\n", smp_processor_id(), cnt);
@@ -490,10 +491,10 @@ static void scorpion_pmnc_reset_counter(unsigned int cnt)
scorpion_pmnc_disable_counter(cnt);
if (scorpion_pmnc_select_counter(cnt) == cnt)
- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
if (pmnc_enabled[cnt] != 0)
- scorpion_pmnc_enable_counter(cnt);
+ scorpion_pmnc_enable_counter(cnt);
}
}
@@ -507,14 +508,14 @@ static int gator_events_scorpion_create_files(struct super_block *sb, struct den
if (i == 0) {
snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "%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) {
return -1;
}
gatorfs_create_ulong(sb, dir, "enabled", &pmnc_enabled[i]);
- gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]);
if (i > 0) {
gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]);
}
@@ -523,7 +524,7 @@ static int gator_events_scorpion_create_files(struct super_block *sb, struct den
return 0;
}
-static int gator_events_scorpion_online(int** buffer)
+static int gator_events_scorpion_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
@@ -562,13 +563,10 @@ static int gator_events_scorpion_online(int** buffer)
// read the counters and toss the invalid data, return zero instead
for (cnt = 0; cnt < pmnc_counters; cnt++) {
if (pmnc_enabled[cnt]) {
- int value;
if (cnt == CCNT) {
- value = scorpion_ccnt_read();
+ scorpion_ccnt_read();
} else if (scorpion_pmnc_select_counter(cnt) == cnt) {
- value = scorpion_cntn_read();
- } else {
- value = 0;
+ scorpion_cntn_read();
}
scorpion_pmnc_reset_counter(cnt);
@@ -583,7 +581,7 @@ static int gator_events_scorpion_online(int** buffer)
return len;
}
-static int gator_events_scorpion_offline(int** buffer)
+static int gator_events_scorpion_offline(int **buffer)
{
scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E);
return 0;
@@ -657,7 +655,7 @@ int gator_events_scorpion_init(void)
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = CCNT; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_fs.c b/driver/gator_fs.c
index 81b0d5b..9ff118b 100644
--- a/driver/gator_fs.c
+++ b/driver/gator_fs.c
@@ -35,8 +35,8 @@ static struct inode *gatorfs_get_inode(struct super_block *sb, int mode)
}
static const struct super_operations s_ops = {
- .statfs = simple_statfs,
- .drop_inode = generic_delete_inode,
+ .statfs = simple_statfs,
+ .drop_inode = generic_delete_inode,
};
ssize_t gatorfs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset)
@@ -104,19 +104,21 @@ static int default_open(struct inode *inode, struct file *filp)
}
static const struct file_operations ulong_fops = {
- .read = ulong_read_file,
- .write = ulong_write_file,
- .open = default_open,
+ .read = ulong_read_file,
+ .write = ulong_write_file,
+ .open = default_open,
};
static const struct file_operations ulong_ro_fops = {
- .read = ulong_read_file,
- .open = default_open,
+ .read = ulong_read_file,
+ .open = default_open,
};
static struct dentry *__gatorfs_create_file(struct super_block *sb,
- struct dentry *root, char const *name, const struct file_operations *fops,
- int perm)
+ struct dentry *root,
+ char const *name,
+ const struct file_operations *fops,
+ int perm)
{
struct dentry *dentry;
struct inode *inode;
@@ -135,10 +137,10 @@ static struct dentry *__gatorfs_create_file(struct super_block *sb,
}
int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val)
+ char const *name, unsigned long *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &ulong_fops, 0644);
+ &ulong_fops, 0644);
if (!d)
return -EFAULT;
@@ -147,10 +149,10 @@ 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)
+ char const *name, unsigned long *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &ulong_ro_fops, 0444);
+ &ulong_ro_fops, 0444);
if (!d)
return -EFAULT;
@@ -165,15 +167,15 @@ static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t coun
}
static const struct file_operations atomic_ro_fops = {
- .read = atomic_read_file,
- .open = default_open,
+ .read = atomic_read_file,
+ .open = default_open,
};
int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root,
- char const *name, atomic_t *val)
+ char const *name, atomic_t *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &atomic_ro_fops, 0444);
+ &atomic_ro_fops, 0444);
if (!d)
return -EFAULT;
@@ -182,7 +184,7 @@ int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root,
}
int gatorfs_create_file(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops)
+ char const *name, const struct file_operations *fops)
{
if (!__gatorfs_create_file(sb, root, name, fops, 0644))
return -EFAULT;
@@ -190,7 +192,8 @@ int gatorfs_create_file(struct super_block *sb, struct dentry *root,
}
int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops, int perm)
+ char const *name,
+ const struct file_operations *fops, int perm)
{
if (!__gatorfs_create_file(sb, root, name, fops, perm))
return -EFAULT;
@@ -198,7 +201,7 @@ int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
}
struct dentry *gatorfs_mkdir(struct super_block *sb,
- struct dentry *root, char const *name)
+ struct dentry *root, char const *name)
{
struct dentry *dentry;
struct inode *inode;
@@ -256,28 +259,29 @@ static int gatorfs_fill_super(struct super_block *sb, void *data, int silent)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
static int gatorfs_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+ int flags, const char *dev_name, void *data,
+ struct vfsmount *mnt)
{
return get_sb_single(fs_type, flags, data, gatorfs_fill_super, mnt);
}
#else
static struct dentry *gatorfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+ int flags, const char *dev_name, void *data)
{
return mount_nodev(fs_type, flags, data, gatorfs_fill_super);
}
#endif
static struct file_system_type gatorfs_type = {
- .owner = THIS_MODULE,
- .name = "gatorfs",
+ .owner = THIS_MODULE,
+ .name = "gatorfs",
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
- .get_sb = gatorfs_get_sb,
+ .get_sb = gatorfs_get_sb,
#else
- .mount = gatorfs_mount,
+ .mount = gatorfs_mount,
#endif
- .kill_sb = kill_litter_super,
+ .kill_sb = kill_litter_super,
};
int __init gatorfs_register(void)
diff --git a/driver/gator_main.c b/driver/gator_main.c
index a2d8ef0..9e031c1 100644
--- a/driver/gator_main.c
+++ b/driver/gator_main.c
@@ -7,7 +7,7 @@
*
*/
-static unsigned long gator_protocol_version = 11;
+static unsigned long gator_protocol_version = 12;
#include <linux/slab.h>
#include <linux/cpu.h>
@@ -48,9 +48,9 @@ static unsigned long gator_protocol_version = 11;
#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT))
#ifndef CONFIG_PERF_EVENTS
-#warning gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters
+#error gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters
#elif !defined CONFIG_HW_PERF_EVENTS
-#warning gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters
+#error gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters
#endif
#endif
@@ -60,12 +60,12 @@ static unsigned long gator_protocol_version = 11;
#define SUMMARY_BUFFER_SIZE (1*1024)
#define BACKTRACE_BUFFER_SIZE (128*1024)
#define NAME_BUFFER_SIZE (64*1024)
-#define COUNTER_BUFFER_SIZE (64*1024) // counters have the core as part of the data and the core value in the frame header may be discarded
+#define COUNTER_BUFFER_SIZE (64*1024) // counters have the core as part of the data and the core value in the frame header may be discarded
#define BLOCK_COUNTER_BUFFER_SIZE (128*1024)
-#define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded
+#define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded
#define SCHED_TRACE_BUFFER_SIZE (128*1024)
-#define GPU_TRACE_BUFFER_SIZE (64*1024) // gpu trace counters have the core as part of the data and the core value in the frame header may be discarded
-#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded
+#define GPU_TRACE_BUFFER_SIZE (64*1024) // gpu trace counters have the core as part of the data and the core value in the frame header may be discarded
+#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded
#define NO_COOKIE 0U
#define INVALID_COOKIE ~0U
@@ -94,7 +94,6 @@ static unsigned long gator_protocol_version = 11;
#define MAXSIZE_PACK32 5
#define MAXSIZE_PACK64 10
-#define MAXSIZE_CORE_NAME 32
#if defined(__arm__)
#define PC_REG regs->ARM_pc
@@ -121,6 +120,7 @@ enum {
* Globals
******************************************************************************/
static unsigned long gator_cpu_cores;
+// Size of the largest buffer. Effectively constant, set in gator_op_create_files
static unsigned long userspace_buffer_size;
static unsigned long gator_backtrace_depth;
@@ -148,15 +148,23 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
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);
+static void gator_add_sample(int cpu, struct pt_regs *const regs);
static uint64_t gator_get_time(void);
+// Size of the buffer, must be a power of 2. Effectively constant, set in gator_op_setup.
static uint32_t gator_buffer_size[NUM_GATOR_BUFS];
+// gator_buffer_size - 1, bitwise and with pos to get offset into the array. Effectively constant, set in gator_op_setup.
static uint32_t gator_buffer_mask[NUM_GATOR_BUFS];
+// Read position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are read by userspace in userspace_buffer_read
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_read);
+// Write position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are written to the buffer
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_write);
+// Commit position in the buffer. Initialized to zero in gator_op_setup and incremented after a frame is ready to be read by userspace
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_commit);
+// If set to false, decreases the number of bytes returned by buffer_bytes_available. Set in buffer_check_space if no space is remaining. Initialized to true in gator_op_setup
+// This means that if we run out of space, continue to report that no space is available until bytes are read by userspace
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], buffer_space_available);
+// The buffer. Allocated in gator_op_setup
static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
/******************************************************************************
@@ -177,9 +185,125 @@ static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
/******************************************************************************
* Misc
******************************************************************************/
-#if defined(__arm__) || defined(__aarch64__)
+
+struct gator_cpu gator_cpus[] = {
+ {
+ .cpuid = ARM1136,
+ .core_name = "ARM1136",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM1156,
+ .core_name = "ARM1156",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM1176,
+ .core_name = "ARM1176",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM11MPCORE,
+ .core_name = "ARM11MPCore",
+ .pmnc_name = "ARM_ARM11MPCore",
+ .pmnc_counters = 3,
+ },
+ {
+ .cpuid = CORTEX_A5,
+ .core_name = "Cortex-A5",
+ .pmnc_name = "ARM_Cortex-A5",
+ .pmnc_counters = 2,
+ },
+ {
+ .cpuid = CORTEX_A7,
+ .core_name = "Cortex-A7",
+ .pmnc_name = "ARM_Cortex-A7",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A8,
+ .core_name = "Cortex-A8",
+ .pmnc_name = "ARM_Cortex-A8",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A9,
+ .core_name = "Cortex-A9",
+ .pmnc_name = "ARM_Cortex-A9",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = CORTEX_A15,
+ .core_name = "Cortex-A15",
+ .pmnc_name = "ARM_Cortex-A15",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = SCORPION,
+ .core_name = "Scorpion",
+ .pmnc_name = "Scorpion",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = SCORPIONMP,
+ .core_name = "ScorpionMP",
+ .pmnc_name = "ScorpionMP",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAITSIM,
+ .core_name = "KraitSIM",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAIT,
+ .core_name = "Krait",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAIT_S4_PRO,
+ .core_name = "Krait S4 Pro",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A53,
+ .core_name = "Cortex-A53",
+ .pmnc_name = "ARM_Cortex-A53",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = CORTEX_A57,
+ .core_name = "Cortex-A57",
+ .pmnc_name = "ARM_Cortex-A57",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = AARCH64,
+ .core_name = "AArch64",
+ .pmnc_name = "ARM_AArch64",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = OTHER,
+ .core_name = "Other",
+ .pmnc_name = "Other",
+ .pmnc_counters = 6,
+ },
+ {}
+};
+
u32 gator_cpuid(void)
{
+#if defined(__arm__) || defined(__aarch64__)
u32 val;
#if !defined(__aarch64__)
asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val));
@@ -187,8 +311,10 @@ u32 gator_cpuid(void)
asm volatile("mrs %0, midr_el1" : "=r" (val));
#endif
return (val >> 4) & 0xfff;
-}
+#else
+ return OTHER;
#endif
+}
static void gator_buffer_wake_up(unsigned long data)
{
@@ -198,7 +324,7 @@ static void gator_buffer_wake_up(unsigned long data)
/******************************************************************************
* Commit interface
******************************************************************************/
-static bool buffer_commit_ready(int* cpu, int* buftype)
+static bool buffer_commit_ready(int *cpu, int *buftype)
{
int cpu_x, x;
for_each_present_cpu(cpu_x) {
@@ -265,7 +391,7 @@ static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int le
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];
+ char *buffer = per_cpu(gator_buffer, cpu)[buftype];
for (i = 0; i < len; i++) {
buffer[write] = x[i];
@@ -282,55 +408,27 @@ static void gator_buffer_write_string(int cpu, int buftype, const char *x)
gator_buffer_write_bytes(cpu, buftype, x, len);
}
-static void gator_buffer_header(int cpu, int buftype)
-{
- int frame;
-
- 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;
- }
-
- if (per_cpu(gator_buffer, cpu)[buftype]) {
- marshal_frame(cpu, buftype, frame);
- }
-}
-
static void gator_commit_buffer(int cpu, int buftype)
{
+ 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(int);
+ for (byte = 0; byte < sizeof(int); 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];
- gator_buffer_header(cpu, buftype);
+ 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
mod_timer(&gator_buffer_wake_up_timer, jiffies + 1);
@@ -359,7 +457,7 @@ static void gator_add_trace(int cpu, unsigned long address)
marshal_backtrace(offset & ~1, cookie);
}
-static void gator_add_sample(int cpu, struct pt_regs * const regs)
+static void gator_add_sample(int cpu, struct pt_regs *const regs)
{
bool inKernel;
unsigned long exec_cookie;
@@ -392,11 +490,11 @@ static void gator_add_sample(int cpu, struct pt_regs * const regs)
******************************************************************************/
static void gator_timer_interrupt(void)
{
- struct pt_regs * const regs = get_irq_regs();
+ struct pt_regs *const regs = get_irq_regs();
gator_backtrace_handler(regs);
}
-void gator_backtrace_handler(struct pt_regs * const regs)
+void gator_backtrace_handler(struct pt_regs *const regs)
{
int cpu = smp_processor_id();
@@ -412,11 +510,11 @@ void gator_backtrace_handler(struct pt_regs * const regs)
static int gator_running;
// This function runs in interrupt context and on the appropriate core
-static void gator_timer_offline(void* unused)
+static void gator_timer_offline(void *unused)
{
struct gator_interface *gi;
int i, len, cpu = smp_processor_id();
- int* buffer;
+ int *buffer;
gator_trace_sched_offline();
gator_trace_power_offline();
@@ -444,8 +542,8 @@ static void gator_timer_offline_dispatch(int cpu)
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list)
- if (gi->offline_dispatch)
- gi->offline_dispatch(cpu);
+ if (gi->offline_dispatch)
+ gi->offline_dispatch(cpu);
}
static void gator_timer_stop(void)
@@ -464,11 +562,11 @@ static void gator_timer_stop(void)
}
// This function runs in interrupt context and on the appropriate core
-static void gator_timer_online(void* unused)
+static void gator_timer_online(void *unused)
{
struct gator_interface *gi;
int len, cpu = smp_processor_id();
- int* buffer;
+ int *buffer;
gator_trace_power_online();
@@ -485,25 +583,15 @@ static void gator_timer_online(void* unused)
gator_hrtimer_online(cpu);
#if defined(__arm__) || defined(__aarch64__)
{
- const char * core_name = NULL;
-
- // String lengths must be less than MAXSIZE_CORE_NAME
- switch (gator_cpuid()) {
- case ARM1136: core_name = "ARM1136"; break;
- case ARM1156: core_name = "ARM1156"; break;
- case ARM1176: core_name = "ARM1176"; break;
- case ARM11MPCORE: core_name = "ARM11MPCore"; break;
- case CORTEX_A5: core_name = "Cortex-A5"; break;
- case CORTEX_A7: core_name = "Cortex-A7"; break;
- case CORTEX_A8: core_name = "Cortex-A8"; break;
- case CORTEX_A9: core_name = "Cortex-A9"; break;
- case CORTEX_A15: core_name = "Cortex-A15"; break;
- case SCORPION: core_name = "Scorpion"; break;
- case SCORPIONMP: core_name = "ScorpionMP"; break;
- case KRAITSIM: core_name = "KraitSIM"; break;
- case KRAIT: core_name = "Krait"; break;
- case AARCH64: core_name = "AArch64"; break;
- default: core_name = "Unknown"; break;
+ const char *core_name = "Unknown";
+ const u32 cpuid = gator_cpuid();
+ int i;
+
+ for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
+ if (gator_cpus[i].cpuid == cpuid) {
+ core_name = gator_cpus[i].core_name;
+ break;
+ }
}
marshal_core_name(core_name);
@@ -517,8 +605,8 @@ static void gator_timer_online_dispatch(int cpu)
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list)
- if (gi->online_dispatch)
- gi->online_dispatch(cpu);
+ if (gi->online_dispatch)
+ gi->online_dispatch(cpu);
}
int gator_timer_start(unsigned long sample_rate)
@@ -563,16 +651,16 @@ static int __cpuinit gator_hotcpu_notify(struct notifier_block *self, unsigned l
long cpu = (long)hcpu;
switch (action) {
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- smp_call_function_single(cpu, gator_timer_offline, NULL, 1);
- gator_timer_offline_dispatch(cpu);
- break;
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- gator_timer_online_dispatch(cpu);
- smp_call_function_single(cpu, gator_timer_online, NULL, 1);
- break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ smp_call_function_single(cpu, gator_timer_offline, NULL, 1);
+ gator_timer_offline_dispatch(cpu);
+ break;
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ gator_timer_online_dispatch(cpu);
+ smp_call_function_single(cpu, gator_timer_online, NULL, 1);
+ break;
}
return NOTIFY_OK;
@@ -589,24 +677,24 @@ static int gator_pm_notify(struct notifier_block *nb, unsigned long event, void
int cpu;
switch (event) {
- case PM_HIBERNATION_PREPARE:
- case PM_SUSPEND_PREPARE:
- unregister_hotcpu_notifier(&gator_hotcpu_notifier);
- unregister_scheduler_tracepoints();
- on_each_cpu(gator_timer_offline, NULL, 1);
- for_each_online_cpu(cpu) {
- gator_timer_offline_dispatch(cpu);
- }
- break;
- case PM_POST_HIBERNATION:
- case PM_POST_SUSPEND:
- for_each_online_cpu(cpu) {
- gator_timer_online_dispatch(cpu);
- }
- on_each_cpu(gator_timer_online, NULL, 1);
- register_scheduler_tracepoints();
- register_hotcpu_notifier(&gator_hotcpu_notifier);
- break;
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ unregister_hotcpu_notifier(&gator_hotcpu_notifier);
+ unregister_scheduler_tracepoints();
+ on_each_cpu(gator_timer_offline, NULL, 1);
+ for_each_online_cpu(cpu) {
+ gator_timer_offline_dispatch(cpu);
+ }
+ break;
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ for_each_online_cpu(cpu) {
+ gator_timer_online_dispatch(cpu);
+ }
+ on_each_cpu(gator_timer_online, NULL, 1);
+ register_scheduler_tracepoints();
+ register_hotcpu_notifier(&gator_hotcpu_notifier);
+ break;
}
return NOTIFY_OK;
@@ -676,6 +764,15 @@ static int gator_init(void)
return 0;
}
+static void gator_exit(void)
+{
+ struct gator_interface *gi;
+
+ list_for_each_entry(gi, &gator_events, list)
+ if (gi->shutdown)
+ gi->shutdown();
+}
+
static int gator_start(void)
{
unsigned long cpu, i;
@@ -684,7 +781,7 @@ static int gator_start(void)
// Initialize the buffer with the frame type and core
for_each_present_cpu(cpu) {
for (i = 0; i < NUM_GATOR_BUFS; i++) {
- gator_buffer_header(cpu, i);
+ marshal_frame(cpu, i);
}
}
@@ -741,8 +838,8 @@ annotate_failure:
cookies_failure:
// stop all events
list_for_each_entry(gi, &gator_events, list)
- if (gi->stop)
- gi->stop();
+ if (gi->stop)
+ gi->stop();
events_failure:
return -1;
@@ -758,13 +855,13 @@ static void gator_stop(void)
gator_trace_gpu_stop();
// stop all interrupt callback reads before tearing down other interfaces
- gator_notifier_stop(); // should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined
+ gator_notifier_stop(); // should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined
gator_timer_stop();
// stop all events
list_for_each_entry(gi, &gator_events, list)
- if (gi->stop)
- gi->stop();
+ if (gi->stop)
+ gi->stop();
}
/******************************************************************************
@@ -941,8 +1038,8 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co
}
static const struct file_operations enable_fops = {
- .read = enable_read,
- .write = enable_write,
+ .read = enable_read,
+ .write = enable_write,
};
static int userspace_buffer_open(struct inode *inode, struct file *file)
@@ -978,10 +1075,10 @@ static int userspace_buffer_release(struct inode *inode, struct file *file)
}
static ssize_t userspace_buffer_read(struct file *file, char __user *buf,
- size_t count, loff_t *offset)
+ size_t count, loff_t *offset)
{
int retval = -EINVAL;
- int commit = 0, length, length1, length2, read, byte, type_length;
+ int commit = 0, length1, length2, read;
char *buffer1;
char *buffer2 = NULL;
int cpu, buftype;
@@ -1026,13 +1123,6 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf,
length2 = commit;
}
- // 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;
- length = length1 + length2 - type_length - sizeof(int);
- for (byte = 0; byte < sizeof(int); byte++) {
- per_cpu(gator_buffer, cpu)[buftype][(read + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;
- }
-
/* start, middle or end */
if (length1 > 0) {
if (copy_to_user(&buf[0], buffer1, length1)) {
@@ -1059,15 +1149,14 @@ out:
}
const struct file_operations gator_event_buffer_fops = {
- .open = userspace_buffer_open,
- .release = userspace_buffer_release,
- .read = userspace_buffer_read,
+ .open = userspace_buffer_open,
+ .release = userspace_buffer_release,
+ .read = userspace_buffer_read,
};
static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
- return gatorfs_ulong_to_user(gator_backtrace_depth, buf, count,
- offset);
+ return gatorfs_ulong_to_user(gator_backtrace_depth, buf, count, offset);
}
static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
@@ -1090,8 +1179,8 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou
}
static const struct file_operations depth_fops = {
- .read = depth_read,
- .write = depth_write
+ .read = depth_read,
+ .write = depth_write
};
void gator_op_create_files(struct super_block *sb, struct dentry *root)
@@ -1105,7 +1194,7 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root)
for_each_present_cpu(cpu) {
gator_cpu_cores++;
}
- userspace_buffer_size = BACKTRACE_BUFFER_SIZE;
+ userspace_buffer_size = BACKTRACE_BUFFER_SIZE;
gator_response_type = 1;
gatorfs_create_file(sb, root, "enable", &enable_fops);
@@ -1123,8 +1212,8 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root)
// Linux Events
dir = gatorfs_mkdir(sb, root, "events");
list_for_each_entry(gi, &gator_events, list)
- if (gi->create_files)
- gi->create_files(sb, dir);
+ if (gi->create_files)
+ gi->create_files(sb, dir);
// Power interface
gator_trace_power_create_files(sb, dir);
@@ -1153,6 +1242,7 @@ static void __exit gator_module_exit(void)
{
del_timer_sync(&gator_buffer_wake_up_timer);
tracepoint_synchronize_unregister();
+ gator_exit();
gatorfs_unregister();
}
diff --git a/driver/gator_marshaling.c b/driver/gator_marshaling.c
index a84b280..b2efdd2 100644
--- a/driver/gator_marshaling.c
+++ b/driver/gator_marshaling.c
@@ -7,49 +7,52 @@
*
*/
-static void marshal_summary(long long timestamp, long long uptime) {
+static void marshal_summary(long long timestamp, long long uptime)
+{
int cpu = 0;
gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
buffer_check(cpu, SUMMARY_BUF);
}
-static bool marshal_cookie_header(char* text) {
+static bool marshal_cookie_header(const char *text)
+{
int cpu = smp_processor_id();
- return buffer_check_space(cpu, NAME_BUF, strlen(text) + 2*MAXSIZE_PACK32);
+ return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
}
-static void marshal_cookie(int cookie, char* text) {
+static void marshal_cookie(int cookie, const char *text)
+{
int cpu = smp_processor_id();
- // TODO(dreric01) How long can the string be?
- if (buffer_check_space(cpu, NAME_BUF, 2*MAXSIZE_PACK32)) {
- gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
- gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
- gator_buffer_write_string(cpu, NAME_BUF, text);
- }
+ // buffer_check_space already called by marshal_cookie_header
+ gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
+ gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
+ gator_buffer_write_string(cpu, NAME_BUF, text);
buffer_check(cpu, NAME_BUF);
}
-static void marshal_thread_name(int pid, char* name) {
+static void marshal_thread_name(int pid, char *name)
+{
unsigned long flags, cpu;
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 2*MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
+ if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
gator_buffer_write_packed_int64(cpu, NAME_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
gator_buffer_write_string(cpu, NAME_BUF, name);
}
- local_irq_restore(flags);
buffer_check(cpu, NAME_BUF);
+ local_irq_restore(flags);
}
-static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel) {
+static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
+{
int cpu = smp_processor_id();
- if (buffer_check_space(cpu, BACKTRACE_BUF, gator_backtrace_depth*2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, gator_get_time());
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, tgid);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
return true;
@@ -61,13 +64,15 @@ static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inK
return false;
}
-static void marshal_backtrace(unsigned long address, int cookie) {
+static void marshal_backtrace(unsigned long address, int cookie)
+{
int cpu = smp_processor_id();
- gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
+ gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
}
-static void marshal_backtrace_footer(void) {
+static void marshal_backtrace_footer(void)
+{
int cpu = smp_processor_id();
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
@@ -75,30 +80,31 @@ static void marshal_backtrace_footer(void) {
buffer_check(cpu, BACKTRACE_BUF);
}
-static bool marshal_event_header(void) {
+static bool marshal_event_header(void)
+{
unsigned long flags, cpu = smp_processor_id();
bool retval = false;
-
+
local_irq_save(flags);
if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
- gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
+ gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, gator_get_time());
retval = true;
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
return retval;
}
-static void marshal_event(int len, int* buffer) {
+static void marshal_event(int len, int *buffer)
+{
unsigned long i, flags, cpu = smp_processor_id();
if (len <= 0)
return;
-
+
// length must be even since all data is a (key, value) pair
if (len & 0x1) {
pr_err("gator: invalid counter data detected and discarded");
@@ -106,27 +112,26 @@ static void marshal_event(int len, int* buffer) {
}
// events must be written in key,value pairs
+ local_irq_save(flags);
for (i = 0; i < len; i += 2) {
- local_irq_save(flags);
- if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2*MAXSIZE_PACK32)) {
- local_irq_restore(flags);
+ if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
break;
}
gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
- local_irq_restore(flags);
}
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
}
-static void marshal_event64(int len, long long* buffer64) {
+static void marshal_event64(int len, long long *buffer64)
+{
unsigned long i, flags, cpu = smp_processor_id();
if (len <= 0)
return;
-
+
// length must be even since all data is a (key, value) pair
if (len & 0x1) {
pr_err("gator: invalid counter data detected and discarded");
@@ -134,48 +139,47 @@ static void marshal_event64(int len, long long* buffer64) {
}
// events must be written in key,value pairs
+ local_irq_save(flags);
for (i = 0; i < len; i += 2) {
- local_irq_save(flags);
- if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2*MAXSIZE_PACK64)) {
- local_irq_restore(flags);
+ if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
break;
}
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
- local_irq_restore(flags);
}
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
}
#if GATOR_CPU_FREQ_SUPPORT
-static void marshal_event_single(int core, int key, int value) {
+static void marshal_event_single(int core, int key, int value)
+{
unsigned long flags, cpu;
-
+
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int64(cpu, COUNTER_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
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);
+ local_irq_restore(flags);
}
#endif
-static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid) {
+static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
@@ -183,39 +187,39 @@ 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);
+ local_irq_restore(flags);
}
-static void marshal_sched_gpu_stop(int unit, int core) {
+static void marshal_sched_gpu_stop(int unit, int core)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
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);
+ local_irq_restore(flags);
}
-static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state) {
+static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
@@ -223,49 +227,88 @@ 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);
+ local_irq_restore(flags);
}
-static void marshal_sched_trace_exit(int tgid, int pid) {
+static void marshal_sched_trace_exit(int tgid, int pid)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_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);
+ local_irq_restore(flags);
}
#if GATOR_CPU_FREQ_SUPPORT
-static void marshal_idle(int core, int state) {
+static void marshal_idle(int core, int state)
+{
unsigned long flags, cpu;
-
+
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
gator_buffer_write_packed_int64(cpu, IDLE_BUF, gator_get_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);
+ local_irq_restore(flags);
}
#endif
-static void marshal_frame(int cpu, int buftype, int frame) {
+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);
@@ -280,7 +323,8 @@ static void marshal_frame(int cpu, int buftype, int frame) {
}
#if defined(__arm__) || defined(__aarch64__)
-static void marshal_core_name(const char* name) {
+static void marshal_core_name(const char *name)
+{
int cpu = smp_processor_id();
unsigned long flags;
local_irq_save(flags);
@@ -288,8 +332,7 @@ static void marshal_core_name(const char* name) {
gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
gator_buffer_write_string(cpu, NAME_BUF, name);
}
- local_irq_restore(flags);
-
buffer_check(cpu, NAME_BUF);
+ local_irq_restore(flags);
}
#endif
diff --git a/driver/gator_pack.c b/driver/gator_pack.c
index 5ad53db..119746b 100644
--- a/driver/gator_pack.c
+++ b/driver/gator_pack.c
@@ -21,23 +21,23 @@ static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x)
} else if ((x & 0xffffc000) == 0) {
int write2 = (write + 2) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) & 0x7f;
+ buffer[write1] = (x >> 7) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write2;
} else if ((x & 0xffe00000) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write3;
} else if ((x & 0xf0000000) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
int write4 = (write + 4) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write4;
} else {
int write2 = (write + 2) & mask;
@@ -45,10 +45,10 @@ static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x)
int write4 = (write + 4) & mask;
int write5 = (write + 5) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) & 0x0f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) & 0x0f;
per_cpu(gator_buffer_write, cpu)[buftype] = write5;
}
}
@@ -67,23 +67,23 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
} else if ((x & 0xffffffffffffc000LL) == 0) {
int write2 = (write + 2) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) & 0x7f;
+ buffer[write1] = (x >> 7) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write2;
} else if ((x & 0xffffffffffe00000LL) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write3;
} else if ((x & 0xfffffffff0000000LL) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
int write4 = (write + 4) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write4;
} else if ((x & 0xfffffff800000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -91,10 +91,10 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write4 = (write + 4) & mask;
int write5 = (write + 5) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write5;
} else if ((x & 0xfffffc0000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -103,11 +103,11 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write5 = (write + 5) & mask;
int write6 = (write + 6) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write6;
} else if ((x & 0xfffe000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -117,12 +117,12 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write6 = (write + 6) & mask;
int write7 = (write + 7) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write7;
} else if ((x & 0xff00000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -133,13 +133,13 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write7 = (write + 7) & mask;
int write8 = (write + 8) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write8;
} else if ((x & 0x8000000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -151,14 +151,14 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write8 = (write + 8) & mask;
int write9 = (write + 9) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) | 0x80;
- buffer[write8] = (x>>56) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) | 0x80;
+ buffer[write8] = (x >> 56) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write9;
} else {
int write2 = (write + 2) & mask;
@@ -171,15 +171,15 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write9 = (write + 9) & mask;
int write10 = (write + 10) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) | 0x80;
- buffer[write8] = (x>>56) | 0x80;
- buffer[write9] = (x>>63) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) | 0x80;
+ buffer[write8] = (x >> 56) | 0x80;
+ buffer[write9] = (x >> 63) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write10;
}
}
diff --git a/driver/gator_trace_gpu.c b/driver/gator_trace_gpu.c
index 0511d71..9fc488b 100644
--- a/driver/gator_trace_gpu.c
+++ b/driver/gator_trace_gpu.c
@@ -27,7 +27,6 @@
#define EVENT_TYPE_SUSPEND 3
#define EVENT_TYPE_RESUME 4
-
/* Note whether tracepoints have been registered */
static int mali_timeline_trace_registered;
static int mali_job_slots_trace_registered;
@@ -49,34 +48,33 @@ static int gpu_trace_registered;
*/
enum {
EVENT_CHANNEL_SOFTWARE = 0,
- EVENT_CHANNEL_VP0 = 1,
- EVENT_CHANNEL_FP0 = 5,
- EVENT_CHANNEL_FP1,
- EVENT_CHANNEL_FP2,
- EVENT_CHANNEL_FP3,
- EVENT_CHANNEL_FP4,
- EVENT_CHANNEL_FP5,
- EVENT_CHANNEL_FP6,
- EVENT_CHANNEL_FP7,
- EVENT_CHANNEL_GPU = 21
+ EVENT_CHANNEL_VP0 = 1,
+ EVENT_CHANNEL_FP0 = 5,
+ EVENT_CHANNEL_FP1,
+ EVENT_CHANNEL_FP2,
+ EVENT_CHANNEL_FP3,
+ EVENT_CHANNEL_FP4,
+ EVENT_CHANNEL_FP5,
+ EVENT_CHANNEL_FP6,
+ EVENT_CHANNEL_FP7,
+ EVENT_CHANNEL_GPU = 21
};
/**
* These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
*/
enum {
- EVENT_REASON_SINGLE_GPU_NONE = 0,
- EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
+ EVENT_REASON_SINGLE_GPU_NONE = 0,
+ EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
};
-
GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4))
{
unsigned int component, state;
// do as much work as possible before disabling interrupts
- component = (event_id >> 16) & 0xFF; // component is an 8-bit field
- state = (event_id >> 24) & 0xF; // state is a 4-bit field
+ component = (event_id >> 16) & 0xFF; // component is an 8-bit field
+ state = (event_id >> 24) & 0xF; // state is a 4-bit field
switch (state) {
case EVENT_TYPE_START:
@@ -101,7 +99,7 @@ GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned
if (component == EVENT_CHANNEL_GPU) {
unsigned int reason = (event_id & 0xffff);
- if(reason == EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE) {
+ if (reason == EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE) {
gator_events_mali_log_dvfs_event(d0, d1);
}
}
@@ -118,11 +116,10 @@ GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigne
{
unsigned int component, state, unit;
- component = (event_id >> 16) & 0xFF; // component is an 8-bit field
- state = (event_id >> 24) & 0xF; // state is a 4-bit field
+ component = (event_id >> 16) & 0xFF; // component is an 8-bit field
+ state = (event_id >> 24) & 0xF; // state is a 4-bit field
- switch (component)
- {
+ switch (component) {
case 0:
unit = GPU_UNIT_FP;
break;
@@ -136,9 +133,8 @@ GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigne
unit = GPU_UNIT_NONE;
}
- if (unit != GPU_UNIT_NONE)
- {
- switch(state) {
+ if (unit != GPU_UNIT_NONE) {
+ switch (state) {
case EVENT_TYPE_START:
marshal_sched_gpu_start(unit, 0, tgid, (pid != 0 ? pid : tgid));
break;
@@ -175,27 +171,27 @@ int gator_trace_gpu_start(void)
gpu_trace_registered = mali_timeline_trace_registered = mali_job_slots_trace_registered = 0;
#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
- if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
- mali_timeline_trace_registered = 1;
- }
+ if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
+ mali_timeline_trace_registered = 1;
+ }
#endif
#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
- if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
- mali_job_slots_trace_registered = 1;
- }
+ if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
+ mali_job_slots_trace_registered = 1;
+ }
#endif
- if (!mali_timeline_trace_registered) {
- if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
- return 0;
- }
- if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
- GATOR_UNREGISTER_TRACE(gpu_activity_start);
- return 0;
- }
- gpu_trace_registered = 1;
- }
+ if (!mali_timeline_trace_registered) {
+ if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
+ return 0;
+ }
+ if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
+ GATOR_UNREGISTER_TRACE(gpu_activity_start);
+ return 0;
+ }
+ gpu_trace_registered = 1;
+ }
return 0;
}
diff --git a/driver/gator_trace_gpu.h b/driver/gator_trace_gpu.h
index 894289b..efb47c6 100644
--- a/driver/gator_trace_gpu.h
+++ b/driver/gator_trace_gpu.h
@@ -28,50 +28,50 @@
*/
TRACE_EVENT(gpu_activity_start,
- TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p),
+ TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p),
- TP_ARGS(gpu_unit, gpu_core, p),
+ TP_ARGS(gpu_unit, gpu_core, p),
- TP_STRUCT__entry(
- __field( int, gpu_unit )
- __field( int, gpu_core )
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- ),
+ TP_STRUCT__entry(
+ __field(int, gpu_unit)
+ __field(int, gpu_core)
+ __array(char, comm, TASK_COMM_LEN)
+ __field(pid_t, pid)
+ ),
- TP_fast_assign(
- __entry->gpu_unit = gpu_unit;
- __entry->gpu_core = gpu_core;
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
- ),
+ TP_fast_assign(
+ __entry->gpu_unit = gpu_unit;
+ __entry->gpu_core = gpu_core;
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ ),
- TP_printk("unit=%d core=%d comm=%s pid=%d",
- __entry->gpu_unit, __entry->gpu_core, __entry->comm, __entry->pid)
-);
+ TP_printk("unit=%d core=%d comm=%s pid=%d",
+ __entry->gpu_unit, __entry->gpu_core, __entry->comm,
+ __entry->pid)
+ );
/*
* Tracepoint for calling GPU unit stop activity on core
*/
TRACE_EVENT(gpu_activity_stop,
- TP_PROTO(int gpu_unit, int gpu_core),
+ TP_PROTO(int gpu_unit, int gpu_core),
- TP_ARGS(gpu_unit, gpu_core),
+ TP_ARGS(gpu_unit, gpu_core),
- TP_STRUCT__entry(
- __field( int, gpu_unit )
- __field( int, gpu_core )
- ),
+ TP_STRUCT__entry(
+ __field(int, gpu_unit)
+ __field(int, gpu_core)
+ ),
- TP_fast_assign(
- __entry->gpu_unit = gpu_unit;
- __entry->gpu_core = gpu_core;
- ),
+ TP_fast_assign(
+ __entry->gpu_unit = gpu_unit;
+ __entry->gpu_core = gpu_core;
+ ),
- TP_printk("unit=%d core=%d",
- __entry->gpu_unit, __entry->gpu_core)
-);
+ TP_printk("unit=%d core=%d", __entry->gpu_unit, __entry->gpu_core)
+ );
#endif /* _TRACE_GPU_H */
diff --git a/driver/gator_trace_power.c b/driver/gator_trace_power.c
index b1687e1..79fa13c 100644
--- a/driver/gator_trace_power.c
+++ b/driver/gator_trace_power.c
@@ -9,8 +9,19 @@
#include <linux/cpufreq.h>
#include <trace/events/power.h>
+
+#if defined(__arm__)
+
#include <asm/mach-types.h>
+#define implements_wfi() (!machine_is_omap3_beagle())
+
+#else
+
+#define implements_wfi() false
+
+#endif
+
// cpu_frequency and cpu_idle trace points were introduced in Linux kernel v2.6.38
// the now deprecated power_frequency trace point was available prior to 2.6.38, but only for x86
#if GATOR_CPU_FREQ_SUPPORT
@@ -61,9 +72,9 @@ GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu))
return;
}
- if (!machine_is_omap3_beagle()) {
+ if (implements_wfi()) {
if (state == PWR_EVENT_EXIT) {
- // transition from wfi to non-wfi
+ // transition from wfi to non-wfi
marshal_idle(cpu, WFI_EXIT);
} else {
// transition from non-wfi to wfi
@@ -149,10 +160,29 @@ void gator_trace_power_init(void)
}
}
#else
-static int gator_trace_power_create_files(struct super_block *sb, struct dentry *root) {return 0;}
-static void gator_trace_power_online(void) {}
-static void gator_trace_power_offline(void) {}
-static int gator_trace_power_start(void) {return 0;}
-static void gator_trace_power_stop(void) {}
-void gator_trace_power_init(void) {}
+static int gator_trace_power_create_files(struct super_block *sb, struct dentry *root)
+{
+ return 0;
+}
+
+static void gator_trace_power_online(void)
+{
+}
+
+static void gator_trace_power_offline(void)
+{
+}
+
+static int gator_trace_power_start(void)
+{
+ return 0;
+}
+
+static void gator_trace_power_stop(void)
+{
+}
+
+void gator_trace_power_init(void)
+{
+}
#endif
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c
index 9ddb822..d0336f9 100644
--- a/driver/gator_trace_sched.c
+++ b/driver/gator_trace_sched.c
@@ -13,7 +13,7 @@
#define SCHED_SWITCH 1
#define SCHED_PROCESS_EXIT 2
-#define TASK_MAP_ENTRIES 1024 /* must be power of 2 */
+#define TASK_MAP_ENTRIES 1024 /* must be power of 2 */
#define TASK_MAX_COLLISIONS 2
static DEFINE_PER_CPU(uint64_t *, taskname_keys);
@@ -26,14 +26,14 @@ enum {
STATE_WAIT_ON_MUTEX,
};
-void emit_pid_name(struct task_struct* task)
+void emit_pid_name(struct task_struct *task)
{
bool found = false;
char taskcomm[TASK_COMM_LEN + 3];
unsigned long x, cpu = smp_processor_id();
uint64_t *keys = &(per_cpu(taskname_keys, cpu)[(task->pid & 0xFF) * TASK_MAX_COLLISIONS]);
uint64_t value;
-
+
value = gator_chksum_crc32(task->comm);
value = (value << 32) | (uint32_t)task->pid;
@@ -64,7 +64,6 @@ void emit_pid_name(struct task_struct* task)
}
}
-
static void collect_counters(void)
{
int *buffer, len;
@@ -84,7 +83,7 @@ static void collect_counters(void)
}
}
-static void probe_sched_write(int type, struct task_struct* task, struct task_struct* old_task)
+static void probe_sched_write(int type, struct task_struct *task, struct task_struct *old_task)
{
int cookie = 0, state = 0;
int cpu = smp_processor_id();
@@ -141,7 +140,14 @@ GATOR_DEFINE_PROBE(sched_process_exit, TP_PROTO(struct task_struct *p))
probe_sched_write(SCHED_PROCESS_EXIT, p, 0);
}
-static int register_scheduler_tracepoints(void) {
+static void do_nothing(void *info)
+{
+ // Intentionally do nothing
+ (void)info;
+}
+
+static int register_scheduler_tracepoints(void)
+{
// register tracepoints
if (GATOR_REGISTER_TRACE(sched_switch))
goto fail_sched_switch;
@@ -149,6 +155,10 @@ static int register_scheduler_tracepoints(void) {
goto fail_sched_process_exit;
pr_debug("gator: registered tracepoints\n");
+ // Now that the scheduler tracepoint is registered, force a context switch
+ // on all cpus to capture what is currently running.
+ on_each_cpu(do_nothing, NULL, 0);
+
return 0;
// unregister tracepoints on error
@@ -166,7 +176,7 @@ int gator_trace_sched_start(void)
for_each_present_cpu(cpu) {
size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t);
- per_cpu(taskname_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(taskname_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(taskname_keys, cpu))
return -1;
memset(per_cpu(taskname_keys, cpu), 0, size);