-diff -Nurb linux-2.6.27-590/arch/Kconfig linux-2.6.27-591/arch/Kconfig
---- linux-2.6.27-590/arch/Kconfig 2010-01-29 16:29:46.000000000 -0500
-+++ linux-2.6.27-591/arch/Kconfig 2010-01-29 16:30:22.000000000 -0500
-@@ -13,9 +13,18 @@
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 1d07625..7d503e4 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -13,9 +13,18 @@ config OPROFILE
If unsure, say N.
config KPROBES
bool "Kprobes"
depends on KALLSYMS && MODULES
-diff -Nurb linux-2.6.27-590/arch/x86/kernel/asm-offsets_32.c linux-2.6.27-591/arch/x86/kernel/asm-offsets_32.c
---- linux-2.6.27-590/arch/x86/kernel/asm-offsets_32.c 2008-10-09 18:13:53.000000000 -0400
-+++ linux-2.6.27-591/arch/x86/kernel/asm-offsets_32.c 2010-01-29 16:45:48.000000000 -0500
+diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
+index 6649d09..5508d20 100644
+--- a/arch/x86/kernel/asm-offsets_32.c
++++ b/arch/x86/kernel/asm-offsets_32.c
@@ -9,6 +9,7 @@
#include <linux/signal.h>
#include <linux/personality.h>
#include <linux/kbuild.h>
#include <asm/ucontext.h>
#include "sigframe.h"
-@@ -24,9 +25,20 @@
+@@ -24,6 +25,18 @@
#include <linux/lguest.h>
#include "../../../drivers/lguest/lg.h"
-+
++#ifdef CONFIG_CHOPSTIX
+#define STACKOFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem)-sizeof(struct str));
+
- /* workaround for a warning with -Wmissing-prototypes */
- void foo(void);
-
+struct event_spec {
+ unsigned long pc;
+ unsigned long dcookie;
+ unsigned count;
+ unsigned int number;
+};
++#endif
+
- void foo(void)
- {
- OFFSET(IA32_SIGCONTEXT_ax, sigcontext, ax);
-@@ -50,6 +62,16 @@
+ /* workaround for a warning with -Wmissing-prototypes */
+ void foo(void);
+
+@@ -50,6 +63,18 @@ void foo(void)
OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
BLANK();
-+ STACKOFFSET(TASK_thread, task_struct, thread);
-+ STACKOFFSET(THREAD_esp, thread_struct, sp);
-+ STACKOFFSET(EVENT_event_data, event, event_data);
-+ STACKOFFSET(EVENT_task, event, task);
-+ STACKOFFSET(EVENT_event_type, event, event_type);
-+ STACKOFFSET(SPEC_number, event_spec, number);
-+ DEFINE(EVENT_SIZE, sizeof(struct event));
-+ DEFINE(SPEC_SIZE, sizeof(struct event_spec));
-+ DEFINE(SPEC_EVENT_SIZE, sizeof(struct event_spec)+sizeof(struct event));
++#ifdef CONFIG_CHOPSTIX
++ STACKOFFSET(TASK_thread, task_struct, thread);
++ STACKOFFSET(THREAD_esp, thread_struct, sp);
++ STACKOFFSET(EVENT_event_data, event, event_data);
++ STACKOFFSET(EVENT_task, event, task);
++ STACKOFFSET(EVENT_event_type, event, event_type);
++ STACKOFFSET(SPEC_number, event_spec, number);
++ DEFINE(EVENT_SIZE, sizeof(struct event));
++ DEFINE(SPEC_SIZE, sizeof(struct event_spec));
++ DEFINE(SPEC_EVENT_SIZE, sizeof(struct event_spec)+sizeof(struct event));
++#endif
+
OFFSET(TI_task, thread_info, task);
OFFSET(TI_exec_domain, thread_info, exec_domain);
OFFSET(TI_flags, thread_info, flags);
-diff -Nurb linux-2.6.27-590/arch/x86/kernel/asm-offsets_32.c.rej linux-2.6.27-591/arch/x86/kernel/asm-offsets_32.c.rej
---- linux-2.6.27-590/arch/x86/kernel/asm-offsets_32.c.rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.27-591/arch/x86/kernel/asm-offsets_32.c.rej 2010-01-31 22:21:08.000000000 -0500
-@@ -0,0 +1,17 @@
-+***************
-+*** 63,69 ****
-+ BLANK();
-+
-+ STACKOFFSET(TASK_thread, task_struct, thread);
-+- STACKOFFSET(THREAD_esp, thread_struct, esp);
-+ STACKOFFSET(EVENT_event_data, event, event_data);
-+ STACKOFFSET(EVENT_task, event, task);
-+ STACKOFFSET(EVENT_event_type, event, event_type);
-+--- 63,69 ----
-+ BLANK();
-+
-+ STACKOFFSET(TASK_thread, task_struct, thread);
-++ STACKOFFSET(THREAD_esp, thread_struct, sp);
-+ STACKOFFSET(EVENT_event_data, event, event_data);
-+ STACKOFFSET(EVENT_task, event, task);
-+ STACKOFFSET(EVENT_event_type, event, event_type);
-diff -Nurb linux-2.6.27-590/arch/x86/kernel/entry_32.S linux-2.6.27-591/arch/x86/kernel/entry_32.S
---- linux-2.6.27-590/arch/x86/kernel/entry_32.S 2008-10-09 18:13:53.000000000 -0400
-+++ linux-2.6.27-591/arch/x86/kernel/entry_32.S 2010-01-29 16:30:22.000000000 -0500
-@@ -426,6 +426,33 @@
+diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
+index 109792b..92a4f72 100644
+--- a/arch/x86/kernel/entry_32.S
++++ b/arch/x86/kernel/entry_32.S
+@@ -426,6 +426,34 @@ ENTRY(system_call)
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
-+ /* Move Chopstix syscall probe here */
-+ /* Save and clobber: eax, ecx, ebp */
-+ pushl %eax
-+ pushl %ecx
-+ pushl %ebp
-+ movl %esp, %ebp
-+ subl $SPEC_EVENT_SIZE, %esp
-+ movl rec_event, %ecx
-+ testl %ecx, %ecx
-+ jz carry_on
-+ # struct event is first, just below %ebp
-+ movl %eax, (SPEC_number-EVENT_SIZE)(%ebp)
-+ leal -SPEC_EVENT_SIZE(%ebp), %eax
-+ movl %eax, EVENT_event_data(%ebp)
-+ movl $6, EVENT_event_type(%ebp)
-+ movl rec_event, %edx
-+ movl $1, 4(%esp)
-+ leal -EVENT_SIZE(%ebp), %eax
-+ movl %eax, (%esp)
-+ call rec_event_asm
++#ifdef CONFIG_CHOPSTIX
++ /* Move Chopstix syscall probe here */
++ /* Save and clobber: eax, ecx, ebp */
++ pushl %eax
++ pushl %ecx
++ pushl %ebp
++ movl %esp, %ebp
++ subl $SPEC_EVENT_SIZE, %esp
++ movl rec_event, %ecx
++ testl %ecx, %ecx
++ jz carry_on
++ # struct event is first, just below %ebp
++ movl %eax, (SPEC_number-EVENT_SIZE)(%ebp)
++ leal -SPEC_EVENT_SIZE(%ebp), %eax
++ movl %eax, EVENT_event_data(%ebp)
++ movl $7, EVENT_event_type(%ebp)
++ movl rec_event, %edx
++ movl $1, 4(%esp)
++ leal -EVENT_SIZE(%ebp), %eax
++ movl %eax, (%esp)
++ call rec_event_asm
+carry_on:
-+ addl $SPEC_EVENT_SIZE, %esp
-+ popl %ebp
-+ popl %ecx
-+ popl %eax
-+ /* End chopstix */
-+
++ addl $SPEC_EVENT_SIZE, %esp
++ popl %ebp
++ popl %ecx
++ popl %eax
++ /* End chopstix */
++#endif
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
-diff -Nurb linux-2.6.27-590/arch/x86/mm/fault.c linux-2.6.27-591/arch/x86/mm/fault.c
---- linux-2.6.27-590/arch/x86/mm/fault.c 2010-01-29 16:29:46.000000000 -0500
-+++ linux-2.6.27-591/arch/x86/mm/fault.c 2010-01-29 16:30:22.000000000 -0500
-@@ -79,6 +79,15 @@
+diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
+index 3384255..cd535c7 100644
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -79,6 +79,16 @@ static inline int notify_page_fault(struct pt_regs *regs)
#endif
}
-+
++#ifdef CONFIG_CHOPSTIX
+extern void (*rec_event)(void *,unsigned int);
+struct event_spec {
+ unsigned long pc;
+ unsigned count;
+ unsigned char reason;
+};
++#endif
+
/*
* X86_32
* Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
-diff -Nurb linux-2.6.27-590/drivers/oprofile/cpu_buffer.c linux-2.6.27-591/drivers/oprofile/cpu_buffer.c
---- linux-2.6.27-590/drivers/oprofile/cpu_buffer.c 2008-10-09 18:13:53.000000000 -0400
-+++ linux-2.6.27-591/drivers/oprofile/cpu_buffer.c 2010-01-29 16:30:22.000000000 -0500
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 2cba5ef..7fc6c2b 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -30,9 +30,20 @@
+ #include <linux/cpu.h>
+ #include <linux/blktrace_api.h>
+ #include <linux/fault-inject.h>
++#include <linux/arrays.h>
+
+ #include "blk.h"
+
++#ifdef CONFIG_CHOPSTIX
++extern void (*rec_event)(void *,unsigned int);
++struct event_spec {
++ unsigned long pc;
++ unsigned long dcookie;
++ unsigned count;
++ unsigned char reason;
++};
++#endif
++
+ static int __make_request(struct request_queue *q, struct bio *bio);
+
+ /*
+@@ -1414,6 +1425,24 @@ end_io:
+ goto end_io;
+ }
+
++#ifdef CONFIG_CHOPSTIX
++ if (rec_event) {
++ struct event event;
++ struct event_spec espec;
++ unsigned long eip;
++
++ espec.reason = 0;/*request */
++
++ eip = bio->bi_end_io;
++ event.event_data=&espec;
++ espec.pc=eip;
++ event.event_type=3;
++ /* index in the event array currently set up */
++ /* make sure the counters are loaded in the order we want them to show up*/
++ (*rec_event)(&event, bio->bi_size);
++ }
++#endif
++
+ ret = q->make_request_fn(q, bio);
+ } while (ret);
+ }
+diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
+index 7ba78e6..ef379fb 100644
+--- a/drivers/oprofile/cpu_buffer.c
++++ b/drivers/oprofile/cpu_buffer.c
@@ -21,6 +21,7 @@
#include <linux/oprofile.h>
#include <linux/vmalloc.h>
#include "event_buffer.h"
#include "cpu_buffer.h"
-@@ -147,6 +148,17 @@
+@@ -147,6 +148,17 @@ static void increment_head(struct oprofile_cpu_buffer * b)
b->head_pos = 0;
}
static inline void
add_sample(struct oprofile_cpu_buffer * cpu_buf,
unsigned long pc, unsigned long event)
-@@ -155,6 +167,7 @@
- entry->eip = pc;
- entry->event = event;
- increment_head(cpu_buf);
-+
- }
-
- static inline void
-@@ -250,8 +263,28 @@
- {
+@@ -251,7 +263,24 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
int is_kernel = !user_mode(regs);
unsigned long pc = profile_pc(regs);
-+ int res=0;
+#ifdef CONFIG_CHOPSTIX
+ if (rec_event) {
+ (*rec_event)(&esig, 1);
+ }
+ else {
- oprofile_add_ext_sample(pc, regs, event, is_kernel);
++ oprofile_add_ext_sample(pc, regs, event, is_kernel);
+ }
+#else
-+ oprofile_add_ext_sample(pc, regs, event, is_kernel);
+ oprofile_add_ext_sample(pc, regs, event, is_kernel);
+#endif
-+
-+
}
void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
-diff -Nurb linux-2.6.27-590/fs/bio.c linux-2.6.27-591/fs/bio.c
---- linux-2.6.27-590/fs/bio.c 2008-10-09 18:13:53.000000000 -0400
-+++ linux-2.6.27-591/fs/bio.c 2010-01-31 22:21:09.000000000 -0500
+diff --git a/fs/bio.c b/fs/bio.c
+index 3cba7ae..2f16e17 100644
+--- a/fs/bio.c
++++ b/fs/bio.c
@@ -27,6 +27,7 @@
#include <linux/workqueue.h>
#include <linux/blktrace_api.h>
static struct kmem_cache *bio_slab __read_mostly;
-@@ -44,6 +45,7 @@
+@@ -44,6 +45,7 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
};
#undef BV
/*
* fs_bio_set is the bio_set containing bio and iovec memory pools used by
* IO code that does not need private memory pools.
-@@ -1171,6 +1173,14 @@
+@@ -1171,6 +1173,17 @@ void bio_check_pages_dirty(struct bio *bio)
}
}
++#ifdef CONFIG_CHOPSTIX
+struct event_spec {
+ unsigned long pc;
+ unsigned long dcookie;
+};
+
+extern void (*rec_event)(void *,unsigned int);
++#endif
++
/**
* bio_endio - end I/O on a bio
* @bio: bio
-@@ -1192,6 +1202,24 @@
+@@ -1192,6 +1205,24 @@ void bio_endio(struct bio *bio, int error)
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
error = -EIO;
-+#if 0
++#ifdef CONFIG_CHOPSTIX
+ if (rec_event) {
+ struct event event;
+ struct event_spec espec;
+ event.event_type=3;
+ /* index in the event array currently set up */
+ /* make sure the counters are loaded in the order we want them to show up*/
-+ (*rec_event)(&event, bytes_done);
++ (*rec_event)(&event, bio->bi_size);
+ }
+#endif
+
if (bio->bi_end_io)
bio->bi_end_io(bio, error);
}
-diff -Nurb linux-2.6.27-590/fs/exec.c linux-2.6.27-591/fs/exec.c
---- linux-2.6.27-590/fs/exec.c 2010-01-29 16:29:48.000000000 -0500
-+++ linux-2.6.27-591/fs/exec.c 2010-01-29 16:45:48.000000000 -0500
+diff --git a/fs/exec.c b/fs/exec.c
+index e557406..19bc9d8 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
@@ -27,6 +27,7 @@
#include <linux/fdtable.h>
#include <linux/mm.h>
#include <linux/fcntl.h>
#include <linux/smp_lock.h>
#include <linux/swap.h>
-@@ -698,6 +699,13 @@
+@@ -698,6 +699,13 @@ struct file *open_exec(const char *name)
goto out;
}
+ #ifdef CONFIG_CHOPSTIX
+ unsigned long cookie;
+ extern void (*rec_event)(void *, unsigned int);
-+ if (rec_event && !nd.dentry->d_cookie)
-+ get_dcookie(nd.dentry, nd.mnt, &cookie);
++ if (rec_event && !nd.path.dentry->d_cookie)
++ get_dcookie(&nd.path, &cookie);
+ #endif
+
return file;
out_path_put:
-diff -Nurb linux-2.6.27-590/fs/exec.c.rej linux-2.6.27-591/fs/exec.c.rej
---- linux-2.6.27-590/fs/exec.c.rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.27-591/fs/exec.c.rej 2010-01-31 22:21:18.000000000 -0500
-@@ -0,0 +1,36 @@
-+***************
-+*** 40,46 ****
-+ #include <linux/personality.h>
-+ #include <linux/binfmts.h>
-+ #include <linux/utsname.h>
-+- /*#include <linux/pid_namespace.h>*/
-+ #include <linux/module.h>
-+ #include <linux/namei.h>
-+ #include <linux/proc_fs.h>
-+--- 40,46 ----
-+ #include <linux/personality.h>
-+ #include <linux/binfmts.h>
-+ #include <linux/utsname.h>
-++ #include <linux/pid_namespace.h>
-+ #include <linux/module.h>
-+ #include <linux/namei.h>
-+ #include <linux/proc_fs.h>
-+***************
-+*** 702,709 ****
-+ #ifdef CONFIG_CHOPSTIX
-+ unsigned long cookie;
-+ extern void (*rec_event)(void *, unsigned int);
-+- if (rec_event && !nd.dentry->d_cookie)
-+- get_dcookie(nd.dentry, nd.mnt, &cookie);
-+ #endif
-+
-+ return file;
-+--- 702,709 ----
-+ #ifdef CONFIG_CHOPSTIX
-+ unsigned long cookie;
-+ extern void (*rec_event)(void *, unsigned int);
-++ if (rec_event && !nd.path.dentry->d_cookie)
-++ get_dcookie(&nd.path, &cookie);
-+ #endif
-+
-+ return file;
-diff -Nurb linux-2.6.27-590/include/linux/arrays.h linux-2.6.27-591/include/linux/arrays.h
---- linux-2.6.27-590/include/linux/arrays.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.27-591/include/linux/arrays.h 2010-01-29 16:30:22.000000000 -0500
-@@ -0,0 +1,36 @@
+diff --git a/include/linux/arrays.h b/include/linux/arrays.h
+new file mode 100644
+index 0000000..7641a3c
+--- /dev/null
++++ b/include/linux/arrays.h
+@@ -0,0 +1,39 @@
+#ifndef __ARRAYS_H__
+#define __ARRAYS_H__
+#include <linux/list.h>
+#define SAMPLING_METHOD_DEFAULT 0
+#define SAMPLING_METHOD_LOG 1
+
++#define DEFAULT_ARRAY_SIZE 2048
++
+/* Every probe has an array handler */
+
+/* XXX - Optimize this structure */
+ void **epoch_samples; /* size-sized lists of samples */
+ unsigned int (*serialize)(void *, void *);
+ unsigned char code[5];
++ unsigned int last_threshold;
+};
+
+struct event {
+ struct task_struct *task;
+};
+#endif
-diff -Nurb linux-2.6.27-590/include/linux/sched.h.rej linux-2.6.27-591/include/linux/sched.h.rej
---- linux-2.6.27-590/include/linux/sched.h.rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.27-591/include/linux/sched.h.rej 2010-01-29 16:30:22.000000000 -0500
-@@ -0,0 +1,19 @@
-+***************
-+*** 850,855 ****
-+ #endif
-+ unsigned long sleep_avg;
-+ unsigned long long timestamp, last_ran;
-+ unsigned long long sched_time; /* sched_clock time spent running */
-+ enum sleep_type sleep_type;
-+
-+--- 850,859 ----
-+ #endif
-+ unsigned long sleep_avg;
-+ unsigned long long timestamp, last_ran;
-++ #ifdef CONFIG_CHOPSTIX
-++ unsigned long last_interrupted, last_ran_j;
-++ #endif
-++
-+ unsigned long long sched_time; /* sched_clock time spent running */
-+ enum sleep_type sleep_type;
-+
-diff -Nurb linux-2.6.27-590/kernel/sched.c linux-2.6.27-591/kernel/sched.c
---- linux-2.6.27-590/kernel/sched.c 2010-01-29 16:29:48.000000000 -0500
-+++ linux-2.6.27-591/kernel/sched.c 2010-01-31 22:21:08.000000000 -0500
+diff --git a/include/linux/mutex.h b/include/linux/mutex.h
+index bc6da10..a385919 100644
+--- a/include/linux/mutex.h
++++ b/include/linux/mutex.h
+@@ -55,6 +55,9 @@ struct mutex {
+ const char *name;
+ void *magic;
+ #endif
++#ifdef CONFIG_CHOPSTIX
++ struct thread_info *owner;
++#endif
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+ #endif
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 891fbda..05ba57f 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1134,6 +1134,11 @@ struct task_struct {
+ cputime_t utime, stime, utimescaled, stimescaled;
+ cputime_t gtime;
+ cputime_t prev_utime, prev_stime;
++
++ #ifdef CONFIG_CHOPSTIX
++ unsigned long last_interrupted, last_ran_j;
++ #endif
++
+ unsigned long nvcsw, nivcsw; /* context switch counts */
+ struct timespec start_time; /* monotonic time */
+ struct timespec real_start_time; /* boot based time */
+diff --git a/kernel/mutex.c b/kernel/mutex.c
+index 12c779d..fcc074f 100644
+--- a/kernel/mutex.c
++++ b/kernel/mutex.c
+@@ -18,6 +18,16 @@
+ #include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+ #include <linux/debug_locks.h>
++#include <linux/arrays.h>
++
++#ifdef CONFIG_CHOPSTIX
++struct event_spec {
++ unsigned long pc;
++ unsigned long dcookie;
++ unsigned count;
++ unsigned char reason;
++};
++#endif
+
+ /*
+ * In the DEBUG case we are using the "NULL fastpath" for mutexes,
+@@ -44,6 +54,9 @@ void
+ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
+ {
+ atomic_set(&lock->count, 1);
++#ifdef CONFIG_CHOPSTIX
++ lock->owner = NULL;
++#endif
+ spin_lock_init(&lock->wait_lock);
+ INIT_LIST_HEAD(&lock->wait_list);
+
+@@ -177,6 +190,25 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+ }
+ __set_task_state(task, state);
+
++#if 0 && CONFIG_CHOPSTIX
++ if (rec_event) {
++ if (lock->owner) {
++ struct event event;
++ struct event_spec espec;
++ struct task_struct *p = lock->owner->task;
++
++ espec.reason = 0; /* lock */
++ event.event_data = &espec;
++ event.task = p;
++ espec.pc = lock;
++ event.event_type = 5;
++ (*rec_event)(&event, 1);
++ } else {
++ BUG();
++ }
++ }
++#endif
++
+ /* didnt get the lock, go to sleep: */
+ spin_unlock_mutex(&lock->wait_lock, flags);
+ schedule();
+@@ -189,6 +221,10 @@ done:
+ mutex_remove_waiter(lock, &waiter, task_thread_info(task));
+ debug_mutex_set_owner(lock, task_thread_info(task));
+
++#ifdef CONFIG_CHOPSTIX
++ lock->owner = task_thread_info(task);
++#endif
++
+ /* set it to 0 if there are no waiters left: */
+ if (likely(list_empty(&lock->wait_list)))
+ atomic_set(&lock->count, 0);
+@@ -257,6 +293,25 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested)
+
+ debug_mutex_wake_waiter(lock, waiter);
+
++#if 0 && CONFIG_CHOPSTIX
++ if (rec_event) {
++ if (lock->owner) {
++ struct event event;
++ struct event_spec espec;
++ struct task_struct *p = lock->owner->task;
++
++ espec.reason = 1; /* unlock */
++ event.event_data = &espec;
++ event.task = p;
++ espec.pc = lock;
++ event.event_type = 5;
++ (*rec_event)(&event, 1);
++ } else {
++ BUG();
++ }
++ }
++#endif
++
+ wake_up_process(waiter->task);
+ }
+
+diff --git a/kernel/sched.c b/kernel/sched.c
+index 2d66cdd..347ce2a 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
@@ -10,7 +10,7 @@
* 1998-11-19 Implemented schedule_timeout() and related stuff
* by Andrea Arcangeli
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
-@@ -4428,6 +4432,29 @@
+@@ -2368,6 +2372,10 @@ static void __sched_fork(struct task_struct *p)
+ INIT_HLIST_HEAD(&p->preempt_notifiers);
+ #endif
+
++#ifdef CONFIG_CHOPSTIX
++ p->last_ran_j = jiffies;
++ p->last_interrupted = INTERRUPTIBLE;
++#endif
+ /*
+ * We mark the process as running here, but have not actually
+ * inserted it onto the runqueue yet. This guarantees that
+@@ -4428,6 +4436,30 @@ pick_next_task(struct rq *rq, struct task_struct *prev)
}
}
++#ifdef CONFIG_CHOPSTIX
+void (*rec_event)(void *,unsigned int) = NULL;
+EXPORT_SYMBOL(rec_event);
-+#ifdef CONFIG_CHOPSTIX
++EXPORT_SYMBOL(in_sched_functions);
+
+struct event_spec {
+ unsigned long pc;
/*
* schedule() is the main scheduler function.
*/
-@@ -5369,6 +5396,7 @@
+@@ -4482,6 +4514,54 @@ need_resched_nonpreemptible:
+ next = pick_next_task(rq, prev);
+
+ if (likely(prev != next)) {
++
++#ifdef CONFIG_CHOPSTIX
++ /* Run only if the Chopstix module so decrees it */
++ if (rec_event) {
++ unsigned long diff;
++ int sampling_reason;
++ prev->last_ran_j = jiffies;
++ if (next->last_interrupted!=INTERRUPTIBLE) {
++ if (next->last_interrupted!=RUNNING) {
++ diff = (jiffies-next->last_interrupted);
++ sampling_reason = 0;/* BLOCKING */
++ }
++ else {
++ diff = jiffies-next->last_ran_j;
++ sampling_reason = 1;/* PREEMPTION */
++ }
++
++ if (diff >= HZ/10) {
++ struct event event;
++ struct event_spec espec;
++ struct pt_regs *regs;
++ regs = task_pt_regs(current);
++
++ espec.reason = sampling_reason;
++ event.event_data=&espec;
++ event.task=next;
++ espec.pc=regs->ip;
++ event.event_type=2;
++ /* index in the event array currently set up */
++ /* make sure the counters are loaded in the order we want them to show up*/
++ (*rec_event)(&event, diff);
++ }
++ }
++ /* next has been elected to run */
++ next->last_interrupted=0;
++
++ /* An uninterruptible process just yielded. Record the current jiffy */
++ if (prev->state & TASK_UNINTERRUPTIBLE) {
++ prev->last_interrupted=jiffies;
++ }
++ /* An interruptible process just yielded, or it got preempted.
++ * Mark it as interruptible */
++ else if (prev->state & TASK_INTERRUPTIBLE) {
++ prev->last_interrupted=INTERRUPTIBLE;
++ }
++ }
++#endif
++
+ sched_info_switch(prev, next);
+
+ rq->nr_switches++;
+@@ -5369,6 +5449,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
get_task_struct(p);
read_unlock(&tasklist_lock);
retval = -EPERM;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
!capable(CAP_SYS_NICE))
-@@ -9296,3 +9324,26 @@
- .subsys_id = cpuacct_subsys_id,
- };
- #endif /* CONFIG_CGROUP_CPUACCT */
-+
-+#ifdef CONFIG_CHOPSTIX
-+void (*rec_event)();
-+EXPORT_SYMBOL(rec_event);
-+
-+struct event_spec {
-+ unsigned long pc;
-+ unsigned long dcookie;
-+ unsigned int count;
-+ unsigned int reason;
-+};
-+
-+/* To support safe calling from asm */
-+asmlinkage void rec_event_asm (struct event *event_signature_in, unsigned int count) {
-+ struct pt_regs *regs;
-+ struct event_spec *es = event_signature_in->event_data;
-+ regs = task_pt_regs(current);
-+ event_signature_in->task=current;
-+ es->pc=regs->ip;
-+ event_signature_in->count=1;
-+ (*rec_event)(event_signature_in, count);
-+}
-+#endif
-diff -Nurb linux-2.6.27-590/kernel/sched.c.rej linux-2.6.27-591/kernel/sched.c.rej
---- linux-2.6.27-590/kernel/sched.c.rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.27-591/kernel/sched.c.rej 2010-01-29 16:30:22.000000000 -0500
-@@ -0,0 +1,258 @@
-+***************
-+*** 23,28 ****
-+ #include <linux/nmi.h>
-+ #include <linux/init.h>
-+ #include <asm/uaccess.h>
-+ #include <linux/highmem.h>
-+ #include <linux/smp_lock.h>
-+ #include <asm/mmu_context.h>
-+--- 23,29 ----
-+ #include <linux/nmi.h>
-+ #include <linux/init.h>
-+ #include <asm/uaccess.h>
-++ #include <linux/arrays.h>
-+ #include <linux/highmem.h>
-+ #include <linux/smp_lock.h>
-+ #include <asm/mmu_context.h>
-+***************
-+*** 451,456 ****
-+
-+ repeat_lock_task:
-+ rq = task_rq(p);
-+ spin_lock(&rq->lock);
-+ if (unlikely(rq != task_rq(p))) {
-+ spin_unlock(&rq->lock);
-+--- 455,461 ----
-+
-+ repeat_lock_task:
-+ rq = task_rq(p);
-++
-+ spin_lock(&rq->lock);
-+ if (unlikely(rq != task_rq(p))) {
-+ spin_unlock(&rq->lock);
-+***************
-+*** 1761,1766 ****
-+ * event cannot wake it up and insert it on the runqueue either.
-+ */
-+ p->state = TASK_RUNNING;
-+
-+ /*
-+ * Make sure we do not leak PI boosting priority to the child:
-+--- 1766,1786 ----
-+ * event cannot wake it up and insert it on the runqueue either.
-+ */
-+ p->state = TASK_RUNNING;
-++ #ifdef CONFIG_CHOPSTIX
-++ /* The jiffy of last interruption */
-++ if (p->state & TASK_UNINTERRUPTIBLE) {
-++ p->last_interrupted=jiffies;
-++ }
-++ else
-++ if (p->state & TASK_INTERRUPTIBLE) {
-++ p->last_interrupted=INTERRUPTIBLE;
-++ }
-++ else
-++ p->last_interrupted=RUNNING;
-++
-++ /* The jiffy of last execution */
-++ p->last_ran_j=jiffies;
-++ #endif
-+
-+ /*
-+ * Make sure we do not leak PI boosting priority to the child:
-+***************
-+*** 3628,3633 ****
-+
-+ #endif
-+
-+ static inline int interactive_sleep(enum sleep_type sleep_type)
-+ {
-+ return (sleep_type == SLEEP_INTERACTIVE ||
-+--- 3648,3654 ----
-+
-+ #endif
-+
-++
-+ static inline int interactive_sleep(enum sleep_type sleep_type)
-+ {
-+ return (sleep_type == SLEEP_INTERACTIVE ||
-+***************
-+*** 3637,3652 ****
-+ /*
-+ * schedule() is the main scheduler function.
-+ */
-+ asmlinkage void __sched schedule(void)
-+ {
-+ struct task_struct *prev, *next;
-+ struct prio_array *array;
-+ struct list_head *queue;
-+ unsigned long long now;
-+- unsigned long run_time;
-+ int cpu, idx, new_prio;
-+ long *switch_count;
-+ struct rq *rq;
-+
-+ /*
-+ * Test if we are atomic. Since do_exit() needs to call into
-+--- 3658,3685 ----
-+ /*
-+ * schedule() is the main scheduler function.
-+ */
-++
-++ #ifdef CONFIG_CHOPSTIX
-++ extern void (*rec_event)(void *,unsigned int);
-++ struct event_spec {
-++ unsigned long pc;
-++ unsigned long dcookie;
-++ unsigned int count;
-++ unsigned int reason;
-++ };
-++ #endif
-++
-+ asmlinkage void __sched schedule(void)
-+ {
-+ struct task_struct *prev, *next;
-+ struct prio_array *array;
-+ struct list_head *queue;
-+ unsigned long long now;
-++ unsigned long run_time, diff;
-+ int cpu, idx, new_prio;
-+ long *switch_count;
-+ struct rq *rq;
-++ int sampling_reason;
-+
-+ /*
-+ * Test if we are atomic. Since do_exit() needs to call into
-+***************
-+*** 3700,3705 ****
-+ switch_count = &prev->nivcsw;
-+ if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
-+ switch_count = &prev->nvcsw;
-+ if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
-+ unlikely(signal_pending(prev))))
-+ prev->state = TASK_RUNNING;
-+--- 3733,3739 ----
-+ switch_count = &prev->nivcsw;
-+ if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
-+ switch_count = &prev->nvcsw;
-++
-+ if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
-+ unlikely(signal_pending(prev))))
-+ prev->state = TASK_RUNNING;
-+***************
-+*** 3709,3714 ****
-+ vx_uninterruptible_inc(prev);
-+ }
-+ deactivate_task(prev, rq);
-+ }
-+ }
-+
-+--- 3743,3759 ----
-+ vx_uninterruptible_inc(prev);
-+ }
-+ deactivate_task(prev, rq);
-++ #ifdef CONFIG_CHOPSTIX
-++ /* An uninterruptible process just yielded. Record the current jiffie */
-++ if (prev->state & TASK_UNINTERRUPTIBLE) {
-++ prev->last_interrupted=jiffies;
-++ }
-++ /* An interruptible process just yielded, or it got preempted.
-++ * Mark it as interruptible */
-++ else if (prev->state & TASK_INTERRUPTIBLE) {
-++ prev->last_interrupted=INTERRUPTIBLE;
-++ }
-++ #endif
-+ }
-+ }
-+
-+***************
-+*** 3785,3790 ****
-+ prev->sleep_avg = 0;
-+ prev->timestamp = prev->last_ran = now;
-+
-+ sched_info_switch(prev, next);
-+ if (likely(prev != next)) {
-+ next->timestamp = next->last_ran = now;
-+--- 3830,3869 ----
-+ prev->sleep_avg = 0;
-+ prev->timestamp = prev->last_ran = now;
-+
-++ #ifdef CONFIG_CHOPSTIX
-++ /* Run only if the Chopstix module so decrees it */
-++ if (rec_event) {
-++ prev->last_ran_j = jiffies;
-++ if (next->last_interrupted!=INTERRUPTIBLE) {
-++ if (next->last_interrupted!=RUNNING) {
-++ diff = (jiffies-next->last_interrupted);
-++ sampling_reason = 0;/* BLOCKING */
-++ }
-++ else {
-++ diff = jiffies-next->last_ran_j;
-++ sampling_reason = 1;/* PREEMPTION */
-++ }
-++
-++ if (diff >= HZ/10) {
-++ struct event event;
-++ struct event_spec espec;
-++ struct pt_regs *regs;
-++ regs = task_pt_regs(current);
-++
-++ espec.reason = sampling_reason;
-++ event.event_data=&espec;
-++ event.task=next;
-++ espec.pc=regs->eip;
-++ event.event_type=2;
-++ /* index in the event array currently set up */
-++ /* make sure the counters are loaded in the order we want them to show up*/
-++ (*rec_event)(&event, diff);
-++ }
-++ }
-++ /* next has been elected to run */
-++ next->last_interrupted=0;
-++ }
-++ #endif
-+ sched_info_switch(prev, next);
-+ if (likely(prev != next)) {
-+ next->timestamp = next->last_ran = now;
-+***************
-+*** 5737,5742 ****
-+ jiffies_to_timespec(p->policy == SCHED_FIFO ?
-+ 0 : task_timeslice(p), &t);
-+ read_unlock(&tasklist_lock);
-+ retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
-+ out_nounlock:
-+ return retval;
-+--- 5817,5823 ----
-+ jiffies_to_timespec(p->policy == SCHED_FIFO ?
-+ 0 : task_timeslice(p), &t);
-+ read_unlock(&tasklist_lock);
-++
-+ retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
-+ out_nounlock:
-+ return retval;
-+***************
-+*** 7980,7982 ****
-+ }
-+
-+ #endif
-+--- 8061,8080 ----
-+ }
-+
-+ #endif
-++
-++ #ifdef CONFIG_CHOPSTIX
-++ void (*rec_event)(void *,unsigned int) = NULL;
-++
-++ /* To support safe calling from asm */
-++ asmlinkage void rec_event_asm (struct event *event_signature_in, unsigned int count) {
-++ struct pt_regs *regs;
-++ struct event_spec *es = event_signature_in->event_data;
-++ regs = task_pt_regs(current);
-++ event_signature_in->task=current;
-++ es->pc=regs->eip;
-++ event_signature_in->count=1;
-++ (*rec_event)(event_signature_in, count);
-++ }
-++ EXPORT_SYMBOL(rec_event);
-++ EXPORT_SYMBOL(in_sched_functions);
-++ #endif
-diff -Nurb linux-2.6.27-590/mm/memory.c linux-2.6.27-591/mm/memory.c
---- linux-2.6.27-590/mm/memory.c 2010-01-29 16:29:48.000000000 -0500
-+++ linux-2.6.27-591/mm/memory.c 2010-01-31 22:21:18.000000000 -0500
+diff --git a/mm/memory.c b/mm/memory.c
+index a258b98..1c1a375 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
@@ -61,6 +61,7 @@
#include <linux/swapops.h>
#include "internal.h"
-@@ -2690,6 +2691,15 @@
+@@ -2753,6 +2754,16 @@ out:
return ret;
}
++#ifdef CONFIG_CHOPSTIX
+extern void (*rec_event)(void *,unsigned int);
+struct event_spec {
+ unsigned long pc;
+ unsigned count;
+ unsigned char reason;
+};
-+
++#endif
+
/*
* By the time we get here, we already hold the mm semaphore
*/
-@@ -2719,6 +2729,24 @@
+@@ -2782,6 +2793,24 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
if (!pte)
return VM_FAULT_OOM;
+ if (rec_event) {
+ struct event event;
+ struct event_spec espec;
-+ struct pt_regs *regs;
-+ unsigned int pc;
-+ regs = task_pt_regs(current);
-+ pc = regs->ip & (unsigned int) ~4095;
++ struct pt_regs *regs;
++ unsigned int pc;
++ regs = task_pt_regs(current);
++ pc = regs->ip & (unsigned int) ~4095;
+
+ espec.reason = 0; /* alloc */
+ event.event_data=&espec;
+ event.task = current;
+ espec.pc=pc;
-+ event.event_type=5;
++ event.event_type=6;
+ (*rec_event)(&event, 1);
+ }
+#endif
return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
}
-diff -Nurb linux-2.6.27-590/mm/slab.c linux-2.6.27-591/mm/slab.c
---- linux-2.6.27-590/mm/slab.c 2010-01-29 16:29:48.000000000 -0500
-+++ linux-2.6.27-591/mm/slab.c 2010-01-29 16:30:22.000000000 -0500
+diff --git a/mm/slab.c b/mm/slab.c
+index 88dd5a5..3486baa 100644
+--- a/mm/slab.c
++++ b/mm/slab.c
@@ -110,6 +110,7 @@
#include <linux/fault-inject.h>
#include <linux/rtmutex.h>
#include <linux/debugobjects.h>
#include <asm/cacheflush.h>
-@@ -248,6 +249,14 @@
+@@ -248,6 +249,16 @@ struct slab_rcu {
void *addr;
};
++#ifdef CONFIG_CHOPSTIX
+extern void (*rec_event)(void *,unsigned int);
+struct event_spec {
+ unsigned long pc;
+ unsigned count;
+ unsigned char reason;
+};
++#endif
+
/*
* struct array_cache
*
-@@ -3469,6 +3478,19 @@
+@@ -3469,6 +3480,19 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
local_irq_restore(save_flags);
objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);
prefetchw(objp);
+ event.event_data=&espec;
+ event.task = current;
+ espec.pc=caller;
-+ event.event_type=5;
++ event.event_type=4;
+ (*rec_event)(&event, cachep->buffer_size);
+ }
+#endif
if (unlikely((flags & __GFP_ZERO) && objp))
memset(objp, 0, obj_size(cachep));
-@@ -3578,12 +3600,26 @@
+@@ -3578,12 +3602,26 @@ free_done:
* Release an obj back to its cache. If the obj has a constructed state, it must
* be in this state _before_ it is released. Called with disabled ints.
*/
vx_slab_free(cachep);
/*
-@@ -3714,6 +3750,7 @@
- void *caller)
- {
- struct kmem_cache *cachep;
-+ void *ret;
-
- /* If you want to save a few bytes .text space: replace
- * __ with kmem_.
-@@ -3741,10 +3778,17 @@
+@@ -3741,10 +3779,17 @@ void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
EXPORT_SYMBOL(__kmalloc_track_caller);
#else
EXPORT_SYMBOL(__kmalloc);
#endif
-@@ -3764,7 +3808,7 @@
+@@ -3764,7 +3809,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
debug_check_no_locks_freed(objp, obj_size(cachep));
if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
debug_check_no_obj_freed(objp, obj_size(cachep));
local_irq_restore(flags);
}
EXPORT_SYMBOL(kmem_cache_free);
-@@ -3790,7 +3834,7 @@
+@@ -3790,7 +3835,7 @@ void kfree(const void *objp)
c = virt_to_cache(objp);
debug_check_no_locks_freed(objp, obj_size(c));
debug_check_no_obj_freed(objp, obj_size(c));