1 diff -Nurb linux-2.6.22-580/drivers/oprofile/cpu_buffer.c linux-2.6.22-590/drivers/oprofile/cpu_buffer.c
2 --- linux-2.6.22-580/drivers/oprofile/cpu_buffer.c 2007-07-08 19:32:17.000000000 -0400
3 +++ linux-2.6.22-590/drivers/oprofile/cpu_buffer.c 2008-02-27 13:53:47.000000000 -0500
5 #include <linux/oprofile.h>
6 #include <linux/vmalloc.h>
7 #include <linux/errno.h>
8 +#include <linux/arrays.h>
10 #include "event_buffer.h"
11 #include "cpu_buffer.h"
18 + unsigned long dcookie;
22 +extern void (*rec_event)(void *,unsigned int);
25 add_sample(struct oprofile_cpu_buffer * cpu_buf,
26 unsigned long pc, unsigned long event)
30 increment_head(cpu_buf);
36 oprofile_end_trace(cpu_buf);
39 +static int proc_pid_cmdline(struct task_struct *task, char * buffer)
43 + struct mm_struct *mm = get_task_mm(task);
47 + goto out_mm; /* Shh! No looking before we're done */
49 + len = mm->arg_end - mm->arg_start;
51 + if (len > PAGE_SIZE)
54 + res = access_process_vm(task, mm->arg_start, buffer, len, 0);
56 + // If the nul at the end of args has been overwritten, then
57 + // assume application is using setproctitle(3).
58 + if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
59 + len = strnlen(buffer, res);
63 + len = mm->env_end - mm->env_start;
64 + if (len > PAGE_SIZE - res)
65 + len = PAGE_SIZE - res;
66 + res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
67 + res = strnlen(buffer, res);
78 void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
80 int is_kernel = !user_mode(regs);
81 unsigned long pc = profile_pc(regs);
86 + struct event_spec espec;
87 + /*res = proc_pid_cmdline(current, espec->appname);*/
88 + esig.task = current;
91 + esig.event_data=&espec;
92 + esig.event_type=event; /* index in the event array currently set up */
93 + /* make sure the counters are loaded in the order we want them to show up*/
94 + (*rec_event)(&esig, 1);
97 oprofile_add_ext_sample(pc, regs, event, is_kernel);
101 void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
102 diff -Nurb linux-2.6.22-580/drivers/oprofile/oprof.c linux-2.6.22-590/drivers/oprofile/oprof.c
103 --- linux-2.6.22-580/drivers/oprofile/oprof.c 2007-07-08 19:32:17.000000000 -0400
104 +++ linux-2.6.22-590/drivers/oprofile/oprof.c 2008-02-27 13:48:29.000000000 -0500
107 static int timer = 0;
109 +extern void *rec_event;
111 int oprofile_setup(void)
115 * us missing task deaths and eventually oopsing
116 * when trying to process the event buffer.
118 - if ((err = sync_start()))
119 + if (err = sync_start())
123 diff -Nurb linux-2.6.22-580/fs/exec.c linux-2.6.22-590/fs/exec.c
124 --- linux-2.6.22-580/fs/exec.c 2008-02-27 13:46:38.000000000 -0500
125 +++ linux-2.6.22-590/fs/exec.c 2008-02-27 13:49:58.000000000 -0500
127 #include <linux/audit.h>
128 #include <linux/signalfd.h>
129 #include <linux/vs_memory.h>
130 +#include <linux/dcookies.h>
132 #include <asm/uaccess.h>
133 #include <asm/mmu_context.h>
137 struct inode *inode = nd.dentry->d_inode;
138 + unsigned long cookie;
139 + if (!nd.dentry->d_cookie)
140 + get_dcookie(nd.dentry, nd.mnt, &cookie);
142 file = ERR_PTR(-EACCES);
143 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
144 S_ISREG(inode->i_mode)) {
145 diff -Nurb linux-2.6.22-580/include/linux/arrays.h linux-2.6.22-590/include/linux/arrays.h
146 --- linux-2.6.22-580/include/linux/arrays.h 1969-12-31 19:00:00.000000000 -0500
147 +++ linux-2.6.22-590/include/linux/arrays.h 2008-02-27 13:48:29.000000000 -0500
149 +#ifndef __ARRAYS_H__
150 +#define __ARRAYS_H__
151 +#include <linux/list.h>
153 +#define SAMPLING_METHOD_DEFAULT 0
154 +#define SAMPLING_METHOD_LOG 1
156 +/* Every probe has an array handler */
158 +/* XXX - Optimize this structure */
160 +struct array_handler {
161 + struct list_head link;
162 + unsigned int (*hash_func)(void *);
163 + unsigned int (*sampling_func)(void *,int,void *);
164 + unsigned short size;
165 + unsigned int threshold;
166 + unsigned char **expcount;
167 + unsigned int sampling_method;
168 + unsigned int **arrays;
169 + unsigned int arraysize;
170 + unsigned int num_samples[2];
171 + void **epoch_samples; /* size-sized lists of samples */
172 + unsigned int (*serialize)(void *, void *);
173 + unsigned char code[5];
177 + struct list_head link;
179 + unsigned int count;
180 + unsigned int event_type;
181 + struct task_struct *task;
184 diff -Nurb linux-2.6.22-580/include/linux/sched.h linux-2.6.22-590/include/linux/sched.h
185 --- linux-2.6.22-580/include/linux/sched.h 2008-02-27 13:46:40.000000000 -0500
186 +++ linux-2.6.22-590/include/linux/sched.h 2008-02-27 13:48:29.000000000 -0500
188 unsigned int btrace_seq;
190 unsigned long sleep_avg;
191 - unsigned long long timestamp, last_ran;
192 + unsigned long long timestamp, last_ran, last_interrupted, last_ran_j;
193 unsigned long long sched_time; /* sched_clock time spent running */
194 enum sleep_type sleep_type;
196 diff -Nurb linux-2.6.22-580/kernel/fork.c linux-2.6.22-590/kernel/fork.c
197 --- linux-2.6.22-580/kernel/fork.c 2008-02-27 13:46:40.000000000 -0500
198 +++ linux-2.6.22-590/kernel/fork.c 2008-02-27 13:48:29.000000000 -0500
202 tsk->splice_pipe = NULL;
203 + //tsk->cmdline[0]='\0';
204 + tsk->last_interrupted = 0;
208 diff -Nurb linux-2.6.22-580/kernel/sched.c linux-2.6.22-590/kernel/sched.c
209 --- linux-2.6.22-580/kernel/sched.c 2008-02-27 13:46:40.000000000 -0500
210 +++ linux-2.6.22-590/kernel/sched.c 2008-02-27 14:08:26.000000000 -0500
212 * 1998-11-19 Implemented schedule_timeout() and related stuff
213 * by Andrea Arcangeli
214 * 2002-01-04 New ultra-scalable O(1) scheduler by Ingo Molnar:
215 - * hybrid priority-list and round-robin design with
216 + * hybrid priority-list and round-robin deventn with
217 * an array-switch method of distributing timeslices
218 * and per-CPU runqueues. Cleanups and useful suggestions
219 * by Davide Libenzi, preemptible kernel bits by Robert Love.
223 #include <asm/unistd.h>
224 +#include <linux/arrays.h>
225 #include <linux/vs_sched.h>
226 #include <linux/vs_cvirt.h>
228 @@ -3608,6 +3609,8 @@
232 +extern void (*rec_event)(void *,unsigned int);
234 static inline int interactive_sleep(enum sleep_type sleep_type)
236 return (sleep_type == SLEEP_INTERACTIVE ||
237 @@ -3617,16 +3620,51 @@
239 * schedule() is the main scheduler function.
244 + unsigned long dcookie;
246 + unsigned char reason;
249 +#define top_esp (THREAD_SIZE - sizeof(unsigned long))
250 +#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
252 +static inline unsigned long my_get_wchan(struct task_struct *p)
254 + unsigned long ebp, esp, eip;
255 + unsigned long stack_page;
257 + stack_page = (unsigned long)task_stack_page(p);
258 + esp = p->thread.esp;
259 + if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
261 + /* include/asm-i386/system.h:switch_to() pushes ebp last. */
262 + ebp = *(unsigned long *) esp;
264 + if (ebp < stack_page || ebp > top_ebp+stack_page)
266 + eip = *(unsigned long *) (ebp+4);
267 + if (!in_sched_functions(eip))
269 + ebp = *(unsigned long *) ebp;
270 + } while (count++ < 16);
275 asmlinkage void __sched schedule(void)
277 struct task_struct *prev, *next;
278 struct prio_array *array;
279 struct list_head *queue;
280 unsigned long long now;
281 - unsigned long run_time;
282 + unsigned long run_time, diff;
283 int cpu, idx, new_prio;
286 + int sampling_reason;
289 * Test if we are atomic. Since do_exit() needs to call into
290 @@ -3680,6 +3718,7 @@
291 switch_count = &prev->nivcsw;
292 if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
293 switch_count = &prev->nvcsw;
295 if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
296 unlikely(signal_pending(prev))))
297 prev->state = TASK_RUNNING;
298 @@ -3689,6 +3728,9 @@
299 vx_uninterruptible_inc(prev);
301 deactivate_task(prev, rq);
302 + if (prev->state & TASK_INTERRUPTIBLE) {
303 + prev->last_interrupted=jiffies;
308 @@ -3763,8 +3805,44 @@
309 prev->sleep_avg -= run_time;
310 if ((long)prev->sleep_avg <= 0)
313 prev->timestamp = prev->last_ran = now;
317 + prev->last_ran_j = jiffies;
318 + if (next->last_interrupted) {
319 + diff = (jiffies-next->last_interrupted);
320 + next->last_interrupted = 0;
321 + sampling_reason = 0;
324 + diff = jiffies-next->last_ran_j;
325 + sampling_reason = 1;
328 + if (rec_event && (diff>HZ/5)) {
329 + struct event event;
330 + struct event_spec espec;
332 + unsigned int state = next->state;
334 + espec.reason = sampling_reason;
337 + eip = next->thread.esp;
338 + next->state = state;
340 + next->last_interrupted = 0;
341 + event.event_data=&espec;
344 + event.event_type=2;
345 + /* index in the event array currently set up */
346 + /* make sure the counters are loaded in the order we want them to show up*/
347 + (*rec_event)(&event, diff);
350 sched_info_switch(prev, next);
351 if (likely(prev != next)) {
352 next->timestamp = next->last_ran = now;
353 @@ -7275,3 +7353,7 @@
358 +void (*rec_event)(void *,unsigned int);
359 +EXPORT_SYMBOL(rec_event);
360 +EXPORT_SYMBOL(in_sched_functions);
361 diff -Nurb linux-2.6.22-580/kernel/sched.c.rej linux-2.6.22-590/kernel/sched.c.rej
362 --- linux-2.6.22-580/kernel/sched.c.rej 1969-12-31 19:00:00.000000000 -0500
363 +++ linux-2.6.22-590/kernel/sched.c.rej 2008-02-27 13:48:29.000000000 -0500
368 + #include <asm/tlb.h>
369 + #include <asm/unistd.h>
372 + * Scheduler clock - returns current time in nanosec units.
375 + #include <asm/tlb.h>
376 + #include <asm/unistd.h>
377 ++ #include <linux/arrays.h>
382 + * Scheduler clock - returns current time in nanosec units.