+--- linux-2.6.22-590/mm/memory.c 2009-03-16 20:49:42.000000000 -0400
++++ linux-2.6.22-591/mm/memory.c 2009-03-16 20:58:59.000000000 -0400
+@@ -59,6 +59,7 @@
+
+ #include <linux/swapops.h>
+ #include <linux/elf.h>
++#include <linux/arrays.h>
+
+ #ifndef CONFIG_NEED_MULTIPLE_NODES
+ /* use the per-pgdat data instead for discontigmem - mbligh */
+@@ -2601,6 +2602,15 @@
+ return ret;
+ }
+
++extern void (*rec_event)(void *,unsigned int);
++struct event_spec {
++ unsigned long pc;
++ unsigned long dcookie;
++ unsigned count;
++ unsigned char reason;
++};
++
++
+ /*
+ * By the time we get here, we already hold the mm semaphore
+ */
+@@ -2630,6 +2640,24 @@
+ if (!pte)
+ return VM_FAULT_OOM;
+
++#ifdef CONFIG_CHOPSTIX
++ if (rec_event) {
++ struct event event;
++ struct event_spec espec;
++ struct pt_regs *regs;
++ unsigned int pc;
++ regs = task_pt_regs(current);
++ pc = regs->eip & (unsigned int) ~4095;
++
++ espec.reason = 0; /* alloc */
++ event.event_data=&espec;
++ event.task = current;
++ espec.pc=pc;
++ event.event_type=5;
++ (*rec_event)(&event, 1);
++ }
++#endif
++
+ return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
+ }
+
+--- linux-2.6.22-590/mm/slab.c 2009-03-16 20:49:42.000000000 -0400
++++ linux-2.6.22-591/mm/slab.c 2009-03-16 21:00:27.000000000 -0400
+@@ -110,11 +110,13 @@
+ #include <linux/fault-inject.h>
+ #include <linux/rtmutex.h>
+ #include <linux/reciprocal_div.h>
++#include <linux/arrays.h>
+
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
+ #include <asm/page.h>
+
++
+ /*
+ * DEBUG - 1 for kmem_cache_create() to honour; SLAB_RED_ZONE & SLAB_POISON.
+ * 0 for faster, smaller code (especially in the critical paths).
+@@ -249,6 +251,14 @@
+ void *addr;
+ };
+
++extern void (*rec_event)(void *,unsigned int);
++struct event_spec {
++ unsigned long pc;
++ unsigned long dcookie;
++ unsigned count;
++ unsigned char reason;
++};
++
+ /*
+ * struct array_cache
+ *
+@@ -3443,6 +3453,19 @@
+ local_irq_restore(save_flags);
+ objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);
+ prefetchw(objp);
++#ifdef CONFIG_CHOPSTIX
++ if (rec_event && objp) {
++ struct event event;
++ struct event_spec espec;
++
++ espec.reason = 0; /* alloc */
++ event.event_data=&espec;
++ event.task = current;
++ espec.pc=caller;
++ event.event_type=5;
++ (*rec_event)(&event, cachep->buffer_size);
++ }
++#endif
+
+ return objp;
+ }
+@@ -3549,12 +3572,26 @@
+ * 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.
+ */
+-static inline void __cache_free(struct kmem_cache *cachep, void *objp)
++static inline void __cache_free(struct kmem_cache *cachep, void *objp, void *caller)
+ {
+ struct array_cache *ac = cpu_cache_get(cachep);
+
+ check_irq_off();
+- objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
++ objp = cache_free_debugcheck(cachep, objp, caller);
++ #ifdef CONFIG_CHOPSTIX
++ if (rec_event && objp) {
++ struct event event;
++ struct event_spec espec;
++
++ espec.reason = 1; /* free */
++ event.event_data=&espec;
++ event.task = current;
++ espec.pc=caller;
++ event.event_type=4;
++ (*rec_event)(&event, cachep->buffer_size);
++ }
++ #endif
++
+ vx_slab_free(cachep);
+
+ if (cache_free_alien(cachep, objp))
+@@ -3651,16 +3688,19 @@
+ __builtin_return_address(0));
+ }
+ EXPORT_SYMBOL(kmem_cache_alloc_node);
+-
+ static __always_inline void *
+ __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
+ {
+ struct kmem_cache *cachep;
++ void *ret;
++
+
+ cachep = kmem_find_general_cachep(size, flags);
+ if (unlikely(cachep == NULL))
+ return NULL;
+- return kmem_cache_alloc_node(cachep, flags, node);
++ ret = kmem_cache_alloc_node(cachep, flags, node);
++
++ return ret;
+ }
+
+ #ifdef CONFIG_DEBUG_SLAB
+@@ -3696,6 +3736,7 @@
+ void *caller)
+ {
+ struct kmem_cache *cachep;
++ void *ret;
+
+ /* If you want to save a few bytes .text space: replace
+ * __ with kmem_.
+@@ -3705,9 +3746,10 @@
+ cachep = __find_general_cachep(size, flags);
+ if (unlikely(cachep == NULL))
+ return NULL;
+- return __cache_alloc(cachep, flags, caller);
+-}
++ ret = __cache_alloc(cachep, flags, caller);
+
++ return ret;
++}
+
+ #ifdef CONFIG_DEBUG_SLAB
+ void *__kmalloc(size_t size, gfp_t flags)
+@@ -3723,10 +3765,17 @@
+ EXPORT_SYMBOL(__kmalloc_track_caller);
+
+ #else
++#ifdef CONFIG_CHOPSTIX
++void *__kmalloc(size_t size, gfp_t flags)
++{
++ return __do_kmalloc(size, flags, __builtin_return_address(0));
++}
++#else
+ void *__kmalloc(size_t size, gfp_t flags)
+ {
+ return __do_kmalloc(size, flags, NULL);
+ }
++#endif
+ EXPORT_SYMBOL(__kmalloc);
+ #endif
+
+@@ -3792,7 +3841,7 @@
+
+ local_irq_save(flags);
+ debug_check_no_locks_freed(objp, obj_size(cachep));
+- __cache_free(cachep, objp);
++ __cache_free(cachep, objp,__builtin_return_address(0));
+ local_irq_restore(flags);
+ }
+ EXPORT_SYMBOL(kmem_cache_free);
+@@ -3817,7 +3866,7 @@
+ kfree_debugcheck(objp);
+ c = virt_to_cache(objp);
+ debug_check_no_locks_freed(objp, obj_size(c));
+- __cache_free(c, (void *)objp);
++ __cache_free(c, (void *)objp,__builtin_return_address(0));
+ local_irq_restore(flags);
+ }
+ EXPORT_SYMBOL(kfree);
+