aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@arm.com>2011-03-14 15:22:44 +0000
committerPawel Moll <pawel.moll@arm.com>2011-03-14 15:22:44 +0000
commit438a1e1cbf4b99b4f6ff1ecf07f9b7cfcc20d517 (patch)
tree844b0b30da7b0653eb5a0d0408b45c86f1e494ea
parent4b1652908140265b28795a529b73ebb41d690c15 (diff)
gator: ARM DS-5.4 Streamline gator driverDS-5.4
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
-rw-r--r--Makefile3
-rw-r--r--README_Streamline.txt36
-rw-r--r--gator.h34
-rw-r--r--gator_annotate.c2
-rw-r--r--gator_backtrace.c2
-rw-r--r--gator_cookies.c16
-rw-r--r--gator_events.c5
-rw-r--r--gator_events_armv6.c41
-rw-r--r--gator_events_armv7.c32
-rw-r--r--gator_events_block.c12
-rw-r--r--gator_events_irq.c20
-rw-r--r--gator_events_meminfo.c10
-rw-r--r--gator_events_net.c176
-rw-r--r--gator_events_sched.c11
-rw-r--r--gator_main.c377
-rw-r--r--gator_trace_sched.c14
16 files changed, 489 insertions, 302 deletions
diff --git a/Makefile b/Makefile
index 8e679a7..0583ae3 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ gator-objs := gator_main.o \
gator_events_armv7.o \
gator_events_irq.o \
gator_events_sched.o \
+ gator_events_net.o \
gator_events_block.o \
gator_events_meminfo.o
@@ -20,6 +21,6 @@ all:
$(error)
clean:
- rm -f *.o .*.cmd */*.o */.*.cmd modules.order Module.symvers gator.ko gator.mod.c
+ rm -f *.o modules.order Module.symvers gator.ko gator.mod.c
endif
diff --git a/README_Streamline.txt b/README_Streamline.txt
index 4c52b7d..4688474 100644
--- a/README_Streamline.txt
+++ b/README_Streamline.txt
@@ -76,42 +76,6 @@ vi rungator.sh
/path/to/gatord &
update-rc.d rungator.sh defaults
-*** Driver Sources ***
-
-Gator Sources
- backtrace.c
- cpu_buffer.c
- cpu_fifo.c
- cpu_fifo.h
- gator_annotate.c
- gator_events_irq.c
- gator_init.c
- gator_interrupt.c
- gator_pmnc_armv7.c
- gator_pmnc_none.c
- gator_schedtrace.c
- gator_setup.c
- gator_timer.c
- gator_traceprobe.h
-
-Oprofile Sources // function names updated to avoid Oprofile collisions
- buffer_sync.c
- buffer_sync.h
- cpu_buffer.h
- event_buffer.c
- event_buffer.h
- oprof.h
- oprofile.h
- oprofile_files.c
- oprofile_stats.c
- oprofile_stats.h
- timer_int.c
-
-Modified Oprofile Sources
- buffer_sync.c // modify sample contract to allow bad 'mm' or cookie
- oprofilefs.c // gatorfs and magic number
- oprof.c // updated module name and author
-
*** GPL License ***
For license information, please see the file LICENSE.
diff --git a/gator.h b/gator.h
index 87ca107..f0c95bf 100644
--- a/gator.h
+++ b/gator.h
@@ -6,6 +6,13 @@
* published by the Free Software Foundation.
*/
+#ifndef GATOR_H_
+#define GATOR_H_
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
/******************************************************************************
* Filesystem
******************************************************************************/
@@ -22,6 +29,27 @@ int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
char const *name, unsigned long *val);
/******************************************************************************
+ * Tracepoints
+ ******************************************************************************/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
+# error Kernels prior to 2.6.32 not supported
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+# define GATOR_DEFINE_PROBE(probe_name, proto) \
+ static void probe_##probe_name(PARAMS(proto))
+# define GATOR_REGISTER_TRACE(probe_name) \
+ register_trace_##probe_name(probe_##probe_name)
+# define GATOR_UNREGISTER_TRACE(probe_name) \
+ unregister_trace_##probe_name(probe_##probe_name)
+#else
+# define GATOR_DEFINE_PROBE(probe_name, proto) \
+ static void probe_##probe_name(void *data, PARAMS(proto))
+# define GATOR_REGISTER_TRACE(probe_name) \
+ register_trace_##probe_name(probe_##probe_name, NULL)
+# define GATOR_UNREGISTER_TRACE(probe_name) \
+ unregister_trace_##probe_name(probe_##probe_name, NULL)
+#endif
+
+/******************************************************************************
* Events
******************************************************************************/
struct __gator_interface {
@@ -29,6 +57,8 @@ struct __gator_interface {
int (*init)(int *key);
int (*start)(void);
void (*stop)(void);
+ void (*online)(void);
+ void (*offline)(void);
int (*read)(int **buffer);
struct __gator_interface *next;
};
@@ -36,3 +66,7 @@ struct __gator_interface {
typedef struct __gator_interface gator_interface;
int gator_event_install(int (*event_install)(gator_interface *));
+
+extern unsigned long gator_net_traffic;
+
+#endif // GATOR_H_
diff --git a/gator_annotate.c b/gator_annotate.c
index 1844157..56656f0 100644
--- a/gator_annotate.c
+++ b/gator_annotate.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/gator_backtrace.c b/gator_backtrace.c
index c4ddf41..628a18f 100644
--- a/gator_backtrace.c
+++ b/gator_backtrace.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/gator_cookies.c b/gator_cookies.c
index d267a57..4e39667 100644
--- a/gator_cookies.c
+++ b/gator_cookies.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,8 +11,6 @@
#define MAX_COLLISIONS 2
static DEFINE_PER_CPU(uint32_t, cookie_next_key);
-static DEFINE_PER_CPU(uint32_t, cookie_prev_text);
-static DEFINE_PER_CPU(uint32_t, cookie_prev_value);
static DEFINE_PER_CPU(uint64_t *, cookie_keys);
static DEFINE_PER_CPU(uint32_t *, cookie_values);
@@ -105,10 +103,6 @@ static inline uint32_t get_cookie(int cpu, int tgid, struct vm_area_struct *vma)
}
text = (char*)path->dentry->d_name.name;
- if (per_cpu (cookie_prev_text, cpu) == (uint32_t)text) {
- return per_cpu(cookie_prev_value, cpu);
- }
-
key = gator_chksum_crc32(text);
key = (key << 32) | (uint32_t)text;
@@ -125,8 +119,6 @@ static inline uint32_t get_cookie(int cpu, int tgid, struct vm_area_struct *vma)
gator_buffer_write_string(cpu, text);
output:
- per_cpu(cookie_prev_text, cpu) = (uint32_t)text;
- per_cpu(cookie_prev_value, cpu) = cookie;
return cookie;
}
@@ -187,10 +179,8 @@ static void cookies_initialize(void)
int cpu, size;
int i, j;
- for_each_possible_cpu(cpu) {
+ for_each_present_cpu(cpu) {
per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
- per_cpu(cookie_prev_text, cpu) = 0;
- per_cpu(cookie_prev_value, cpu) = 0;
size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t);
per_cpu(cookie_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL);
@@ -221,7 +211,7 @@ static void cookies_release(void)
{
int cpu;
- for_each_possible_cpu(cpu) {
+ for_each_present_cpu(cpu) {
kfree(per_cpu(cookie_keys, cpu));
per_cpu(cookie_keys, cpu) = NULL;
diff --git a/gator_events.c b/gator_events.c
index 1a5d0a0..d837257 100644
--- a/gator_events.c
+++ b/gator_events.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@ extern int gator_events_irq_install(gator_interface *gi);
extern int gator_events_sched_install(gator_interface *gi);
extern int gator_events_block_install(gator_interface *gi);
extern int gator_events_meminfo_install(gator_interface *gi);
+extern int gator_events_net_install(gator_interface *gi);
static int gator_events_install(void)
{
@@ -33,5 +34,7 @@ static int gator_events_install(void)
return -1;
if (gator_event_install(gator_events_meminfo_install))
return -1;
+ if (gator_event_install(gator_events_net_install))
+ return -1;
return 0;
}
diff --git a/gator_events_armv6.c b/gator_events_armv6.c
index a916d83..c571e44 100644
--- a/gator_events_armv6.c
+++ b/gator_events_armv6.c
@@ -1,17 +1,11 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/fs.h>
-
#include "gator.h"
#if defined(__arm__)
@@ -119,15 +113,13 @@ static int gator_events_armv6_init(int *key)
return 0;
}
-static void __gator_events_armv6_start(void* unused)
+static void gator_events_armv6_online(void)
{
unsigned int cnt;
u32 pmnc;
if (armv6_pmnc_read() & PMCR_E) {
- pr_err("gator: CPU%u PMNC still enabled when setup new event counter.\n", smp_processor_id());
- pmnc_count = 0;
- return;
+ armv6_pmnc_write(armv6_pmnc_read() & ~PMCR_E);
}
/* initialize PMNC, reset overflow, D bit, C bit and P bit. */
@@ -162,31 +154,24 @@ static void __gator_events_armv6_start(void* unused)
armv6_pmnc_write(pmnc | PMCR_E);
}
-static int gator_events_armv6_start(void)
-{
- if (!pmnc_count)
- return 0;
- return on_each_cpu(__gator_events_armv6_start, NULL, 1);
-}
-
-static void __gator_events_armv6_stop(void* unused)
+static void gator_events_armv6_offline(void)
{
unsigned int cnt;
armv6_pmnc_write(armv6_pmnc_read() & ~PMCR_E);
-
for (cnt = PMN0; cnt <= CCNT; cnt++) {
armv6_pmnc_reset_counter(cnt);
- pmnc_enabled[cnt] = 0;
- pmnc_event[cnt] = 0;
}
}
static void gator_events_armv6_stop(void)
{
- if (!pmnc_count)
- return;
- on_each_cpu(__gator_events_armv6_stop, NULL, 1);
+ unsigned int cnt;
+
+ for (cnt = PMN0; cnt <= CCNT; cnt++) {
+ pmnc_enabled[cnt] = 0;
+ pmnc_event[cnt] = 0;
+ }
}
static int gator_events_armv6_read(int **buffer)
@@ -194,9 +179,6 @@ static int gator_events_armv6_read(int **buffer)
int cnt, len = 0;
int cpu = raw_smp_processor_id();
- if (!pmnc_count)
- return 0;
-
for (cnt = PMN0; cnt <= CCNT; cnt++) {
if (pmnc_enabled[cnt]) {
u32 value = 0;
@@ -242,8 +224,9 @@ int gator_events_armv6_install(gator_interface *gi) {
gi->create_files = gator_events_armv6_create_files;
gi->init = gator_events_armv6_init;
- gi->start = gator_events_armv6_start;
gi->stop = gator_events_armv6_stop;
+ gi->online = gator_events_armv6_online;
+ gi->offline = gator_events_armv6_offline;
gi->read = gator_events_armv6_read;
#endif
return 0;
diff --git a/gator_events_armv7.c b/gator_events_armv7.c
index ca37bef..5a3268f 100644
--- a/gator_events_armv7.c
+++ b/gator_events_armv7.c
@@ -1,15 +1,10 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/fs.h>
#include "gator.h"
@@ -284,14 +279,12 @@ static int gator_events_armv7_init(int *key)
return 0;
}
-static void __gator_events_armv7_start(void* unused)
+static void gator_events_armv7_online(void)
{
unsigned int cnt;
if (armv7_pmnc_read() & PMNC_E) {
- pr_err("gator: CPU%u PMNC still enabled when setup new event counter\n", raw_smp_processor_id());
- pmnc_count = 0;
- return;
+ armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
}
/* Initialize & Reset PMNC: C bit and P bit */
@@ -339,17 +332,14 @@ static void __gator_events_armv7_start(void* unused)
armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
}
-static int gator_events_armv7_start(void)
+static void gator_events_armv7_offline(void)
{
- if (!pmnc_count)
- return 0;
- return on_each_cpu(__gator_events_armv7_start, NULL, 1);
+ armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
}
-static void __gator_events_armv7_stop(void* unused)
+static void gator_events_armv7_stop(void)
{
unsigned int cnt;
- armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
for (cnt = CCNT; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
@@ -357,13 +347,6 @@ static void __gator_events_armv7_stop(void* unused)
}
}
-static void gator_events_armv7_stop(void)
-{
- if (!pmnc_count)
- return;
- on_each_cpu(__gator_events_armv7_stop, NULL, 1);
-}
-
static int gator_events_armv7_read(int **buffer)
{
int cnt, len = 0;
@@ -419,8 +402,9 @@ int gator_events_armv7_install(gator_interface *gi) {
gi->create_files = gator_events_armv7_create_files;
gi->init = gator_events_armv7_init;
- gi->start = gator_events_armv7_start;
gi->stop = gator_events_armv7_stop;
+ gi->online = gator_events_armv7_online;
+ gi->offline = gator_events_armv7_offline;
gi->read = gator_events_armv7_read;
#endif
return 0;
diff --git a/gator_events_block.c b/gator_events_block.c
index c2d1e7e..f32d8ef 100644
--- a/gator_events_block.c
+++ b/gator_events_block.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,14 +7,8 @@
*
*/
-#include <linux/version.h>
-#include <linux/blkdev.h>
-#include <trace/events/block.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-
#include "gator.h"
-#include "gator_trace.h"
+#include <trace/events/block.h>
#define BLOCK_RQ_WR 0
#define BLOCK_RQ_RD 1
@@ -102,7 +96,7 @@ static int gator_events_block_start(void)
{
int cpu;
- for_each_possible_cpu(cpu)
+ for_each_present_cpu(cpu)
per_cpu(new_data_avail, cpu) = true;
// register tracepoints
diff --git a/gator_events_irq.c b/gator_events_irq.c
index f34cc18..7bbbd4b 100644
--- a/gator_events_irq.c
+++ b/gator_events_irq.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,15 +7,8 @@
*
*/
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/dcookies.h>
-#include <linux/version.h>
-#include <trace/events/irq.h>
-
#include "gator.h"
-#include "gator_trace.h"
+#include <trace/events/irq.h>
#define HARDIRQ 0
#define SOFTIRQ 1
@@ -41,8 +34,11 @@ GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq,
local_irq_restore(flags);
}
-GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(struct softirq_action *h,
- struct softirq_action *vec))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(struct softirq_action *h, struct softirq_action *vec))
+#else
+GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(unsigned int vec_nr))
+#endif
{
unsigned long flags;
@@ -93,7 +89,7 @@ static int gator_events_irq_start(void)
{
int cpu, i;
- for_each_possible_cpu(cpu) {
+ for_each_present_cpu(cpu) {
for (i = 0; i < TOTALIRQ; i++)
per_cpu(irqPrev, cpu)[i] = 0;
}
diff --git a/gator_events_meminfo.c b/gator_events_meminfo.c
index 52345c8..1b576f8 100644
--- a/gator_events_meminfo.c
+++ b/gator_events_meminfo.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,16 +7,10 @@
*
*/
+#include "gator.h"
#include <linux/workqueue.h>
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
#include <trace/events/kmem.h>
-#include "gator.h"
-#include "gator_trace.h"
-
#define MEMINFO_MEMFREE 0
#define MEMINFO_MEMUSED 1
#define MEMINFO_BUFFERRAM 2
diff --git a/gator_events_net.c b/gator_events_net.c
new file mode 100644
index 0000000..3ca5911
--- /dev/null
+++ b/gator_events_net.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "gator.h"
+#include <linux/netdevice.h>
+
+#define NETRX 0
+#define NETTX 1
+#define NETDRV 2
+#define TOTALNET (NETDRV+1)
+
+static ulong netdrv_enabled;
+static ulong netrx_enabled;
+static ulong nettx_enabled;
+static ulong netdrv_key;
+static ulong netrx_key;
+static ulong nettx_key;
+static int rx_total, tx_total;
+static ulong netPrev[TOTALNET];
+static int netGet[TOTALNET * 2];
+
+static void get_network_stats(struct work_struct *wsptr) {
+ int rx = 0, tx = 0;
+ struct net_device *dev;
+
+ for_each_netdev(&init_net, dev) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
+ const struct net_device_stats *stats = dev_get_stats(dev);
+#else
+ struct rtnl_link_stats64 temp;
+ const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
+#endif
+ rx += stats->rx_bytes;
+ tx += stats->tx_bytes;
+ }
+ rx_total = rx;
+ tx_total = tx;
+}
+DECLARE_WORK(wq_get_stats, get_network_stats);
+
+static void calculate_delta(int *drv, int *rx, int *tx)
+{
+ int drv_calc, rx_calc, tx_calc;
+
+ drv_calc = gator_net_traffic - netPrev[NETDRV];
+ if (drv_calc > 0) {
+ netPrev[NETDRV] += drv_calc;
+ netPrev[NETTX] += drv_calc;
+ // remove tcp/ip header overhead
+ // approximation based on empirical measurement
+ netPrev[NETRX] += drv_calc / 42;
+ netPrev[NETTX] += drv_calc / 18;
+ }
+
+ rx_calc = (int)(rx_total - netPrev[NETRX]);
+ if (rx_calc < 0)
+ rx_calc = 0;
+ netPrev[NETRX] += rx_calc;
+
+ tx_calc = (int)(tx_total - netPrev[NETTX]);
+ if (tx_calc < 0)
+ tx_calc = 0;
+ netPrev[NETTX] += tx_calc;
+
+ *drv = drv_calc;
+ *rx = rx_calc;
+ *tx = tx_calc;
+}
+
+static int gator_events_net_create_files(struct super_block *sb, struct dentry *root)
+{
+ struct dentry *dir;
+
+ dir = gatorfs_mkdir(sb, root, "Linux_net_drv");
+ if (!dir) {
+ return -1;
+ }
+ gatorfs_create_ulong(sb, dir, "enabled", &netdrv_enabled);
+ gatorfs_create_ro_ulong(sb, dir, "key", &netdrv_key);
+
+ dir = gatorfs_mkdir(sb, root, "Linux_net_rx");
+ if (!dir) {
+ return -1;
+ }
+ gatorfs_create_ulong(sb, dir, "enabled", &netrx_enabled);
+ gatorfs_create_ro_ulong(sb, dir, "key", &netrx_key);
+
+ dir = gatorfs_mkdir(sb, root, "Linux_net_tx");
+ if (!dir) {
+ return -1;
+ }
+ gatorfs_create_ulong(sb, dir, "enabled", &nettx_enabled);
+ gatorfs_create_ro_ulong(sb, dir, "key", &nettx_key);
+
+ return 0;
+}
+
+static int gator_events_net_init(int *key)
+{
+ netdrv_key = *key;
+ *key = *key + 1;
+ netrx_key = *key;
+ *key = *key + 1;
+ nettx_key = *key;
+ *key = *key + 1;
+
+ netdrv_enabled = 0;
+ netrx_enabled = 0;
+ nettx_enabled = 0;
+
+ return 0;
+}
+
+static int gator_events_net_start(void)
+{
+ get_network_stats(NULL);
+ netPrev[NETDRV] = 0;
+ netPrev[NETRX] = rx_total;
+ netPrev[NETTX] = tx_total;
+ return 0;
+}
+
+static void gator_events_net_stop(void)
+{
+ netdrv_enabled = 0;
+ netrx_enabled = 0;
+ nettx_enabled = 0;
+}
+
+static int gator_events_net_read(int **buffer)
+{
+ int len, drv_delta, rx_delta, tx_delta;
+
+ if (raw_smp_processor_id() != 0)
+ return 0;
+
+ schedule_work(&wq_get_stats);
+ calculate_delta(&drv_delta, &rx_delta, &tx_delta);
+
+ len = 0;
+ if (netdrv_enabled) {
+ netGet[len++] = netdrv_key;
+ netGet[len++] = drv_delta;
+ }
+
+ if (netrx_enabled) {
+ netGet[len++] = netrx_key;
+ netGet[len++] = rx_delta;
+ }
+
+ if (nettx_enabled) {
+ netGet[len++] = nettx_key;
+ netGet[len++] = tx_delta;
+ }
+
+ if (buffer)
+ *buffer = netGet;
+
+ return len;
+}
+
+int gator_events_net_install(gator_interface *gi) {
+ gi->create_files = gator_events_net_create_files;
+ gi->init = gator_events_net_init;
+ gi->start = gator_events_net_start;
+ gi->stop = gator_events_net_stop;
+ gi->read = gator_events_net_read;
+ gator_net_traffic++;
+ return 0;
+}
diff --git a/gator_events_sched.c b/gator_events_sched.c
index 57b710a..138b7e4 100644
--- a/gator_events_sched.c
+++ b/gator_events_sched.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,15 +7,8 @@
*
*/
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/dcookies.h>
-#include <trace/events/sched.h>
-
#include "gator.h"
-#include "gator_trace.h"
+#include <trace/events/sched.h>
#define SCHED_SWITCH 0
#define SCHED_TOTAL (SCHED_SWITCH+1)
diff --git a/gator_main.c b/gator_main.c
index 6748448..60b09cb 100644
--- a/gator_main.c
+++ b/gator_main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,20 +7,13 @@
*
*/
-static unsigned long gator_protocol_version = 2;
+static unsigned long gator_protocol_version = 3;
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/fs.h>
+#include "gator.h"
+#include <linux/slab.h>
+#include <linux/cpu.h>
#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/smp.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/dcookies.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
@@ -42,12 +35,11 @@ static unsigned long gator_protocol_version = 2;
#error kernels prior to 2.6.32 are not supported
#endif
-#include "gator.h"
-
/******************************************************************************
* DEFINES
******************************************************************************/
-#define BUFFER_SIZE_DEFAULT 131072
+#define BUFFER_SIZE_DEFAULT 262144
+#define SYNC_FREQ_DEFAULT 1000
#define NO_COOKIE 0UL
#define INVALID_COOKIE ~0UL
@@ -61,6 +53,7 @@ static unsigned long gator_protocol_version = 2;
#define PROTOCOL_SCHEDULER_TRACE 11
#define PROTOCOL_COUNTERS 13
#define PROTOCOL_ANNOTATE 15
+#define PROTOCOL_CPU_SYNC 17
#if defined(__arm__)
#define PC_REG regs->ARM_pc
@@ -71,19 +64,30 @@ static unsigned long gator_protocol_version = 2;
/******************************************************************************
* PER CPU
******************************************************************************/
+static unsigned long gator_cpu_cores;
static unsigned long gator_buffer_size;
static unsigned long gator_backtrace_depth;
static unsigned long gator_started;
static unsigned long gator_buffer_opened;
static unsigned long gator_timer_count;
-static unsigned long gator_dump;
+static unsigned long gator_sync_freq;
+static int gator_master_tick;
static DEFINE_MUTEX(start_mutex);
static DEFINE_MUTEX(gator_buffer_mutex);
+
+unsigned long gator_net_traffic;
+
+#define COMMIT_SIZE 128
+#define COMMIT_MASK (COMMIT_SIZE-1)
+static DEFINE_SPINLOCK(gator_commit_lock);
+static int *gator_commit;
+static int gator_commit_read;
+static int gator_commit_write;
+
static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait);
-/* atomic_t because wait_event checks it outside of gator_buffer_mutex */
-static DEFINE_PER_CPU(atomic_t, gator_buffer_ready);
-static DEFINE_PER_CPU(int, gator_tick);
+static DEFINE_PER_CPU(int, gator_cpu_sync);
+static DEFINE_PER_CPU(int, gator_cpu_tick);
static DEFINE_PER_CPU(int, gator_first_time);
/******************************************************************************
@@ -115,6 +119,32 @@ u32 gator_cpuid(void)
return (val >> 4) & 0xfff;
}
#endif
+
+/******************************************************************************
+ * Commit interface
+ ******************************************************************************/
+static int buffer_commit_ready(void)
+{
+ return (gator_commit_read != gator_commit_write);
+}
+
+static void buffer_commit_read(int *cpu, int *readval, int *writeval)
+{
+ int read = gator_commit_read;
+ *cpu = gator_commit[read+0];
+ *readval = gator_commit[read+1];
+ *writeval = gator_commit[read+2];
+ gator_commit_read = (read + 4) & COMMIT_MASK;
+}
+
+static void buffer_commit_write(int cpu, int readval, int writeval) {
+ int write = gator_commit_write;
+ gator_commit[write+0] = cpu;
+ gator_commit[write+1] = readval;
+ gator_commit[write+2] = writeval;
+ gator_commit_write = (write + 4) & COMMIT_MASK;
+}
+
/******************************************************************************
* Buffer management
******************************************************************************/
@@ -123,7 +153,6 @@ static uint32_t use_buffer_mask;
static DEFINE_PER_CPU(int, use_buffer_seq);
static DEFINE_PER_CPU(int, use_buffer_read);
static DEFINE_PER_CPU(int, use_buffer_write);
-static DEFINE_PER_CPU(int, use_buffer_commit);
static DEFINE_PER_CPU(char *, use_buffer);
static void gator_buffer_write_packed_int(int cpu, unsigned int x)
@@ -193,38 +222,46 @@ static void gator_buffer_header(int cpu)
gator_buffer_write_packed_int(cpu, PROTOCOL_FRAME);
gator_buffer_write_packed_int(cpu, cpu);
gator_buffer_write_packed_int(cpu, per_cpu(use_buffer_seq, cpu));
+ per_cpu(use_buffer_seq, cpu)++;
}
static void gator_buffer_commit(int cpu)
{
- per_cpu(use_buffer_commit, cpu) = per_cpu(use_buffer_write, cpu);
-
- per_cpu(use_buffer_seq, cpu)++;
+ buffer_commit_write(cpu, per_cpu(use_buffer_read, cpu), per_cpu(use_buffer_write, cpu));
+ per_cpu(use_buffer_read, cpu) = per_cpu(use_buffer_write, cpu);
gator_buffer_header(cpu);
-
- atomic_set(&per_cpu(gator_buffer_ready, cpu), 1);
wake_up(&gator_buffer_wait);
}
-static void gator_buffer_check(int cpu)
+static void gator_buffer_check(int cpu, int tick)
{
- int commit = 0;
- int available = per_cpu(use_buffer_write, cpu) - per_cpu(use_buffer_read, cpu);
- if (available < 0) {
- available += use_buffer_size;
- }
-
- if (!cpu && gator_dump) {
- gator_dump = 0;
- commit = 1;
- } else if (available >= ((use_buffer_size * 3) / 4)) {
- commit = 1;
- } else if (cpu && (per_cpu(use_buffer_seq, cpu) < per_cpu(use_buffer_seq, 0))) {
- commit = 1;
- }
-
- if (commit) {
+ if (gator_sync_freq && !(tick % gator_sync_freq)) {
+ int c, sync;
+ spin_lock(&gator_commit_lock);
+ // synchronize, if all online cpus have the same tick waypoint
+ sync = per_cpu(gator_cpu_sync, cpu) = per_cpu(gator_cpu_tick, cpu);
+ for_each_online_cpu(c) {
+ if (sync != per_cpu(gator_cpu_sync, c)) {
+ sync = 0;
+ break;
+ }
+ }
+ if (sync) {
+ gator_buffer_write_packed_int(cpu, PROTOCOL_CPU_SYNC);
+ }
+ // commit the buffer
gator_buffer_commit(cpu);
+ spin_unlock(&gator_commit_lock);
+ } else {
+ int available = per_cpu(use_buffer_write, cpu) - per_cpu(use_buffer_read, cpu);
+ if (available < 0) {
+ available += use_buffer_size;
+ }
+ if (available >= ((use_buffer_size * 3) / 4)) {
+ spin_lock(&gator_commit_lock);
+ gator_buffer_commit(cpu);
+ spin_unlock(&gator_commit_lock);
+ }
}
}
@@ -305,11 +342,11 @@ static void gator_write_annotate(int cpu, int len, int *buffer)
******************************************************************************/
static gator_interface *gi = NULL;
-static void gator_timer_interrupt(unsigned int ticks)
+static void gator_timer_interrupt(void)
{
struct pt_regs * const regs = get_irq_regs();
int cpu = raw_smp_processor_id();
- int *buffer, len;
+ int *buffer, len, tick;
gator_interface *i;
// check full backtrace has enough space, otherwise may
@@ -322,7 +359,6 @@ static void gator_timer_interrupt(unsigned int ticks)
i->read(NULL);
}
}
- per_cpu(gator_tick, cpu) += ticks;
return;
}
@@ -354,52 +390,95 @@ static void gator_timer_interrupt(unsigned int ticks)
gator_add_sample(cpu, regs);
// Timer Tick
- gator_write_packet(cpu, PROTOCOL_END_TICK, 1, &per_cpu(gator_tick, cpu));
- per_cpu(gator_tick, cpu) += ticks;
+ tick = per_cpu(gator_cpu_tick, cpu);
+ if (tick == gator_master_tick) {
+ tick++;
+ per_cpu(gator_cpu_tick, cpu) = gator_master_tick = tick;
+ } else {
+ per_cpu(gator_cpu_tick, cpu) = tick = gator_master_tick;
+ }
+ gator_write_packet(cpu, PROTOCOL_END_TICK, 1, &tick);
- // Check and commit
- gator_buffer_check(cpu);
+ // Check and commit; generally, commit is set to occur once per second
+ gator_buffer_check(cpu, tick);
}
/******************************************************************************
* hrtimer
******************************************************************************/
DEFINE_PER_CPU(struct hrtimer, percpu_hrtimer);
-extern void gator_timer_stop(void);
+DEFINE_PER_CPU(int, hrtimer_is_active);
static int hrtimer_running;
static ktime_t profiling_interval;
-static atomic_t num_active_timers;
static enum hrtimer_restart gator_hrtimer_notify(struct hrtimer *hrtimer)
{
- unsigned int ticks = (unsigned int)hrtimer_forward_now(hrtimer, profiling_interval);
- gator_timer_interrupt(ticks);
+ hrtimer_forward_now(hrtimer, profiling_interval);
+ gator_timer_interrupt();
return HRTIMER_RESTART;
}
-int gator_timer_init(void)
+static int gator_timer_init(void)
{
return 0;
}
-static void __gator_timer_start(void *unused)
+static void __gator_timer_offline(void *unused)
{
int cpu = smp_processor_id();
+ if (per_cpu(hrtimer_is_active, cpu)) {
+ gator_interface *i;
+ struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu);
+ hrtimer_cancel(hrtimer);
+ per_cpu(hrtimer_is_active, cpu) = 0;
+ gator_buffer_commit(cpu);
- struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu);
- hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hrtimer->function = gator_hrtimer_notify;
- hrtimer_start(hrtimer, profiling_interval, HRTIMER_MODE_REL_PINNED);
- atomic_inc(&num_active_timers);
+ // offline any events
+ for (i = gi; i != NULL; i = i->next) {
+ if (i->offline) {
+ i->offline();
+ }
+ }
+ }
+}
- per_cpu(gator_first_time, cpu) = 1;
- per_cpu(gator_tick, cpu) = 0;
+static void gator_timer_offline(void)
+{
+ if (hrtimer_running) {
+ hrtimer_running = 0;
+
+ on_each_cpu(__gator_timer_offline, NULL, 1);
+
+ // output a final sync point
+ gator_buffer_write_packed_int(0, PROTOCOL_CPU_SYNC);
+ gator_buffer_commit(0);
+ }
}
-int gator_timer_start(unsigned long setup)
+static void __gator_timer_online(void *unused)
{
- atomic_set(&num_active_timers, 0);
+ int cpu = smp_processor_id();
+ if (!per_cpu(hrtimer_is_active, cpu)) {
+ gator_interface *i;
+ struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu);
+ hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hrtimer->function = gator_hrtimer_notify;
+ hrtimer_start(hrtimer, profiling_interval, HRTIMER_MODE_REL_PINNED);
+ per_cpu(gator_cpu_tick, cpu) = 0;
+ per_cpu(gator_first_time, cpu) = 1;
+ per_cpu(hrtimer_is_active, cpu) = 1;
+
+ // online any events
+ for (i = gi; i != NULL; i = i->next) {
+ if (i->online) {
+ i->online();
+ }
+ }
+ }
+}
+int gator_timer_online(unsigned long setup)
+{
if (!setup) {
pr_err("gator: cannot start due to a system tick value of zero");
return -1;
@@ -414,37 +493,12 @@ int gator_timer_start(unsigned long setup)
profiling_interval = ns_to_ktime(1000000000UL / setup);
// timer interrupt
- on_each_cpu(__gator_timer_start, NULL, 1);
-
- if (atomic_read(&num_active_timers) != num_present_cpus()) {
- pr_err("gator: %d timer(s) started yet %d cpu(s) detected, please bring all cpus online manually and restart\n", atomic_read(&num_active_timers), nr_cpu_ids);
- gator_timer_stop();
- return -1;
- }
+ gator_master_tick = 0;
+ on_each_cpu(__gator_timer_online, NULL, 1);
return 0;
}
-void __gator_timer_stop(void *unused)
-{
- struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, smp_processor_id());
- hrtimer_cancel(hrtimer);
- atomic_dec(&num_active_timers);
-}
-
-void gator_timer_stop(void)
-{
- if (hrtimer_running) {
- int previously_running = atomic_read(&num_active_timers);
- hrtimer_running = 0;
- on_each_cpu(__gator_timer_stop, NULL, 1);
- if (atomic_read(&num_active_timers) != 0) {
- pr_err("gator: %d timers stopped yet %d were running, it is advised to quit and restart gatord", previously_running - atomic_read(&num_active_timers), previously_running);
- atomic_set(&num_active_timers, 0);
- }
- }
-}
-
static uint64_t gator_get_time(void)
{
struct timespec ts;
@@ -457,6 +511,42 @@ static uint64_t gator_get_time(void)
}
/******************************************************************************
+ * cpu online notifier
+ ******************************************************************************/
+static int __cpuinit gator_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ long cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ 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);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata gator_cpu_notifier = {
+ .notifier_call = gator_cpu_notify,
+};
+
+static int gator_notifier_start(void)
+{
+ return register_hotcpu_notifier(&gator_cpu_notifier);
+}
+
+static void gator_notifier_stop(void)
+{
+ unregister_hotcpu_notifier(&gator_cpu_notifier);
+}
+
+/******************************************************************************
* Main
******************************************************************************/
int gator_event_install(int (*event_install)(gator_interface *))
@@ -470,6 +560,8 @@ int gator_event_install(int (*event_install)(gator_interface *))
ni->init = NULL;
ni->start = NULL;
ni->stop = NULL;
+ ni->online = NULL;
+ ni->offline = NULL;
ni->read = NULL;
ni->next = NULL;
@@ -538,11 +630,15 @@ static int gator_start(void)
goto annotate_failure;
if (gator_trace_sched_start())
goto sched_failure;
- if (gator_timer_start(gator_timer_count))
+ if (gator_timer_online(gator_timer_count))
goto timer_failure;
+ if (gator_notifier_start())
+ goto notifier_failure;
return 0;
+notifier_failure:
+ gator_timer_offline();
timer_failure:
gator_trace_sched_stop();
sched_failure:
@@ -560,17 +656,19 @@ static void gator_stop(void)
{
gator_interface *i;
- // stop all interrupt callback reads before tearing down other interfaces
- gator_timer_stop();
- gator_annotate_stop();
- gator_trace_sched_stop();
-
// stop all events
for (i = gi; i != NULL; i = i->next) {
if (i->stop) {
i->stop();
}
}
+
+ gator_annotate_stop();
+ gator_trace_sched_stop();
+
+ // stop all interrupt callback reads before tearing down other interfaces
+ gator_timer_offline();
+ gator_notifier_stop();
}
static void gator_exit(void)
@@ -604,18 +702,28 @@ static int gator_op_setup(void)
goto setup_error;
}
- for_each_possible_cpu(cpu) {
+ gator_net_traffic = 0;
+
+ gator_commit_read = gator_commit_write = 0;
+ gator_commit = vmalloc(COMMIT_SIZE * sizeof(int));
+ if (!gator_commit) {
+ err = -ENOMEM;
+ goto setup_error;
+ }
+
+ for_each_present_cpu(cpu) {
per_cpu(use_buffer, cpu) = vmalloc(use_buffer_size);
if (!per_cpu(use_buffer, cpu)) {
err = -ENOMEM;
goto setup_error;
}
- atomic_set(&per_cpu(gator_buffer_ready, cpu), 0);
+ per_cpu(gator_cpu_sync, cpu) = 0;
+ per_cpu(gator_cpu_tick, cpu) = 0;
+
per_cpu(use_buffer_seq, cpu) = 0;
per_cpu(use_buffer_read, cpu) = 0;
per_cpu(use_buffer_write, cpu) = 0;
- per_cpu(use_buffer_commit, cpu) = 0;
gator_buffer_header(cpu);
}
@@ -646,8 +754,6 @@ static int gator_op_start(void)
/* echo 0>/dev/gator/enable */
static void gator_op_stop(void)
{
- int cpu;
-
mutex_lock(&start_mutex);
if (gator_started) {
@@ -655,11 +761,6 @@ static void gator_op_stop(void)
mutex_lock(&gator_buffer_mutex);
- /* wake up the daemon to read what remains */
- for_each_possible_cpu(cpu) {
- gator_buffer_commit(cpu);
- atomic_set(&per_cpu(gator_buffer_ready, cpu), 1);
- }
gator_started = 0;
cookies_release();
wake_up(&gator_buffer_wait);
@@ -676,14 +777,16 @@ static void gator_shutdown(void)
mutex_lock(&start_mutex);
- for_each_possible_cpu(cpu) {
+ vfree(gator_commit);
+ gator_commit = NULL;
+
+ for_each_present_cpu(cpu) {
mutex_lock(&gator_buffer_mutex);
vfree(per_cpu(use_buffer, cpu));
per_cpu(use_buffer, cpu) = NULL;
per_cpu(use_buffer_seq, cpu) = 0;
per_cpu(use_buffer_read, cpu) = 0;
per_cpu(use_buffer_write, cpu) = 0;
- per_cpu(use_buffer_commit, cpu) = 0;
mutex_unlock(&gator_buffer_mutex);
}
@@ -748,15 +851,6 @@ static int event_buffer_open(struct inode *inode, struct file *file)
if (test_and_set_bit_lock(0, &gator_buffer_opened))
return -EBUSY;
- /* Register as a user of dcookies
- * to ensure they persist for the lifetime of
- * the open event file
- */
- err = -EINVAL;
- file->private_data = dcookie_register();
- if (!file->private_data)
- goto out;
-
if ((err = gator_op_setup()))
goto fail;
@@ -767,35 +861,18 @@ static int event_buffer_open(struct inode *inode, struct file *file)
return 0;
fail:
- dcookie_unregister(file->private_data);
-out:
__clear_bit_unlock(0, &gator_buffer_opened);
return err;
}
static int event_buffer_release(struct inode *inode, struct file *file)
{
- int cpu;
gator_op_stop();
gator_shutdown();
- dcookie_unregister(file->private_data);
- for_each_possible_cpu(cpu) {
- atomic_set(&per_cpu(gator_buffer_ready, cpu), 0);
- }
__clear_bit_unlock(0, &gator_buffer_opened);
return 0;
}
-static int event_buffer_ready(void)
-{
- int cpu;
- for_each_possible_cpu(cpu) {
- if (atomic_read(&per_cpu(gator_buffer_ready, cpu)))
- return cpu;
- }
- return -1;
-}
-
static ssize_t event_buffer_read(struct file *file, char __user *buf,
size_t count, loff_t *offset)
{
@@ -808,18 +885,17 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
if (count != use_buffer_size || *offset)
return -EINVAL;
- wait_event_interruptible(gator_buffer_wait, event_buffer_ready() >= 0 || !gator_started);
- cpu = event_buffer_ready();
+ // sleep until the condition is true or a signal is received
+ // the condition is checked each time gator_buffer_wait is woken up
+ wait_event_interruptible(gator_buffer_wait, buffer_commit_ready() || !gator_started);
if (signal_pending(current))
return -EINTR;
- if (cpu < 0)
+ if (!buffer_commit_ready())
return 0;
- /* should not happen */
- if (!atomic_read(&per_cpu(gator_buffer_ready, cpu)))
- return -EAGAIN;
+ buffer_commit_read(&cpu, &read, &commit);
mutex_lock(&gator_buffer_mutex);
@@ -832,8 +908,6 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
}
/* determine the size of two halves */
- commit = per_cpu(use_buffer_commit, cpu);
- read = per_cpu(use_buffer_read, cpu);
length1 = commit - read;
length2 = 0;
buffer1 = &(per_cpu(use_buffer, cpu)[read]);
@@ -857,16 +931,15 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
}
}
- /* update position */
retval = length1 + length2;
- per_cpu(use_buffer_read, cpu) = (read + retval) & use_buffer_mask;
-
- atomic_set(&per_cpu(gator_buffer_ready, cpu), 0);
/* kick just in case we've lost an SMP event */
wake_up(&gator_buffer_wait);
out:
+ // do not adjust network stats if in non-streaming buffer mode
+ if (gator_sync_freq)
+ gator_net_traffic += retval;
mutex_unlock(&gator_buffer_mutex);
return retval;
}
@@ -922,17 +995,24 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root)
{
struct dentry *dir;
gator_interface *i;
+ int cpu;
/* reinitialize default values */
+ gator_cpu_cores = 0;
+ for_each_present_cpu(cpu) {
+ gator_cpu_cores++;
+ }
gator_buffer_size = BUFFER_SIZE_DEFAULT;
+ gator_sync_freq = SYNC_FREQ_DEFAULT;
gatorfs_create_file(sb, root, "enable", &enable_fops);
gatorfs_create_file(sb, root, "buffer", &gator_event_buffer_fops);
gatorfs_create_file(sb, root, "backtrace_depth", &depth_fops);
gatorfs_create_file(sb, root, "cpu_type", &cpu_type_fops);
+ gatorfs_create_ulong(sb, root, "cpu_cores", &gator_cpu_cores);
gatorfs_create_ulong(sb, root, "buffer_size", &gator_buffer_size);
gatorfs_create_ulong(sb, root, "tick", &gator_timer_count);
- gatorfs_create_ulong(sb, root, "dump", &gator_dump);
+ gatorfs_create_ulong(sb, root, "sync_freq", &gator_sync_freq);
gatorfs_create_ro_ulong(sb, root, "version", &gator_protocol_version);
// Annotate interface
@@ -975,6 +1055,7 @@ static void __exit gator_module_exit(void)
#ifdef GATOR_DEBUG
pr_err("gator_module_exit");
#endif
+ tracepoint_synchronize_unregister();
gatorfs_unregister();
if (gator_initialized) {
gator_initialized = 0;
diff --git a/gator_trace_sched.c b/gator_trace_sched.c
index 1328d88..19d8d89 100644
--- a/gator_trace_sched.c
+++ b/gator_trace_sched.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2011. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -7,14 +7,8 @@
*
*/
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/version.h>
-#include <linux/hardirq.h>
#include <trace/events/sched.h>
-
-#include "gator_trace.h"
+#include "gator.h"
#define SCHED_TIMER_EVENT 0
#define SCHED_WAIT_TASK 1
@@ -147,7 +141,7 @@ int gator_trace_sched_start(void)
{
int cpu;
- for_each_possible_cpu(cpu) {
+ for_each_present_cpu(cpu) {
per_cpu(theSchedSel, cpu) = 0;
per_cpu(theSchedPos, cpu) = 0;
per_cpu(theSchedErr, cpu) = 0;
@@ -217,7 +211,7 @@ void gator_trace_sched_stop(void)
GATOR_UNREGISTER_TRACE(sched_process_fork);
pr_debug("gator: unregistered tracepoints\n");
- for_each_possible_cpu(cpu) {
+ for_each_present_cpu(cpu) {
kfree(per_cpu(theSchedBuf, cpu)[0]);
kfree(per_cpu(theSchedBuf, cpu)[1]);
per_cpu(theSchedBuf, cpu)[0] = NULL;