Setting tag linux-2.6-22-50
[linux-2.6.git] / linux-2.6-590-chopstix-intern.patch
1 diff -Nurb --exclude='*.cmd' --exclude='*.orig' --exclude='*.swp' --exclude=tags --exclude='*.patch' --exclude='*.diff' --exclude='*.svn*' linux-2.6.22-590/arch/i386/Kconfig linux-2.6.22-591/arch/i386/Kconfig
2 --- linux-2.6.22-590/arch/i386/Kconfig  2009-03-16 20:49:42.000000000 -0400
3 +++ linux-2.6.22-591/arch/i386/Kconfig  2009-03-16 20:58:59.000000000 -0400
4 @@ -1217,6 +1217,14 @@
5  
6  source "arch/i386/oprofile/Kconfig"
7  
8 +config CHOPSTIX
9 +       bool "Chopstix (PlanetLab)"
10 +       depends on MODULES && OPROFILE
11 +       help
12 +         Chopstix allows you to monitor various events by summarizing them
13 +         in lossy data structures and transferring these data structures
14 +         into user space. If in doubt, say "N".
15 +
16  config KPROBES
17         bool "Kprobes (EXPERIMENTAL)"
18         depends on KALLSYMS && EXPERIMENTAL && MODULES
19 --- linux-2.6.22-590/arch/i386/kernel/asm-offsets.c     2007-07-08 19:32:17.000000000 -0400
20 +++ linux-2.6.22-591/arch/i386/kernel/asm-offsets.c     2009-03-16 20:58:59.000000000 -0400
21 @@ -9,6 +9,7 @@
22  #include <linux/signal.h>
23  #include <linux/personality.h>
24  #include <linux/suspend.h>
25 +#include <linux/arrays.h>
26  #include <asm/ucontext.h>
27  #include "sigframe.h"
28  #include <asm/pgtable.h>
29 @@ -25,9 +26,19 @@
30  #define OFFSET(sym, str, mem) \
31         DEFINE(sym, offsetof(struct str, mem));
32  
33 +#define STACKOFFSET(sym, str, mem) \
34 +       DEFINE(sym, offsetof(struct str, mem)-sizeof(struct str));
35 +
36  /* workaround for a warning with -Wmissing-prototypes */
37  void foo(void);
38  
39 +struct event_spec {
40 +       unsigned long pc;
41 +       unsigned long dcookie;
42 +       unsigned count;
43 +       unsigned int number;
44 +};
45 +
46  void foo(void)
47  {
48         OFFSET(SIGCONTEXT_eax, sigcontext, eax);
49 @@ -51,7 +62,16 @@
50         OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
51         BLANK();
52  
53 -       OFFSET(TI_task, thread_info, task);
54 +    STACKOFFSET(TASK_thread, task_struct, thread);
55 +    STACKOFFSET(THREAD_esp, thread_struct, esp);
56 +    STACKOFFSET(EVENT_event_data, event, event_data);
57 +    STACKOFFSET(EVENT_task, event, task);
58 +    STACKOFFSET(EVENT_event_type, event, event_type);
59 +    STACKOFFSET(SPEC_number, event_spec, number);
60 +    DEFINE(EVENT_SIZE, sizeof(struct event));
61 +    DEFINE(SPEC_SIZE, sizeof(struct event_spec));
62 +    DEFINE(SPEC_EVENT_SIZE, sizeof(struct event_spec)+sizeof(struct event));
63 +
64         OFFSET(TI_exec_domain, thread_info, exec_domain);
65         OFFSET(TI_flags, thread_info, flags);
66         OFFSET(TI_status, thread_info, status);
67 --- linux-2.6.22-590/arch/i386/kernel/entry.S   2009-03-16 20:49:07.000000000 -0400
68 +++ linux-2.6.22-591/arch/i386/kernel/entry.S   2009-03-16 20:58:59.000000000 -0400
69 @@ -374,6 +374,33 @@
70         cmpl $(nr_syscalls), %eax
71         jae syscall_badsys
72  syscall_call:
73 +    /* Move Chopstix syscall probe here */
74 +    /* Save and clobber: eax, ecx, ebp  */
75 +    pushl   %eax
76 +    pushl   %ecx
77 +    pushl   %ebp
78 +    movl    %esp, %ebp
79 +    subl    $SPEC_EVENT_SIZE, %esp 
80 +    movl    rec_event, %ecx
81 +    testl   %ecx, %ecx
82 +    jz  carry_on
83 +    # struct event is first, just below %ebp
84 +    movl    %eax, (SPEC_number-EVENT_SIZE)(%ebp)
85 +    leal    -SPEC_EVENT_SIZE(%ebp), %eax
86 +    movl    %eax, EVENT_event_data(%ebp)
87 +    movl    $6, EVENT_event_type(%ebp)
88 +    movl    rec_event, %edx
89 +    movl    $1, 4(%esp)
90 +    leal    -EVENT_SIZE(%ebp), %eax
91 +    movl    %eax, (%esp)
92 +    call    rec_event_asm 
93 +carry_on: 
94 +    addl $SPEC_EVENT_SIZE, %esp
95 +    popl %ebp
96 +    popl %ecx
97 +    popl %eax
98 +     /* End chopstix */
99 +
100         call *sys_call_table(,%eax,4)
101         movl %eax,PT_EAX(%esp)          # store the return value
102  syscall_exit:
103 --- linux-2.6.22-590/arch/i386/mm/fault.c       2009-03-16 20:49:42.000000000 -0400
104 +++ linux-2.6.22-591/arch/i386/mm/fault.c       2009-03-16 20:58:59.000000000 -0400
105 @@ -60,6 +60,15 @@
106                                           DIE_PAGE_FAULT, &args);
107  }
108  
109 +
110 +extern void (*rec_event)(void *,unsigned int);
111 +struct event_spec {
112 +       unsigned long pc;
113 +       unsigned long dcookie; 
114 +       unsigned count;
115 +       unsigned char reason;
116 +};
117 +
118  /*
119   * Return EIP plus the CS segment base.  The segment limit is also
120   * adjusted, clamped to the kernel/user address space (whichever is
121 @@ -296,6 +305,8 @@
122   *     bit 3 == 1 means use of reserved bit detected
123   *     bit 4 == 1 means fault was an instruction fetch
124   */
125 +
126 +
127  fastcall void __kprobes do_page_fault(struct pt_regs *regs,
128                                       unsigned long error_code)
129  {
130 --- linux-2.6.22-590/block/ll_rw_blk.c  2009-03-16 20:49:07.000000000 -0400
131 +++ linux-2.6.22-591/block/ll_rw_blk.c  2009-03-16 20:58:59.000000000 -0400
132 @@ -30,6 +30,7 @@
133  #include <linux/cpu.h>
134  #include <linux/blktrace_api.h>
135  #include <linux/fault-inject.h>
136 +#include <linux/arrays.h>
137  
138  /*
139   * for max sense size
140 @@ -3102,6 +3103,13 @@
141  
142  #endif /* CONFIG_FAIL_MAKE_REQUEST */
143  
144 +extern void (*rec_event)(void *,unsigned int);
145 +struct event_spec {
146 +       unsigned long pc;
147 +       unsigned long dcookie;
148 +       unsigned count;
149 +       unsigned char reason;
150 +};
151  /**
152   * generic_make_request: hand a buffer to its device driver for I/O
153   * @bio:  The bio describing the location in memory and on the device.
154 @@ -3220,7 +3228,23 @@
155                                 goto end_io;
156                         }
157                 }
158 -
159 +#ifdef CONFIG_CHOPSTIX
160 +               if (rec_event) {
161 +                       struct event event;
162 +                       struct event_spec espec;
163 +                       unsigned long eip;
164 +                       
165 +                       espec.reason = 0;/*request */
166 +
167 +                       eip = bio->bi_end_io;
168 +                       event.event_data=&espec;
169 +                       espec.pc=eip;
170 +                       event.event_type=3; 
171 +                       /* index in the event array currently set up */
172 +                       /* make sure the counters are loaded in the order we want them to show up*/ 
173 +                       (*rec_event)(&event, bio->bi_size);
174 +               }
175 +#endif
176                 ret = q->make_request_fn(q, bio);
177         } while (ret);
178  }
179 --- linux-2.6.22-590/drivers/oprofile/cpu_buffer.c      2007-07-08 19:32:17.000000000 -0400
180 +++ linux-2.6.22-591/drivers/oprofile/cpu_buffer.c      2009-03-16 20:58:59.000000000 -0400
181 @@ -21,6 +21,7 @@
182  #include <linux/oprofile.h>
183  #include <linux/vmalloc.h>
184  #include <linux/errno.h>
185 +#include <linux/arrays.h>
186   
187  #include "event_buffer.h"
188  #include "cpu_buffer.h"
189 @@ -143,6 +144,17 @@
190                 b->head_pos = 0;
191  }
192  
193 +#ifdef CONFIG_CHOPSTIX
194 +
195 +struct event_spec {
196 +       unsigned int pc;
197 +       unsigned long dcookie;
198 +       unsigned count;
199 +};
200 +
201 +extern void (*rec_event)(void *,unsigned int);
202 +#endif
203 +
204  static inline void
205  add_sample(struct oprofile_cpu_buffer * cpu_buf,
206             unsigned long pc, unsigned long event)
207 @@ -151,6 +163,7 @@
208         entry->eip = pc;
209         entry->event = event;
210         increment_head(cpu_buf);
211 +
212  }
213  
214  static inline void
215 @@ -241,8 +254,28 @@
216  {
217         int is_kernel = !user_mode(regs);
218         unsigned long pc = profile_pc(regs);
219 +       int res=0;
220  
221 +#ifdef CONFIG_CHOPSTIX
222 +       if (rec_event) {
223 +               struct event esig;
224 +               struct event_spec espec;
225 +               esig.task = current;
226 +               espec.pc=pc;
227 +               espec.count=1;
228 +               esig.event_data=&espec;
229 +               esig.event_type=event; /* index in the event array currently set up */
230 +                                       /* make sure the counters are loaded in the order we want them to show up*/ 
231 +               (*rec_event)(&esig, 1);
232 +       }
233 +       else {
234         oprofile_add_ext_sample(pc, regs, event, is_kernel);
235 +       }
236 +#else
237 +       oprofile_add_ext_sample(pc, regs, event, is_kernel);
238 +#endif
239 +
240 +
241  }
242  
243  void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
244 --- linux-2.6.22-590/fs/bio.c   2007-07-08 19:32:17.000000000 -0400
245 +++ linux-2.6.22-591/fs/bio.c   2009-03-16 20:58:59.000000000 -0400
246 @@ -27,6 +27,7 @@
247  #include <linux/workqueue.h>
248  #include <linux/blktrace_api.h>
249  #include <scsi/sg.h>           /* for struct sg_iovec */
250 +#include <linux/arrays.h>
251  
252  #define BIO_POOL_SIZE 2
253  
254 @@ -47,6 +48,7 @@
255         struct kmem_cache *slab;
256  };
257  
258 +
259  /*
260   * if you change this list, also change bvec_alloc or things will
261   * break badly! cannot be bigger than what you can fit into an
262 @@ -999,6 +1001,14 @@
263         }
264  }
265  
266 +struct event_spec {
267 +       unsigned long pc;
268 +       unsigned long dcookie;
269 +       unsigned count;
270 +       unsigned char reason;
271 +};
272 +
273 +extern void (*rec_event)(void *,unsigned int);
274  /**
275   * bio_endio - end I/O on a bio
276   * @bio:       bio
277 @@ -1028,6 +1038,24 @@
278         bio->bi_size -= bytes_done;
279         bio->bi_sector += (bytes_done >> 9);
280  
281 +#ifdef CONFIG_CHOPSTIX
282 +               if (rec_event) {
283 +                       struct event event;
284 +                       struct event_spec espec;
285 +                       unsigned long eip;
286 +                       
287 +                       espec.reason = 1;/*response */
288 +
289 +                       eip = bio->bi_end_io;
290 +                       event.event_data=&espec;
291 +                       espec.pc=eip;
292 +                       event.event_type=3; 
293 +                       /* index in the event array currently set up */
294 +                       /* make sure the counters are loaded in the order we want them to show up*/ 
295 +                       (*rec_event)(&event, bytes_done);
296 +               }
297 +#endif
298 +
299         if (bio->bi_end_io)
300                 bio->bi_end_io(bio, bytes_done, error);
301  }
302 --- linux-2.6.22-580/fs/exec.c  2009-04-08 16:36:16.000000000 -0400
303 +++ linux-2.6.22-590/fs/exec.c  2009-04-08 16:40:34.000000000 -0400
304 @@ -27,6 +27,7 @@
305  #include <linux/mman.h>
306  #include <linux/a.out.h>
307  #include <linux/stat.h>
308 +#include <linux/dcookies.h>
309  #include <linux/fcntl.h>
310  #include <linux/smp_lock.h>
311  #include <linux/init.h>
312 @@ -38,7 +39,7 @@
313  #include <linux/binfmts.h>
314  #include <linux/swap.h>
315  #include <linux/utsname.h>
316 -#include <linux/pid_namespace.h>
317 +/*#include <linux/pid_namespace.h>*/
318  #include <linux/module.h>
319  #include <linux/namei.h>
320  #include <linux/proc_fs.h>
321 @@ -488,6 +489,13 @@
322  
323         if (!err) {
324                 struct inode *inode = nd.dentry->d_inode;
325 +#ifdef CONFIG_CHOPSTIX
326 +               unsigned long cookie;
327 +        extern void (*rec_event)(void *, unsigned int);
328 +               if (rec_event && !nd.dentry->d_cookie)
329 +                       get_dcookie(nd.dentry, nd.mnt, &cookie);
330 +#endif
331 +
332                 file = ERR_PTR(-EACCES);
333                 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
334                     S_ISREG(inode->i_mode)) {
335 @@ -627,8 +635,10 @@
336          * Reparenting needs write_lock on tasklist_lock,
337          * so it is safe to do it under read_lock.
338          */
339 +       /*
340         if (unlikely(tsk->group_leader == child_reaper(tsk)))
341                 tsk->nsproxy->pid_ns->child_reaper = tsk;
342 +               */
343  
344         zap_other_threads(tsk);
345         read_unlock(&tasklist_lock);
346 --- linux-2.6.22-590/include/linux/arrays.h     1969-12-31 19:00:00.000000000 -0500
347 +++ linux-2.6.22-591/include/linux/arrays.h     2009-03-16 20:58:59.000000000 -0400
348 @@ -0,0 +1,36 @@
349 +#ifndef __ARRAYS_H__
350 +#define __ARRAYS_H__
351 +#include <linux/list.h>
352 +
353 +#define SAMPLING_METHOD_DEFAULT 0
354 +#define SAMPLING_METHOD_LOG 1
355 +
356 +/* Every probe has an array handler */
357 +
358 +/* XXX - Optimize this structure */
359 +
360 +extern void (*rec_event)(void *,unsigned int);
361 +struct array_handler {
362 +       struct list_head link;
363 +       unsigned int (*hash_func)(void *);
364 +       unsigned int (*sampling_func)(void *,int,void *);
365 +       unsigned short size;
366 +       unsigned int threshold;
367 +       unsigned char **expcount;
368 +       unsigned int sampling_method;
369 +       unsigned int **arrays;
370 +       unsigned int arraysize;
371 +       unsigned int num_samples[2];
372 +       void **epoch_samples; /* size-sized lists of samples */
373 +       unsigned int (*serialize)(void *, void *);
374 +       unsigned char code[5];
375 +};
376 +
377 +struct event {
378 +       struct list_head link;
379 +       void *event_data;
380 +       unsigned int count;
381 +       unsigned int event_type;
382 +       struct task_struct *task;
383 +};
384 +#endif
385 --- linux-2.6.22-590/include/linux/mutex.h      2007-07-08 19:32:17.000000000 -0400
386 +++ linux-2.6.22-591/include/linux/mutex.h      2009-03-16 20:58:59.000000000 -0400
387 @@ -53,6 +53,10 @@
388         struct thread_info      *owner;
389         const char              *name;
390         void                    *magic;
391 +#else
392 +#ifdef CONFIG_CHOPSTIX
393 +       struct thread_info      *owner;
394 +#endif
395  #endif
396  #ifdef CONFIG_DEBUG_LOCK_ALLOC
397         struct lockdep_map      dep_map;
398 --- linux-2.6.22-590/include/linux/sched.h      2009-03-16 20:49:42.000000000 -0400
399 +++ linux-2.6.22-591/include/linux/sched.h      2009-03-16 20:58:59.000000000 -0400
400 @@ -850,6 +850,10 @@
401  #endif
402         unsigned long sleep_avg;
403         unsigned long long timestamp, last_ran;
404 +#ifdef CONFIG_CHOPSTIX
405 +       unsigned long last_interrupted, last_ran_j;
406 +#endif
407 +
408         unsigned long long sched_time; /* sched_clock time spent running */
409         enum sleep_type sleep_type;
410  
411 --- linux-2.6.22-590/kernel/mutex.c     2007-07-08 19:32:17.000000000 -0400
412 +++ linux-2.6.22-591/kernel/mutex.c     2009-03-16 20:58:59.000000000 -0400
413 @@ -18,6 +18,17 @@
414  #include <linux/spinlock.h>
415  #include <linux/interrupt.h>
416  #include <linux/debug_locks.h>
417 +#include <linux/arrays.h>
418 +
419 +#undef CONFIG_CHOPSTIX
420 +#ifdef CONFIG_CHOPSTIX
421 +struct event_spec {
422 +       unsigned long pc;
423 +       unsigned long dcookie;
424 +       unsigned count;
425 +       unsigned char reason;
426 +};
427 +#endif
428  
429  /*
430   * In the DEBUG case we are using the "NULL fastpath" for mutexes,
431 @@ -43,6 +54,9 @@
432  __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
433  {
434         atomic_set(&lock->count, 1);
435 +#ifdef CONFIG_CHOPSTIX
436 +       lock->owner=NULL;
437 +#endif
438         spin_lock_init(&lock->wait_lock);
439         INIT_LIST_HEAD(&lock->wait_list);
440  
441 @@ -88,6 +102,7 @@
442          * The locking fastpath is the 1->0 transition from
443          * 'unlocked' into 'locked' state.
444          */
445 +
446         __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
447  }
448  
449 @@ -168,6 +183,27 @@
450                 }
451                 __set_task_state(task, state);
452  
453 +#ifdef CONFIG_CHOPSTIX
454 +               if (rec_event) {
455 +                       if (lock->owner) {
456 +                               struct event event;
457 +                               struct event_spec espec;
458 +                               struct task_struct *p = lock->owner->task;
459 +                               /*spin_lock(&p->alloc_lock);*/
460 +                               espec.reason = 0; /* lock */
461 +                               event.event_data=&espec;
462 +                               event.task = p;
463 +                               espec.pc=lock;
464 +                               event.event_type=5; 
465 +                               (*rec_event)(&event, 1);
466 +                               /*spin_unlock(&p->alloc_lock);*/
467 +
468 +                       }
469 +                       else 
470 +                               BUG();
471 +               }
472 +#endif
473 +
474                 /* didnt get the lock, go to sleep: */
475                 spin_unlock_mutex(&lock->wait_lock, flags);
476                 schedule();
477 @@ -177,6 +213,9 @@
478         /* got the lock - rejoice! */
479         mutex_remove_waiter(lock, &waiter, task_thread_info(task));
480         debug_mutex_set_owner(lock, task_thread_info(task));
481 +#ifdef CONFIG_CHOPSTIX
482 +       lock->owner = task_thread_info(task);
483 +#endif
484  
485         /* set it to 0 if there are no waiters left: */
486         if (likely(list_empty(&lock->wait_list)))
487 @@ -202,6 +241,7 @@
488  mutex_lock_nested(struct mutex *lock, unsigned int subclass)
489  {
490         might_sleep();
491 +
492         __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass);
493  }
494  
495 @@ -211,6 +251,7 @@
496  mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass)
497  {
498         might_sleep();
499 +
500         return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, subclass);
501  }
502  
503 @@ -246,6 +287,23 @@
504  
505                 debug_mutex_wake_waiter(lock, waiter);
506  
507 +#ifdef CONFIG_CHOPSTIX
508 +               if (rec_event) {
509 +                       if (lock->owner) {
510 +                               struct event event;
511 +                               struct event_spec espec;
512 +
513 +                               espec.reason = 1; /* unlock */
514 +                               event.event_data=&espec;
515 +                               event.task = lock->owner->task;
516 +                               espec.pc=lock;
517 +                               event.event_type=5; 
518 +                               (*rec_event)(&event, 1);
519 +                       }
520 +                       else 
521 +                               BUG();
522 +               }
523 +#endif
524                 wake_up_process(waiter->task);
525         }
526  
527 --- linux-2.6.22-590/kernel/sched.c     2009-03-16 20:49:42.000000000 -0400
528 +++ linux-2.6.22-591/kernel/sched.c     2009-03-16 20:58:59.000000000 -0400
529 @@ -10,7 +10,7 @@
530   *  1998-11-19 Implemented schedule_timeout() and related stuff
531   *             by Andrea Arcangeli
532   *  2002-01-04 New ultra-scalable O(1) scheduler by Ingo Molnar:
533 - *             hybrid priority-list and round-robin design with
534 + *             hybrid priority-list and round-robin deventn with
535   *             an array-switch method of distributing timeslices
536   *             and per-CPU runqueues.  Cleanups and useful suggestions
537   *             by Davide Libenzi, preemptible kernel bits by Robert Love.
538 @@ -23,6 +23,7 @@
539  #include <linux/nmi.h>
540  #include <linux/init.h>
541  #include <asm/uaccess.h>
542 +#include <linux/arrays.h>
543  #include <linux/highmem.h>
544  #include <linux/smp_lock.h>
545  #include <asm/mmu_context.h>
546 @@ -59,6 +60,9 @@
547  #include <linux/vs_sched.h>
548  #include <linux/vs_cvirt.h>
549  
550 +#define INTERRUPTIBLE   -1
551 +#define RUNNING         0
552 +
553  /*
554   * Scheduler clock - returns current time in nanosec units.
555   * This is default implementation.
556 @@ -431,6 +435,7 @@
557  
558  repeat_lock_task:
559         rq = task_rq(p);
560 +
561         spin_lock(&rq->lock);
562         if (unlikely(rq != task_rq(p))) {
563                 spin_unlock(&rq->lock);
564 @@ -1741,6 +1746,21 @@
565          * event cannot wake it up and insert it on the runqueue either.
566          */
567         p->state = TASK_RUNNING;
568 +#ifdef CONFIG_CHOPSTIX
569 +    /* The jiffy of last interruption */
570 +    if (p->state & TASK_UNINTERRUPTIBLE) {
571 +                               p->last_interrupted=jiffies;
572 +       }
573 +    else
574 +    if (p->state & TASK_INTERRUPTIBLE) {
575 +                               p->last_interrupted=INTERRUPTIBLE;
576 +       }
577 +    else
578 +           p->last_interrupted=RUNNING;
579 +
580 +    /* The jiffy of last execution */ 
581 +       p->last_ran_j=jiffies;
582 +#endif
583  
584         /*
585          * Make sure we do not leak PI boosting priority to the child:
586 @@ -3608,6 +3628,7 @@
587  
588  #endif
589  
590 +
591  static inline int interactive_sleep(enum sleep_type sleep_type)
592  {
593         return (sleep_type == SLEEP_INTERACTIVE ||
594 @@ -3617,16 +3638,28 @@
595  /*
596   * schedule() is the main scheduler function.
597   */
598 +
599 +#ifdef CONFIG_CHOPSTIX
600 +extern void (*rec_event)(void *,unsigned int);
601 +struct event_spec {
602 +       unsigned long pc;
603 +       unsigned long dcookie;
604 +       unsigned int count;
605 +       unsigned int reason;
606 +};
607 +#endif
608 +
609  asmlinkage void __sched schedule(void)
610  {
611         struct task_struct *prev, *next;
612         struct prio_array *array;
613         struct list_head *queue;
614         unsigned long long now;
615 -       unsigned long run_time;
616 +       unsigned long run_time, diff;
617         int cpu, idx, new_prio;
618         long *switch_count;
619         struct rq *rq;
620 +       int sampling_reason;
621  
622         /*
623          * Test if we are atomic.  Since do_exit() needs to call into
624 @@ -3680,6 +3713,7 @@
625         switch_count = &prev->nivcsw;
626         if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
627                 switch_count = &prev->nvcsw;
628 +
629                 if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
630                                 unlikely(signal_pending(prev))))
631                         prev->state = TASK_RUNNING;
632 @@ -3689,6 +3723,17 @@
633                                 vx_uninterruptible_inc(prev);
634                         }
635                         deactivate_task(prev, rq);
636 +#ifdef CONFIG_CHOPSTIX
637 +            /* An uninterruptible process just yielded. Record the current jiffie */
638 +                       if (prev->state & TASK_UNINTERRUPTIBLE) {
639 +                               prev->last_interrupted=jiffies;
640 +                       }
641 +            /* An interruptible process just yielded, or it got preempted. 
642 +             * Mark it as interruptible */
643 +                       else if (prev->state & TASK_INTERRUPTIBLE) {
644 +                               prev->last_interrupted=INTERRUPTIBLE;
645 +                       }
646 +#endif
647                 }
648         }
649  
650 @@ -3765,6 +3810,40 @@
651                 prev->sleep_avg = 0;
652         prev->timestamp = prev->last_ran = now;
653  
654 +#ifdef CONFIG_CHOPSTIX
655 +       /* Run only if the Chopstix module so decrees it */
656 +       if (rec_event) {
657 +               prev->last_ran_j = jiffies;
658 +               if (next->last_interrupted!=INTERRUPTIBLE) {
659 +                       if (next->last_interrupted!=RUNNING) {
660 +                               diff = (jiffies-next->last_interrupted);
661 +                               sampling_reason = 0;/* BLOCKING */
662 +                       }
663 +                       else {
664 +                               diff = jiffies-next->last_ran_j; 
665 +                               sampling_reason = 1;/* PREEMPTION */
666 +                       }
667 +
668 +                       if (diff >= HZ/10) {
669 +                               struct event event;
670 +                               struct event_spec espec;
671 +                struct pt_regs *regs;
672 +                regs = task_pt_regs(current);
673 +
674 +                               espec.reason = sampling_reason;
675 +                               event.event_data=&espec;
676 +                               event.task=next;
677 +                               espec.pc=regs->eip;
678 +                               event.event_type=2; 
679 +                               /* index in the event array currently set up */
680 +                               /* make sure the counters are loaded in the order we want them to show up*/ 
681 +                               (*rec_event)(&event, diff);
682 +                       }
683 +               }
684 +        /* next has been elected to run */
685 +               next->last_interrupted=0;
686 +       }
687 +#endif
688         sched_info_switch(prev, next);
689         if (likely(prev != next)) {
690                 next->timestamp = next->last_ran = now;
691 @@ -4664,6 +4743,7 @@
692         get_task_struct(p);
693         read_unlock(&tasklist_lock);
694  
695 +
696         retval = -EPERM;
697         if ((current->euid != p->euid) && (current->euid != p->uid) &&
698                         !capable(CAP_SYS_NICE))
699 @@ -5032,6 +5112,7 @@
700         jiffies_to_timespec(p->policy == SCHED_FIFO ?
701                                 0 : task_timeslice(p), &t);
702         read_unlock(&tasklist_lock);
703 +
704         retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
705  out_nounlock:
706         return retval;
707 @@ -7275,3 +7356,20 @@
708  }
709  
710  #endif
711 +
712 +#ifdef CONFIG_CHOPSTIX
713 +void (*rec_event)(void *,unsigned int) = NULL;
714 +
715 +/* To support safe calling from asm */
716 +asmlinkage void rec_event_asm (struct event *event_signature_in, unsigned int count) {
717 +    struct pt_regs *regs;
718 +    struct event_spec *es = event_signature_in->event_data;
719 +    regs = task_pt_regs(current);
720 +       event_signature_in->task=current;
721 +       es->pc=regs->eip;
722 +    event_signature_in->count=1;
723 +    (*rec_event)(event_signature_in, count);
724 +}
725 +EXPORT_SYMBOL(rec_event);
726 +EXPORT_SYMBOL(in_sched_functions);
727 +#endif
728 --- linux-2.6.22-590/mm/memory.c        2009-03-16 20:49:42.000000000 -0400
729 +++ linux-2.6.22-591/mm/memory.c        2009-03-16 20:58:59.000000000 -0400
730 @@ -59,6 +59,7 @@
731  
732  #include <linux/swapops.h>
733  #include <linux/elf.h>
734 +#include <linux/arrays.h>
735  
736  #ifndef CONFIG_NEED_MULTIPLE_NODES
737  /* use the per-pgdat data instead for discontigmem - mbligh */
738 @@ -2601,6 +2602,15 @@
739         return ret;
740  }
741  
742 +extern void (*rec_event)(void *,unsigned int);
743 +struct event_spec {
744 +       unsigned long pc;
745 +       unsigned long dcookie; 
746 +       unsigned count;
747 +       unsigned char reason;
748 +};
749 +
750 +
751  /*
752   * By the time we get here, we already hold the mm semaphore
753   */
754 @@ -2630,6 +2640,24 @@
755         if (!pte)
756                 return VM_FAULT_OOM;
757  
758 +#ifdef CONFIG_CHOPSTIX
759 +       if (rec_event) {
760 +               struct event event;
761 +               struct event_spec espec;
762 +        struct pt_regs *regs;
763 +        unsigned int pc;
764 +        regs = task_pt_regs(current);
765 +        pc = regs->eip & (unsigned int) ~4095;
766 +
767 +               espec.reason = 0; /* alloc */
768 +               event.event_data=&espec;
769 +               event.task = current;
770 +               espec.pc=pc;
771 +               event.event_type=5; 
772 +               (*rec_event)(&event, 1);
773 +       }
774 +#endif
775 +
776         return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
777  }
778  
779 --- linux-2.6.22-590/mm/slab.c  2009-03-16 20:49:42.000000000 -0400
780 +++ linux-2.6.22-591/mm/slab.c  2009-03-16 21:00:27.000000000 -0400
781 @@ -110,11 +110,13 @@
782  #include       <linux/fault-inject.h>
783  #include       <linux/rtmutex.h>
784  #include       <linux/reciprocal_div.h>
785 +#include <linux/arrays.h>
786  
787  #include       <asm/cacheflush.h>
788  #include       <asm/tlbflush.h>
789  #include       <asm/page.h>
790  
791 +
792  /*
793   * DEBUG       - 1 for kmem_cache_create() to honour; SLAB_RED_ZONE & SLAB_POISON.
794   *               0 for faster, smaller code (especially in the critical paths).
795 @@ -249,6 +251,14 @@
796         void *addr;
797  };
798  
799 +extern void (*rec_event)(void *,unsigned int);
800 +struct event_spec {
801 +       unsigned long pc;
802 +       unsigned long dcookie; 
803 +       unsigned count;
804 +       unsigned char reason;
805 +};
806 +
807  /*
808   * struct array_cache
809   *
810 @@ -3443,6 +3453,19 @@
811         local_irq_restore(save_flags);
812         objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);
813         prefetchw(objp);
814 +#ifdef CONFIG_CHOPSTIX
815 +       if (rec_event && objp) {
816 +               struct event event;
817 +               struct event_spec espec;
818 +
819 +               espec.reason = 0; /* alloc */
820 +               event.event_data=&espec;
821 +               event.task = current;
822 +               espec.pc=caller;
823 +               event.event_type=5; 
824 +               (*rec_event)(&event, cachep->buffer_size);
825 +       }
826 +#endif
827  
828         return objp;
829  }
830 @@ -3549,12 +3572,26 @@
831   * Release an obj back to its cache. If the obj has a constructed state, it must
832   * be in this state _before_ it is released.  Called with disabled ints.
833   */
834 -static inline void __cache_free(struct kmem_cache *cachep, void *objp)
835 +static inline void __cache_free(struct kmem_cache *cachep, void *objp, void *caller)
836  {
837         struct array_cache *ac = cpu_cache_get(cachep);
838  
839         check_irq_off();
840 -       objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
841 +       objp = cache_free_debugcheck(cachep, objp, caller);
842 + #ifdef CONFIG_CHOPSTIX
843 +       if (rec_event && objp) {
844 +               struct event event;
845 +               struct event_spec espec;
846 +  
847 +               espec.reason = 1; /* free */
848 +               event.event_data=&espec;
849 +               event.task = current;
850 +               espec.pc=caller;
851 +               event.event_type=4; 
852 +               (*rec_event)(&event, cachep->buffer_size);
853 +       }
854 + #endif
855 +
856         vx_slab_free(cachep);
857  
858         if (cache_free_alien(cachep, objp))
859 @@ -3651,16 +3688,19 @@
860                         __builtin_return_address(0));
861  }
862  EXPORT_SYMBOL(kmem_cache_alloc_node);
863 -
864  static __always_inline void *
865  __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
866  {
867         struct kmem_cache *cachep;
868 +       void *ret;
869 +
870  
871         cachep = kmem_find_general_cachep(size, flags);
872         if (unlikely(cachep == NULL))
873                 return NULL;
874 -       return kmem_cache_alloc_node(cachep, flags, node);
875 +       ret = kmem_cache_alloc_node(cachep, flags, node);
876 +       
877 +       return ret;
878  }
879  
880  #ifdef CONFIG_DEBUG_SLAB
881 @@ -3696,6 +3736,7 @@
882                                           void *caller)
883  {
884         struct kmem_cache *cachep;
885 +       void *ret;
886  
887         /* If you want to save a few bytes .text space: replace
888          * __ with kmem_.
889 @@ -3705,9 +3746,10 @@
890         cachep = __find_general_cachep(size, flags);
891         if (unlikely(cachep == NULL))
892                 return NULL;
893 -       return __cache_alloc(cachep, flags, caller);
894 -}
895 +       ret = __cache_alloc(cachep, flags, caller);
896  
897 +       return ret;
898 +}
899  
900  #ifdef CONFIG_DEBUG_SLAB
901  void *__kmalloc(size_t size, gfp_t flags)
902 @@ -3723,10 +3765,17 @@
903  EXPORT_SYMBOL(__kmalloc_track_caller);
904  
905  #else
906 +#ifdef CONFIG_CHOPSTIX
907 +void *__kmalloc(size_t size, gfp_t flags)
908 +{
909 +       return __do_kmalloc(size, flags, __builtin_return_address(0));
910 +}
911 +#else
912  void *__kmalloc(size_t size, gfp_t flags)
913  {
914         return __do_kmalloc(size, flags, NULL);
915  }
916 +#endif
917  EXPORT_SYMBOL(__kmalloc);
918  #endif
919  
920 @@ -3792,7 +3841,7 @@
921  
922         local_irq_save(flags);
923         debug_check_no_locks_freed(objp, obj_size(cachep));
924 -       __cache_free(cachep, objp);
925 +       __cache_free(cachep, objp,__builtin_return_address(0));
926         local_irq_restore(flags);
927  }
928  EXPORT_SYMBOL(kmem_cache_free);
929 @@ -3817,7 +3866,7 @@
930         kfree_debugcheck(objp);
931         c = virt_to_cache(objp);
932         debug_check_no_locks_freed(objp, obj_size(c));
933 -       __cache_free(c, (void *)objp);
934 +       __cache_free(c, (void *)objp,__builtin_return_address(0));
935         local_irq_restore(flags);
936  }
937  EXPORT_SYMBOL(kfree);
938