diff -uNrp linux-2.6.14.5/arch/arm/kernel/entry-common.S linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/entry-common.S
--- linux-2.6.14.5/arch/arm/kernel/entry-common.S	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/entry-common.S	2006-01-22 13:01:13.514413936 +0100
@@ -21,6 +21,11 @@
  * stack.
  */
 ret_fast_syscall:
+#if (CONFIG_LTT)
+	mov r7, r0        @ save returned r0
+	bl  trace_real_syscall_exit
+	mov r0, r7
+#endif
 	disable_irq				@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
@@ -145,6 +150,16 @@ ENTRY(vector_swi)
 	mcr	p15, 0, ip, c1, c0		@ update control register
 #endif
 	enable_irq
+#if (CONFIG_LTT)
+	/* zzz note that validity of scno is not yet checked.
+	 * zzz The visualizer checks it.
+	 */
+	add	r1, sp, #S_R0			@ pointer to regs
+	mov	r0, scno  		        @ syscall number
+	bl	trace_real_syscall_entry
+	add	r1, sp, #S_R0			@ pointer to regs
+	ldmia	r1, {r0 - r3}			@ have to reload r0 - r3
+#endif
 
 	str	r4, [sp, #-S_OFF]!		@ push fifth arg
 
@@ -185,6 +200,9 @@ __sys_trace:
 
 __sys_trace_return:
 	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
+#if (CONFIG_LTT)
+	bl	trace_real_syscall_exit
+#endif
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	syscall_trace
diff -uNrp linux-2.6.14.5/arch/arm/kernel/irq.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/irq.c
--- linux-2.6.14.5/arch/arm/kernel/irq.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/irq.c	2006-01-22 13:01:13.537410440 +0100
@@ -35,6 +35,7 @@
 #include <linux/seq_file.h>
 #include <linux/errno.h>
 #include <linux/list.h>
+#include <linux/ltt-events.h>
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
 
@@ -536,6 +537,8 @@ asmlinkage void asm_do_IRQ(unsigned int 
 {
 	struct irqdesc *desc = irq_desc + irq;
 
+	ltt_ev_irq_entry(irq, !(user_mode(regs)));
+
 	/*
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
@@ -557,6 +560,8 @@ asmlinkage void asm_do_IRQ(unsigned int 
 
 	spin_unlock(&irq_controller_lock);
 	irq_exit();
+
+	ltt_ev_irq_exit();
 }
 
 void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained)
diff -uNrp linux-2.6.14.5/arch/arm/kernel/process.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/process.c
--- linux-2.6.14.5/arch/arm/kernel/process.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/process.c	2006-01-22 13:01:13.554407856 +0100
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/kallsyms.h>
 #include <linux/init.h>
+#include <linux/ltt-events.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -427,6 +428,7 @@ asm(	".section .text\n"
 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 	struct pt_regs regs;
+	long pid;
 
 	memset(&regs, 0, sizeof(regs));
 
@@ -436,7 +438,12 @@ pid_t kernel_thread(int (*fn)(void *), v
 	regs.ARM_pc = (unsigned long)kernel_thread_helper;
 	regs.ARM_cpsr = SVC_MODE;
 
-	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+	pid = do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+#if (CONFIG_LTT)
+	if(pid >= 0)
+		ltt_ev_process(LTT_EV_PROCESS_KTHREAD, pid, (int) fn);
+#endif
+	return pid;
 }
 EXPORT_SYMBOL(kernel_thread);
 
diff -uNrp linux-2.6.14.5/arch/arm/kernel/sys_arm.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/sys_arm.c
--- linux-2.6.14.5/arch/arm/kernel/sys_arm.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/sys_arm.c	2006-01-22 13:01:13.558407248 +0100
@@ -26,6 +26,7 @@
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
+#include <linux/ltt-events.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -160,6 +161,8 @@ asmlinkage int sys_ipc(uint call, int fi
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
 	switch (call) {
 	case SEMOP:
 		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
diff -uNrp linux-2.6.14.5/arch/arm/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/traps.c
--- linux-2.6.14.5/arch/arm/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/arm/kernel/traps.c	2006-01-22 13:01:13.560406944 +0100
@@ -20,6 +20,7 @@
 #include <linux/ptrace.h>
 #include <linux/kallsyms.h>
 #include <linux/init.h>
+#include <linux/ltt-events.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -198,6 +199,69 @@ void show_stack(struct task_struct *tsk,
 	barrier();
 }
 
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(int scno,struct pt_regs * regs)
+{
+	int			depth = 0;
+	unsigned long           end_code;
+	unsigned long		*fp;			/* frame pointer */
+	unsigned long		lower_bound;
+	unsigned long		lr;			/* link register */
+	unsigned long		*prev_fp;
+	int			seek_depth;
+	unsigned long           start_code;
+	unsigned long           *start_stack;
+	ltt_syscall_entry	trace_syscall_event;
+	unsigned long		upper_bound;
+	int			use_bounds;
+	int			use_depth;
+
+	trace_syscall_event.syscall_id = (uint8_t)scno;
+	trace_syscall_event.address    = instruction_pointer(regs);
+
+	if (! (user_mode(regs) ))
+		goto trace_syscall_end;
+
+	if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth,
+				(void*)&lower_bound, (void*)&upper_bound) < 0)
+		goto trace_syscall_end;
+
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		fp          = (unsigned long *)regs->ARM_fp;
+		end_code    = current->mm->end_code;
+		start_code  = current->mm->start_code;
+		start_stack = (unsigned long *)current->mm->start_stack;
+
+		while (!__get_user(lr, (unsigned long *)(fp - 1))) {
+			if ((lr > start_code) && (lr < end_code)) {
+				if (((use_depth == 1) && (depth >= seek_depth)) ||
+				    ((use_bounds == 1) && (lr > lower_bound) && (lr < upper_bound))) {
+					trace_syscall_event.address = lr;
+					goto trace_syscall_end;
+				} else {
+					depth++;
+				}
+			}
+
+			if ((__get_user((unsigned long)prev_fp, (fp - 3))) ||
+			    (prev_fp > start_stack) ||
+			    (prev_fp <= fp)) {
+				goto trace_syscall_end;
+			}
+			fp = prev_fp;
+		}
+	}
+
+trace_syscall_end:
+	ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+        ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+#endif /* (CONFIG_LTT) */
+
 DEFINE_SPINLOCK(die_lock);
 
 /*
@@ -236,8 +300,13 @@ void notify_die(const char *str, struct 
 	if (user_mode(regs)) {
 		current->thread.error_code = err;
 		current->thread.trap_no = trap;
-
+		
+		ltt_ev_trap_entry(current->thread.trap_no, (uint32_t)info->si_addr);
+		
 		force_sig_info(info->si_signo, info, current);
+
+		ltt_ev_trap_exit();
+		
 	} else {
 		die(str, regs, err);
 	}
diff -uNrp linux-2.6.14.5/arch/i386/Kconfig linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/Kconfig
--- linux-2.6.14.5/arch/i386/Kconfig	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/Kconfig	2006-01-22 13:01:13.000000000 +0100
@@ -521,6 +521,8 @@ config SCHED_SMT
 
 source "kernel/Kconfig.preempt"
 
+source "kernel/ipipe/Kconfig"
+
 config X86_UP_APIC
 	bool "Local APIC support on uniprocessors"
 	depends on !SMP && !(X86_VISWS || X86_VOYAGER)
@@ -984,7 +986,6 @@ config CRASH_DUMP
 	  Generate crash dump after being started by kexec.
 endmenu
 
-
 menu "Power management options (ACPI, APM)"
 	depends on !X86_VOYAGER
 
@@ -1305,6 +1306,8 @@ source "crypto/Kconfig"
 
 source "lib/Kconfig"
 
+source "ltt/Kconfig"
+
 #
 # Use the generic interrupt handling code in kernel/irq/:
 #
diff -uNrp linux-2.6.14.5/arch/i386/kernel/apic.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/apic.c
--- linux-2.6.14.5/arch/i386/kernel/apic.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/apic.c	2006-01-22 13:01:13.000000000 +0100
@@ -68,7 +68,7 @@ void ack_bad_irq(unsigned int irq)
 	 * unexpected vectors occur) that might lock up the APIC
 	 * completely.
 	 */
-	ack_APIC_irq();
+	__ack_APIC_irq();
 }
 
 void __init apic_intr_init(void)
@@ -1178,6 +1178,9 @@ inline void smp_local_timer_interrupt(st
 fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
+#ifdef CONFIG_IPIPE
+	regs =  __ipipe_tick_regs + cpu;
+#endif /* CONFIG_IPIPE */
 
 	/*
 	 * the NMI deadlock-detector uses this.
@@ -1214,7 +1217,7 @@ fastcall void smp_spurious_interrupt(str
 	 */
 	v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
 	if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
-		ack_APIC_irq();
+		__ack_APIC_irq();
 
 	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
 	printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
diff -uNrp linux-2.6.14.5/arch/i386/kernel/entry.S linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/entry.S
--- linux-2.6.14.5/arch/i386/kernel/entry.S	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/entry.S	2006-01-22 13:01:13.000000000 +0100
@@ -48,6 +48,7 @@
 #include <asm/smp.h>
 #include <asm/page.h>
 #include <asm/desc.h>
+#include <asm/ipipe.h>
 #include "irq_vectors.h"
 
 #define nr_syscalls ((syscall_table_size)/4)
@@ -75,11 +76,54 @@ DF_MASK		= 0x00000400 
 NT_MASK		= 0x00004000
 VM_MASK		= 0x00020000
 
+#ifdef CONFIG_IPIPE
+#define CLI                     call __ipipe_stall_root	;  sti
+#define STI                     call __ipipe_unstall_root
+#define STI_COND_HW             sti
+#define EMULATE_ROOT_IRET(bypass) \
+				call __ipipe_unstall_iret_root ; \
+				bypass: \
+				movl EAX(%esp),%eax
+#define TEST_PREEMPTIBLE(regs)  call __ipipe_kpreempt_root ; testl %eax,%eax
+#define restore_nocheck         unstall_and_restore_nocheck
+#define restore_nmi             restore_raw
+#define CATCH_ROOT_SYSCALL(bypass1,bypass2)	\
+				call __ipipe_syscall_root ; \
+				testl  %eax,%eax ; \
+				js    bypass1 ; \
+				jne   bypass2 ; \
+				movl ORIG_EAX(%esp),%eax
+#define PUSH_XCODE(v)		pushl $ ex_/**/v
+#define HANDLE_EXCEPTION(code)	movl %code,%ecx ; \
+				call __ipipe_handle_exception ; \
+				testl %eax,%eax	; \
+				jnz restore_raw
+#define DIVERT_EXCEPTION(code)	movl $(__USER_DS), %ecx	; \
+				movl %ecx, %ds ; \
+				movl %ecx, %es ; \
+				movl %esp, %eax	; \
+				movl $ex_/**/code,%edx ; \
+				call __ipipe_divert_exception ; \
+				testl %eax,%eax	; \
+				jnz restore_raw
+#else  /* !CONFIG_IPIPE */
+#define CLI                     cli
+#define STI                     sti
+#define STI_COND_HW
+#define EMULATE_ROOT_IRET(bypass)
+#define TEST_PREEMPTIBLE(regs)  testl $IF_MASK,EFLAGS(regs)
+#define restore_nmi             restore_all
+#define CATCH_ROOT_SYSCALL(bypass1,bypass2)
+#define PUSH_XCODE(v)		pushl $v
+#define HANDLE_EXCEPTION(code)	call *%code
+#define DIVERT_EXCEPTION(code)
+#endif /* CONFIG_IPIPE */
+
 #ifdef CONFIG_PREEMPT
-#define preempt_stop		cli
+#define preempt_stop	  CLI
 #else
 #define preempt_stop
-#define resume_kernel		restore_nocheck
+#define resume_kernel	  restore_nocheck
 #endif
 
 #define SAVE_ALL \
@@ -124,6 +168,7 @@ VM_MASK		= 0x00020000
 
 
 ENTRY(ret_from_fork)
+	STI_COND_HW
 	pushl %eax
 	call schedule_tail
 	GET_THREAD_INFO(%ebp)
@@ -141,14 +186,14 @@ ENTRY(ret_from_fork)
 	ALIGN
 ret_from_exception:
 	preempt_stop
-ret_from_intr:
+ENTRY(ret_from_intr)
 	GET_THREAD_INFO(%ebp)
 	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 	movb CS(%esp), %al
 	testl $(VM_MASK | 3), %eax
 	jz resume_kernel
 ENTRY(resume_userspace)
- 	cli				# make sure we don't miss an interrupt
+	CLI				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
 	movl TI_flags(%ebp), %ecx
@@ -159,14 +204,14 @@ ENTRY(resume_userspace)
 
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
-	cli
+	CLI
 	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
 	jnz restore_nocheck
 need_resched:
 	movl TI_flags(%ebp), %ecx	# need_resched set ?
 	testb $_TIF_NEED_RESCHED, %cl
 	jz restore_all
-	testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
+	TEST_PREEMPTIBLE(%esp)		# interrupts off (exception path) ?
 	jz restore_all
 	call preempt_schedule_irq
 	jmp need_resched
@@ -201,6 +246,7 @@ sysenter_past_esp:
 	pushl %eax
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
+	CATCH_ROOT_SYSCALL(sysenter_tail,sysenter_exit)
 
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
 	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
@@ -209,11 +255,13 @@ sysenter_past_esp:
 	jae syscall_badsys
 	call *sys_call_table(,%eax,4)
 	movl %eax,EAX(%esp)
-	cli
+sysenter_tail:
+	CLI
 	movl TI_flags(%ebp), %ecx
 	testw $_TIF_ALLWORK_MASK, %cx
 	jne syscall_exit_work
 /* if something modifies registers it must also disable sysexit */
+	EMULATE_ROOT_IRET(sysenter_exit)
 	movl EIP(%esp), %edx
 	movl OLDESP(%esp), %ecx
 	xorl %ebp,%ebp
@@ -226,6 +274,7 @@ ENTRY(system_call)
 	pushl %eax			# save orig_eax
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
+ 	CATCH_ROOT_SYSCALL(syscall_exit,restore_raw)
 					# system call tracing in operation / emulation
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
 	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
@@ -233,10 +282,22 @@ ENTRY(system_call)
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
 syscall_call:
+#if (CONFIG_LTT)
+ 	movl %esp, %eax                 # copy the stack pointer
+ 	pushl %eax                      # pass the stack pointer copy
+ 	call trace_real_syscall_entry
+ 	addl $4,%esp                    # return stack to state before pass
+no_syscall_entry_trace:
+ 	movl ORIG_EAX(%esp),%eax	# restore eax to it's original content
+#endif /* CONFIG_LTT */
 	call *sys_call_table(,%eax,4)
 	movl %eax,EAX(%esp)		# store the return value
 syscall_exit:
-	cli				# make sure we don't miss an interrupt
+#if (CONFIG_LTT)
+	call trace_real_syscall_exit
+no_syscall_exit_trace:
+#endif	/* CONFIG_LTT */
+ 	CLI				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
 	movl TI_flags(%ebp), %ecx
@@ -253,7 +314,15 @@ restore_all:
 	andl $(VM_MASK | (4 << 8) | 3), %eax
 	cmpl $((4 << 8) | 3), %eax
 	je ldt_ss			# returning to user-space with LDT SS
+#ifdef CONFIG_IPIPE
+unstall_and_restore_nocheck:
+	call __ipipe_unstall_iret_root
+restore_raw:
+	# FIXME: we need to check for a return to
+	# user-space on a 16bit stack even in the NMI case
+#else /* !CONFIG_IPIPE */
 restore_nocheck:
+#endif /* CONFIG_IPIPE */
 	RESTORE_REGS
 	addl $4, %esp
 1:	iret
@@ -261,7 +330,7 @@ restore_nocheck:
 iret_exc:
 	sti
 	pushl $0			# no error code
-	pushl $do_iret_error
+	PUSH_XCODE(do_iret_error)
 	jmp error_code
 .previous
 .section __ex_table,"a"
@@ -300,8 +369,9 @@ work_pending:
 	testb $_TIF_NEED_RESCHED, %cl
 	jz work_notifysig
 work_resched:
+	STI_COND_HW
 	call schedule
-	cli				# make sure we don't miss an interrupt
+	CLI				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
 	movl TI_flags(%ebp), %ecx
@@ -351,7 +421,7 @@ syscall_trace_entry:
 syscall_exit_work:
 	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
 	jz work_pending
-	sti				# could let do_syscall_trace() call
+	STI				# could let do_syscall_trace() call
 					# schedule() instead
 	movl %esp, %eax
 	movl $1, %edx
@@ -402,7 +472,7 @@ ENTRY(interrupt)
 
 vector=0
 ENTRY(irq_entries_start)
-.rept NR_IRQS
+.rept NR_XIRQS
 	ALIGN
 1:	pushl $vector-256
 	jmp common_interrupt
@@ -412,6 +482,28 @@ ENTRY(irq_entries_start)
 vector=vector+1
 .endr
 
+#ifdef CONFIG_IPIPE
+	ALIGN
+common_interrupt:
+	SAVE_ALL
+	call __ipipe_handle_irq
+	testl %eax,%eax
+	jnz  ret_from_intr
+	RESTORE_REGS
+	addl $4, %esp
+	iret	
+
+#define BUILD_INTERRUPT(name, nr)	\
+ENTRY(name)				\
+	pushl $nr-288;	/* nr - (256 + FIRST_EXTERNAL_VECTOR) */ \
+	SAVE_ALL;			\
+	call __ipipe_handle_irq;	\
+	testl %eax,%eax;		\
+	jnz  ret_from_intr;		\
+	RESTORE_REGS;			\
+	addl $4, %esp;			\
+	iret
+#else /* CONFIG_IPIPE */
 	ALIGN
 common_interrupt:
 	SAVE_ALL
@@ -426,13 +518,14 @@ ENTRY(name)				\
 	movl %esp,%eax;			\
 	call smp_/**/name;		\
 	jmp ret_from_intr;
+#endif /* CONFIG_IPIPE */
 
 /* The include is where all of the SMP etc. interrupts come from */
 #include "entry_arch.h"
 
 ENTRY(divide_error)
 	pushl $0			# no error code
-	pushl $do_divide_error
+	PUSH_XCODE(do_divide_error)
 	ALIGN
 error_code:
 	pushl %ds
@@ -457,22 +550,23 @@ error_code:
 	movl %ecx, %ds
 	movl %ecx, %es
 	movl %esp,%eax			# pt_regs pointer
-	call *%edi
+	HANDLE_EXCEPTION(edi)
 	jmp ret_from_exception
 
 ENTRY(coprocessor_error)
 	pushl $0
-	pushl $do_coprocessor_error
+	PUSH_XCODE(do_coprocessor_error)
 	jmp error_code
 
 ENTRY(simd_coprocessor_error)
 	pushl $0
-	pushl $do_simd_coprocessor_error
+	PUSH_XCODE(do_simd_coprocessor_error)
 	jmp error_code
 
 ENTRY(device_not_available)
 	pushl $-1			# mark this as an int
 	SAVE_ALL
+	DIVERT_EXCEPTION(device_not_available)
 	movl %cr0, %eax
 	testl $0x4, %eax		# EM (math emulation bit)
 	jne device_not_available_emulate
@@ -514,6 +608,7 @@ KPROBE_ENTRY(debug)
 debug_stack_correct:
 	pushl $-1			# mark this as an int
 	SAVE_ALL
+	DIVERT_EXCEPTION(do_debug)
 	xorl %edx,%edx			# error code 0
 	movl %esp,%eax			# pt_regs pointer
 	call do_debug
@@ -552,7 +647,7 @@ nmi_stack_correct:
 	xorl %edx,%edx		# zero error code
 	movl %esp,%eax		# pt_regs pointer
 	call do_nmi
-	jmp restore_all
+	jmp restore_nmi
 
 nmi_stack_fixup:
 	FIX_STACK(12,nmi_stack_correct, 1)
@@ -594,6 +689,7 @@ nmi_16bit_stack:
 KPROBE_ENTRY(int3)
 	pushl $-1			# mark this as an int
 	SAVE_ALL
+	DIVERT_EXCEPTION(do_int3)
 	xorl %edx,%edx		# zero error code
 	movl %esp,%eax		# pt_regs pointer
 	call do_int3
@@ -602,60 +698,60 @@ KPROBE_ENTRY(int3)
 
 ENTRY(overflow)
 	pushl $0
-	pushl $do_overflow
+	PUSH_XCODE(do_overflow)
 	jmp error_code
 
 ENTRY(bounds)
 	pushl $0
-	pushl $do_bounds
+	PUSH_XCODE(do_bounds)
 	jmp error_code
 
 ENTRY(invalid_op)
 	pushl $0
-	pushl $do_invalid_op
+	PUSH_XCODE(do_invalid_op)
 	jmp error_code
 
 ENTRY(coprocessor_segment_overrun)
 	pushl $0
-	pushl $do_coprocessor_segment_overrun
+	PUSH_XCODE(do_coprocessor_segment_overrun)
 	jmp error_code
 
 ENTRY(invalid_TSS)
-	pushl $do_invalid_TSS
+	PUSH_XCODE(do_invalid_TSS)
 	jmp error_code
 
 ENTRY(segment_not_present)
-	pushl $do_segment_not_present
+	PUSH_XCODE(do_segment_not_present)
 	jmp error_code
 
 ENTRY(stack_segment)
-	pushl $do_stack_segment
+	PUSH_XCODE(do_stack_segment)
 	jmp error_code
 
 KPROBE_ENTRY(general_protection)
-	pushl $do_general_protection
+	PUSH_XCODE(do_general_protection)
 	jmp error_code
 	.previous .text
 
 ENTRY(alignment_check)
-	pushl $do_alignment_check
+	PUSH_XCODE(do_alignment_check)
 	jmp error_code
 
 KPROBE_ENTRY(page_fault)
-	pushl $do_page_fault
+	PUSH_XCODE(do_page_fault)
 	jmp error_code
 	.previous .text
 
 #ifdef CONFIG_X86_MCE
 ENTRY(machine_check)
 	pushl $0
-	pushl machine_check_vector
+	PUSH_XCODE(machine_check_vector)
 	jmp error_code
 #endif
 
 ENTRY(spurious_interrupt_bug)
 	pushl $0
-	pushl $do_spurious_interrupt_bug
+	PUSH_XCODE(do_spurious_interrupt_bug)
 	jmp error_code
 
 #include "syscall_table.S"
diff -uNrp linux-2.6.14.5/arch/i386/kernel/i8259.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/i8259.c
--- linux-2.6.14.5/arch/i386/kernel/i8259.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/i8259.c	2006-01-22 13:01:13.000000000 +0100
@@ -89,13 +89,14 @@ void disable_8259A_irq(unsigned int irq)
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
+	ipipe_irq_lock(irq);
 	cached_irq_mask |= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 }
 
 void enable_8259A_irq(unsigned int irq)
@@ -103,13 +104,14 @@ void enable_8259A_irq(unsigned int irq)
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 	cached_irq_mask &= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	ipipe_irq_unlock(irq);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 }
 
 int i8259A_irq_pending(unsigned int irq)
@@ -118,12 +120,12 @@ int i8259A_irq_pending(unsigned int irq)
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 	if (irq < 8)
 		ret = inb(PIC_MASTER_CMD) & mask;
 	else
 		ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 
 	return ret;
 }
@@ -170,7 +172,7 @@ static void mask_and_ack_8259A(unsigned 
 	unsigned int irqmask = 1 << irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 	/*
 	 * Lightweight spurious IRQ detection. We do not want
 	 * to overdo spurious IRQ handling - it's usually a sign
@@ -188,6 +190,15 @@ static void mask_and_ack_8259A(unsigned 
 	 */
 	if (cached_irq_mask & irqmask)
 		goto spurious_8259A_irq;
+#ifdef CONFIG_IPIPE
+	if (irq == 0) {
+	    /* Fast timer ack -- don't mask (unless supposedly
+	      spurious) */
+	    outb(0x20,PIC_MASTER_CMD);
+	    spin_unlock_irqrestore_hw(&i8259A_lock, flags);
+	    return;
+	}
+#endif /* CONFIG_IPIPE */
 	cached_irq_mask |= irqmask;
 
 handle_real_irq:
@@ -201,7 +212,7 @@ handle_real_irq:
 		outb(cached_master_mask, PIC_MASTER_IMR);
 		outb(0x60+irq,PIC_MASTER_CMD);	/* 'Specific EOI to master */
 	}
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 	return;
 
 spurious_8259A_irq:
@@ -302,7 +313,7 @@ void init_8259A(int auto_eoi)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 
 	outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
 	outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */
@@ -336,7 +347,7 @@ void init_8259A(int auto_eoi)
 	outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
 	outb(cached_slave_mask, PIC_SLAVE_IMR);	  /* restore slave IRQ mask */
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 }
 
 /*
@@ -410,7 +421,7 @@ void __init init_IRQ(void)
 	 */
 	for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
 		int vector = FIRST_EXTERNAL_VECTOR + i;
-		if (i >= NR_IRQS)
+		if (i >= NR_XIRQS)
 			break;
 		if (vector != SYSCALL_VECTOR) 
 			set_intr_gate(vector, interrupt[i]);
diff -uNrp linux-2.6.14.5/arch/i386/kernel/io_apic.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/io_apic.c
--- linux-2.6.14.5/arch/i386/kernel/io_apic.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/io_apic.c	2006-01-22 13:01:13.000000000 +0100
@@ -177,18 +177,20 @@ static void mask_IO_APIC_irq (unsigned i
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
+	ipipe_irq_lock(irq);
 	__mask_IO_APIC_irq(irq);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 }
 
 static void unmask_IO_APIC_irq (unsigned int irq)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
+	ipipe_irq_unlock(irq);
 	__unmask_IO_APIC_irq(irq);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 }
 
 static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
@@ -197,10 +199,10 @@ static void clear_IO_APIC_pin(unsigned i
 	unsigned long flags;
 	
 	/* Check delivery_mode to be sure we're not clearing an SMI pin */
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	*(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
 	*(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 	if (entry.delivery_mode == dest_SMI)
 		return;
 
@@ -209,10 +211,10 @@ static void clear_IO_APIC_pin(unsigned i
 	 */
 	memset(&entry, 0, sizeof(entry));
 	entry.mask = 1;
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
 	io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 }
 
 static void clear_IO_APIC (void)
@@ -242,7 +244,7 @@ static void set_ioapic_affinity_irq(unsi
 	apicid_value = cpu_mask_to_apicid(cpumask);
 	/* Prepare to do the io_apic_write */
 	apicid_value = apicid_value << 24;
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	for (;;) {
 		pin = entry->pin;
 		if (pin == -1)
@@ -253,7 +255,7 @@ static void set_ioapic_affinity_irq(unsi
 		entry = irq_2_pin + entry->next;
 	}
 	set_irq_info(irq, cpumask);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 }
 
 #if defined(CONFIG_IRQBALANCE)
@@ -1238,11 +1240,11 @@ static void __init setup_IO_APIC_irqs(vo
 			if (!apic && (irq < 16))
 				disable_8259A_irq(irq);
 		}
-		spin_lock_irqsave(&ioapic_lock, flags);
+		spin_lock_irqsave_hw(&ioapic_lock, flags);
 		io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
 		io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
 		set_native_irq_info(irq, TARGET_CPUS);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
+		spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 	}
 	}
 
@@ -1286,10 +1288,10 @@ static void __init setup_ExtINT_IRQ0_pin
 	/*
 	 * Add it to the IO-APIC irq-routing table:
 	 */
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
 	io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 
 	enable_8259A_irq(0);
 }
@@ -1568,7 +1570,7 @@ void /*__init*/ print_PIC(void)
 
 	printk(KERN_DEBUG "\nprinting PIC contents\n");
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 
 	v = inb(0xa1) << 8 | inb(0x21);
 	printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
@@ -1582,7 +1584,7 @@ void /*__init*/ print_PIC(void)
 	outb(0x0a,0xa0);
 	outb(0x0a,0x20);
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 
 	printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
 
@@ -1838,14 +1840,15 @@ static unsigned int startup_edge_ioapic_
 	int was_pending = 0;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	if (irq < 16) {
 		disable_8259A_irq(irq);
 		if (i8259A_irq_pending(irq))
 			was_pending = 1;
 	}
 	__unmask_IO_APIC_irq(irq);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	ipipe_irq_unlock(irq);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 
 	return was_pending;
 }
@@ -1855,6 +1858,32 @@ static unsigned int startup_edge_ioapic_
  * interrupt for real. This prevents IRQ storms from unhandled
  * devices.
  */
+
+#ifdef CONFIG_IPIPE
+
+static void ack_edge_ioapic_irq (unsigned irq)
+
+{
+    if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
+					== (IRQ_PENDING | IRQ_DISABLED)) {
+	unsigned long flags;
+	spin_lock_irqsave_hw(&ioapic_lock,flags);
+	__mask_IO_APIC_irq(irq);
+	spin_unlock_irqrestore_hw(&ioapic_lock,flags);
+    }
+
+    __ack_APIC_irq();
+}
+
+#ifdef CONFIG_IRQBALANCE
+static void end_edge_ioapic_irq (unsigned irq)
+{
+	move_irq(irq);
+}
+#endif /* CONFIG_IRQBALANCE */
+
+#else /* !CONFIG_IPIPE */
+
 static void ack_edge_ioapic_irq(unsigned int irq)
 {
 	move_irq(irq);
@@ -1864,6 +1893,8 @@ static void ack_edge_ioapic_irq(unsigned
 	ack_APIC_irq();
 }
 
+#endif /* CONFIG_IPIPE */
+
 /*
  * Level triggered interrupts can just be masked,
  * and shutting down and starting up the interrupt
@@ -1885,6 +1916,82 @@ static unsigned int startup_level_ioapic
 	return 0; /* don't check for pending */
 }
 
+#ifdef CONFIG_IPIPE
+
+/* Prevent low priority IRQs grabbed by high priority domains from
+   being delayed, waiting for a high priority interrupt handler
+   running in a low priority domain to complete. */
+
+static unsigned long bugous_edge_triggers;
+
+static void end_level_ioapic_irq (unsigned irq)
+
+{
+	unsigned long flags;
+
+	move_irq(irq);
+
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
+
+	if (test_and_clear_bit(irq,&bugous_edge_triggers)) {
+		atomic_inc(&irq_mis_count);
+		__unmask_and_level_IO_APIC_irq(irq);
+	}
+	else
+		__unmask_IO_APIC_irq(irq);
+
+	ipipe_irq_unlock(irq);
+
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
+}
+
+static void mask_and_ack_level_ioapic_irq (unsigned irq)
+
+{
+	unsigned long flags, v;
+	int i;
+
+	i = IO_APIC_VECTOR(irq);
+	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
+
+	if (!(v & (1 << (i & 0x1f)))) {
+		set_bit(irq,&bugous_edge_triggers);
+		__mask_and_edge_IO_APIC_irq(irq);
+	}
+	else
+		__mask_IO_APIC_irq(irq);
+
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
+
+	__ack_APIC_irq();
+}
+
+#ifdef CONFIG_PCI_MSI
+
+#ifdef CONFIG_IRQBALANCE
+static inline void end_edge_ioapic_vector(unsigned int vector)
+
+{
+	int irq = vector_to_irq(vector);
+
+	end_edge_ioapic_irq(irq);
+}
+#endif /* CONFIG_IRQBALANCE */
+
+static inline void mask_and_ack_level_ioapic_vector(unsigned int vector)
+
+{
+	int irq = vector_to_irq(vector);
+
+	mask_and_ack_level_ioapic_irq(irq);
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+#else /* !CONFIG_IPIPE */
+
 static void end_level_ioapic_irq (unsigned int irq)
 {
 	unsigned long v;
@@ -1925,6 +2032,8 @@ static void end_level_ioapic_irq (unsign
 	}
 }
 
+#endif /* CONFIG_IPIPE */
+
 #ifdef CONFIG_PCI_MSI
 static unsigned int startup_edge_ioapic_vector(unsigned int vector)
 {
@@ -2071,7 +2180,7 @@ static void disable_lapic_irq (unsigned 
 
 static void ack_lapic_irq (unsigned int irq)
 {
-	ack_APIC_irq();
+	__ack_APIC_irq();
 }
 
 static void end_lapic_irq (unsigned int i) { /* nothing */ }
@@ -2344,12 +2453,12 @@ static int ioapic_suspend(struct sys_dev
 	
 	data = container_of(dev, struct sysfs_ioapic_data, dev);
 	entry = data->entry;
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
 		*(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
 		*(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
 	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 
 	return 0;
 }
@@ -2365,7 +2474,7 @@ static int ioapic_resume(struct sys_devi
 	data = container_of(dev, struct sysfs_ioapic_data, dev);
 	entry = data->entry;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	reg_00.raw = io_apic_read(dev->id, 0);
 	if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
 		reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
@@ -2375,7 +2484,7 @@ static int ioapic_resume(struct sys_devi
 		io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
 		io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
 	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 
 	return 0;
 }
@@ -2570,11 +2679,11 @@ int io_apic_set_pci_routing (int ioapic,
 	if (!ioapic && (irq < 16))
 		disable_8259A_irq(irq);
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	spin_lock_irqsave_hw(&ioapic_lock, flags);
 	io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
 	io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
 	set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	spin_unlock_irqrestore_hw(&ioapic_lock, flags);
 
 	return 0;
 }
diff -uNrp linux-2.6.14.5/arch/i386/kernel/ipipe-core.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/ipipe-core.c
--- linux-2.6.14.5/arch/i386/kernel/ipipe-core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/ipipe-core.c	2006-01-22 13:01:13.642394480 +0100
@@ -0,0 +1,601 @@
+/*   -*- linux-c -*-
+ *   linux/arch/i386/kernel/ipipe-core.c
+ *
+ *   Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Architecture-dependent I-PIPE core support for x86.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/hw_irq.h>
+#include <asm/irq.h>
+#include <asm/desc.h>
+#include <asm/io.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/fixmap.h>
+#include <asm/bitops.h>
+#include <asm/mpspec.h>
+#ifdef CONFIG_X86_IO_APIC
+#include <asm/io_apic.h>
+#endif	/* CONFIG_X86_IO_APIC */
+#include <asm/apic.h>
+#include <mach_ipi.h>
+#endif	/* CONFIG_X86_LOCAL_APIC */
+
+struct pt_regs __ipipe_tick_regs[IPIPE_NR_CPUS];
+
+int __ipipe_tick_irq;
+
+#ifdef CONFIG_SMP
+
+static cpumask_t __ipipe_cpu_sync_map;
+
+static cpumask_t __ipipe_cpu_lock_map;
+
+static ipipe_spinlock_t __ipipe_cpu_barrier = IPIPE_SPIN_LOCK_UNLOCKED;
+
+static atomic_t __ipipe_critical_count = ATOMIC_INIT(0);
+
+static void (*__ipipe_cpu_sync) (void);
+
+#endif	/* CONFIG_SMP */
+
+#define __ipipe_call_root_xirq_handler(ipd,irq) \
+   __asm__ __volatile__ ("pushfl\n\t" \
+                         "pushl %%cs\n\t" \
+                         "pushl $1f\n\t" \
+	                 "pushl %%eax\n\t" \
+	                 "pushl %%es\n\t" \
+	                 "pushl %%ds\n\t" \
+	                 "pushl %%eax\n\t" \
+	                 "pushl %%ebp\n\t" \
+	                 "pushl %%edi\n\t" \
+	                 "pushl %%esi\n\t" \
+	                 "pushl %%edx\n\t" \
+	                 "pushl %%ecx\n\t" \
+	                 "pushl %%ebx\n\t" \
+                         "movl  %%esp,%%eax\n\t" \
+                         "call *%1\n\t" \
+	                 "jmp ret_from_intr\n\t" \
+	                 "1:\n" \
+			 : /* no output */ \
+			 : "a" (irq-256), "m" ((ipd)->irqs[irq].handler))
+
+#define __ipipe_call_root_virq_handler(ipd,irq) \
+   __asm__ __volatile__ ("pushfl\n\t" \
+                         "pushl %%cs\n\t" \
+                         "pushl $1f\n\t" \
+	                 "pushl $-1\n\t" \
+	                 "pushl %%es\n\t" \
+	                 "pushl %%ds\n\t" \
+	                 "pushl %%eax\n\t" \
+	                 "pushl %%ebp\n\t" \
+	                 "pushl %%edi\n\t" \
+	                 "pushl %%esi\n\t" \
+	                 "pushl %%edx\n\t" \
+	                 "pushl %%ecx\n\t" \
+	                 "pushl %%ebx\n\t" \
+                         "pushl %%eax\n\t" \
+                         "call *%1\n\t" \
+			 "addl $4,%%esp\n\t" \
+	                 "jmp ret_from_intr\n\t" \
+	                 "1:\n" \
+			 : /* no output */ \
+			 : "a" (irq), "m" ((ipd)->irqs[irq].handler))
+
+static __inline__ unsigned long flnz(unsigned long word)
+{
+      __asm__("bsrl %1, %0":"=r"(word)
+      :	"r"(word));
+	return word;
+}
+
+int __ipipe_ack_system_irq(unsigned irq)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	__ack_APIC_irq();
+#endif	/* CONFIG_X86_LOCAL_APIC */
+	return 1;
+}
+
+#ifdef CONFIG_SMP
+
+/* Always called with hw interrupts off. */
+
+void __ipipe_do_critical_sync(unsigned irq)
+{
+	ipipe_declare_cpuid;
+
+	ipipe_load_cpuid();
+
+	cpu_set(cpuid, __ipipe_cpu_sync_map);
+
+	/* Now we are in sync with the lock requestor running on another
+	   CPU. Enter a spinning wait until he releases the global
+	   lock. */
+	spin_lock_hw(&__ipipe_cpu_barrier);
+
+	/* Got it. Now get out. */
+
+	if (__ipipe_cpu_sync)
+		/* Call the sync routine if any. */
+		__ipipe_cpu_sync();
+
+	spin_unlock_hw(&__ipipe_cpu_barrier);
+
+	cpu_clear(cpuid, __ipipe_cpu_sync_map);
+}
+
+#endif	/* CONFIG_SMP */
+
+/* ipipe_critical_enter() -- Grab the superlock excluding all CPUs
+   but the current one from a critical section. This lock is used when
+   we must enforce a global critical section for a single CPU in a
+   possibly SMP system whichever context the CPUs are running. */
+
+unsigned long ipipe_critical_enter(void (*syncfn) (void))
+{
+	unsigned long flags;
+
+	local_irq_save_hw(flags);
+
+#ifdef CONFIG_SMP
+	if (num_online_cpus() > 1) {	/* We might be running a SMP-kernel on a UP box... */
+		ipipe_declare_cpuid;
+		cpumask_t lock_map;
+
+		ipipe_load_cpuid();
+
+		if (!cpu_test_and_set(cpuid, __ipipe_cpu_lock_map)) {
+			while (cpu_test_and_set
+			       (BITS_PER_LONG - 1, __ipipe_cpu_lock_map)) {
+				int n = 0;
+				do {
+					cpu_relax();
+				} while (++n < cpuid);
+			}
+
+			spin_lock_hw(&__ipipe_cpu_barrier);
+
+			__ipipe_cpu_sync = syncfn;
+
+			/* Send the sync IPI to all processors but the current one. */
+			send_IPI_allbutself(IPIPE_CRITICAL_VECTOR);
+
+			cpus_andnot(lock_map, cpu_online_map,
+				    __ipipe_cpu_lock_map);
+
+			while (!cpus_equal(__ipipe_cpu_sync_map, lock_map))
+				cpu_relax();
+		}
+
+		atomic_inc(&__ipipe_critical_count);
+	}
+#endif	/* CONFIG_SMP */
+
+	return flags;
+}
+
+/* ipipe_critical_exit() -- Release the superlock. */
+
+void ipipe_critical_exit(unsigned long flags)
+{
+#ifdef CONFIG_SMP
+	if (num_online_cpus() > 1) {	/* We might be running a SMP-kernel on a UP box... */
+		ipipe_declare_cpuid;
+
+		ipipe_load_cpuid();
+
+		if (atomic_dec_and_test(&__ipipe_critical_count)) {
+			spin_unlock_hw(&__ipipe_cpu_barrier);
+
+			while (!cpus_empty(__ipipe_cpu_sync_map))
+				cpu_relax();
+
+			cpu_clear(cpuid, __ipipe_cpu_lock_map);
+			cpu_clear(BITS_PER_LONG - 1, __ipipe_cpu_lock_map);
+		}
+	}
+#endif	/* CONFIG_SMP */
+
+	local_irq_restore_hw(flags);
+}
+
+/* __ipipe_sync_stage() -- Flush the pending IRQs for the current
+   domain (and processor).  This routine flushes the interrupt log
+   (see "Optimistic interrupt protection" from D. Stodolsky et al. for
+   more on the deferred interrupt scheme). Every interrupt that
+   occurred while the pipeline was stalled gets played.  WARNING:
+   callers on SMP boxen should always check for CPU migration on
+   return of this routine. One can control the kind of interrupts
+   which are going to be sync'ed using the syncmask
+   parameter. IPIPE_IRQMASK_ANY plays them all, IPIPE_IRQMASK_VIRT
+   plays virtual interrupts only. This routine must be called with hw
+   interrupts off. */
+
+void fastcall __ipipe_sync_stage(unsigned long syncmask)
+{
+	unsigned long mask, submask;
+	struct ipcpudata *cpudata;
+	struct ipipe_domain *ipd;
+	ipipe_declare_cpuid;
+	int level, rank;
+	unsigned irq;
+
+	ipipe_load_cpuid();
+	ipd = ipipe_percpu_domain[cpuid];
+	cpudata = &ipd->cpudata[cpuid];
+
+	if (__test_and_set_bit(IPIPE_SYNC_FLAG, &cpudata->status))
+		return;
+
+	/* The policy here is to keep the dispatching code interrupt-free
+	   by stalling the current stage. If the upper domain handler
+	   (which we call) wants to re-enable interrupts while in a safe
+	   portion of the code (e.g. SA_INTERRUPT flag unset for Linux's
+	   sigaction()), it will have to unstall (then stall again before
+	   returning to us!) the stage when it sees fit. */
+
+	while ((mask = (cpudata->irq_pending_hi & syncmask)) != 0) {
+		/* Give a slight priority advantage to high-numbered IRQs
+		   like the virtual ones. */
+		level = flnz(mask);
+		__clear_bit(level, &cpudata->irq_pending_hi);
+
+		while ((submask = cpudata->irq_pending_lo[level]) != 0) {
+			rank = flnz(submask);
+			irq = (level << IPIPE_IRQ_ISHIFT) + rank;
+
+			if (test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control)) {
+				__clear_bit(rank,
+					    &cpudata->irq_pending_lo[level]);
+				continue;
+			}
+
+			if (--cpudata->irq_hits[irq] == 0) {
+				__clear_bit(rank,
+					    &cpudata->irq_pending_lo[level]);
+				ipipe_mark_irq_delivery(ipd,irq,cpuid);
+			}
+
+			__set_bit(IPIPE_STALL_FLAG, &cpudata->status);
+			ipipe_mark_domain_stall(ipd, cpuid);
+
+			if (ipd == ipipe_root_domain) {
+				/* Linux handlers are called hw interrupts on
+				   so that they could not defer interrupts for
+				   higher priority domains. */
+				local_irq_enable_hw();
+
+				if (likely(!ipipe_virtual_irq_p(irq))) {
+					__ipipe_call_root_xirq_handler(ipd,irq);
+				} else {
+					irq_enter();
+					__ipipe_call_root_virq_handler(ipd,irq);
+					irq_exit();
+				}
+
+				local_irq_disable_hw();
+			} else {
+				__clear_bit(IPIPE_SYNC_FLAG, &cpudata->status);
+				ipd->irqs[irq].handler(irq);
+				__set_bit(IPIPE_SYNC_FLAG, &cpudata->status);
+			}
+
+#ifdef CONFIG_SMP
+			{
+				int _cpuid = ipipe_processor_id();
+
+				if (_cpuid != cpuid) {	/* Handle CPU migration. */
+					/* We expect any domain to clear the SYNC bit each
+					   time it switches in a new task, so that preemptions
+					   and/or CPU migrations (in the SMP case) over the
+					   ISR do not lock out the log syncer for some
+					   indefinite amount of time. In the Linux case,
+					   schedule() handles this (see kernel/sched.c). For
+					   this reason, we don't bother clearing it here for
+					   the source CPU in the migration handling case,
+					   since it must have scheduled another task in by
+					   now. */
+					cpuid = _cpuid;
+					cpudata = &ipd->cpudata[cpuid];
+					__set_bit(IPIPE_SYNC_FLAG,&cpudata->status);
+				}
+			}
+#endif	/* CONFIG_SMP */
+
+			__clear_bit(IPIPE_STALL_FLAG, &cpudata->status);
+			ipipe_mark_domain_unstall(ipd, cpuid);
+		}
+	}
+
+	__clear_bit(IPIPE_SYNC_FLAG, &cpudata->status);
+}
+
+/* ipipe_trigger_irq() -- Push the interrupt at front of the pipeline
+   just like if it has been actually received from a hw source. Also
+   works for virtual interrupts. */
+
+int fastcall ipipe_trigger_irq(unsigned irq)
+{
+	struct pt_regs regs;
+	unsigned long flags;
+
+	if (irq >= IPIPE_NR_IRQS ||
+	    (ipipe_virtual_irq_p(irq) &&
+	     !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
+		return -EINVAL;
+
+	local_irq_save_hw(flags);
+
+	regs.orig_eax = irq;	/* Won't be acked */
+	regs.xcs = __KERNEL_CS;
+	regs.eflags = flags;
+
+	__ipipe_handle_irq(regs);
+
+	local_irq_restore_hw(flags);
+
+	return 1;
+}
+
+#ifdef CONFIG_SMP
+
+cpumask_t __ipipe_set_irq_affinity (unsigned irq, cpumask_t cpumask)
+
+{
+	cpumask_t oldmask = irq_affinity[irq];
+
+	if (irq_desc[irq].handler->set_affinity == NULL)
+		return CPU_MASK_NONE;
+
+	if (cpus_empty(cpumask))
+		return oldmask; /* Return mask value -- no change. */
+
+	cpus_and(cpumask,cpumask,cpu_online_map);
+
+	if (cpus_empty(cpumask))
+		return CPU_MASK_NONE;	/* Error -- bad mask value or non-routable IRQ. */
+
+	irq_affinity[irq] = cpumask;
+	irq_desc[irq].handler->set_affinity(irq,cpumask);
+	return oldmask;
+}
+
+int fastcall __ipipe_send_ipi (unsigned ipi, cpumask_t cpumask)
+
+{
+	unsigned long flags;
+	ipipe_declare_cpuid;
+	int self;
+
+	ipipe_lock_cpu(flags);
+
+	self = cpu_isset(cpuid,cpumask);
+	cpu_clear(cpuid,cpumask);
+
+	if (!cpus_empty(cpumask))
+		send_IPI_mask(cpumask,ipi + FIRST_EXTERNAL_VECTOR);
+
+	if (self)
+		ipipe_trigger_irq(ipi);
+
+	ipipe_unlock_cpu(flags);
+
+	return 0;
+}
+
+#endif /* CONFIG_SMP */
+
+/* ipipe_virtualize_irq() -- Attach a handler (and optionally a hw
+   acknowledge routine) to an interrupt for a given domain. */
+
+int ipipe_virtualize_irq(struct ipipe_domain *ipd,
+			 unsigned irq,
+			 void (*handler) (unsigned irq),
+			 int (*acknowledge) (unsigned irq),
+			 unsigned modemask)
+{
+	unsigned long flags;
+	int err;
+
+	if (irq >= IPIPE_NR_IRQS)
+		return -EINVAL;
+
+	if (ipd->irqs[irq].control & IPIPE_SYSTEM_MASK)
+		return -EPERM;
+
+	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);
+
+	if (handler != NULL) {
+
+		if (handler == IPIPE_SAME_HANDLER) {
+			handler = ipd->irqs[irq].handler;
+
+			if (handler == NULL) {
+				err = -EINVAL;
+				goto unlock_and_exit;
+			}
+		} else if ((modemask & IPIPE_EXCLUSIVE_MASK) != 0 &&
+			   ipd->irqs[irq].handler != NULL) {
+			err = -EBUSY;
+			goto unlock_and_exit;
+		}
+
+		if ((modemask & (IPIPE_SHARED_MASK | IPIPE_PASS_MASK)) ==
+		    IPIPE_SHARED_MASK) {
+			err = -EINVAL;
+			goto unlock_and_exit;
+		}
+
+		if ((modemask & IPIPE_STICKY_MASK) != 0)
+			modemask |= IPIPE_HANDLE_MASK;
+	} else
+		modemask &=
+		    ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK |
+		      IPIPE_SHARED_MASK);
+
+	if (acknowledge == NULL) {
+		if ((modemask & IPIPE_SHARED_MASK) == 0)
+			/* Acknowledge handler unspecified -- this is ok in
+			   non-shared management mode, but we will force the use
+			   of the Linux-defined handler instead. */
+			acknowledge = ipipe_root_domain->irqs[irq].acknowledge;
+		else {
+			/* A valid acknowledge handler to be called in shared mode
+			   is required when declaring a shared IRQ. */
+			err = -EINVAL;
+			goto unlock_and_exit;
+		}
+	}
+
+	ipd->irqs[irq].handler = handler;
+	ipd->irqs[irq].acknowledge = acknowledge;
+	ipd->irqs[irq].control = modemask;
+
+	if (irq < NR_IRQS &&
+	    handler != NULL &&
+	    !ipipe_virtual_irq_p(irq) && (modemask & IPIPE_ENABLE_MASK) != 0) {
+		if (ipd != ipipe_current_domain) {
+			/* IRQ enable/disable state is domain-sensitive, so we may
+			   not change it for another domain. What is allowed
+			   however is forcing some domain to handle an interrupt
+			   source, by passing the proper 'ipd' descriptor which
+			   thus may be different from ipipe_current_domain. */
+			err = -EPERM;
+			goto unlock_and_exit;
+		}
+
+		irq_desc[irq].handler->enable(irq);
+	}
+
+	err = 0;
+
+      unlock_and_exit:
+
+	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);
+
+	return err;
+}
+
+/* ipipe_control_irq() -- Change modes of a pipelined interrupt for
+ * the current domain. */
+
+int ipipe_control_irq(unsigned irq, unsigned clrmask, unsigned setmask)
+{
+	struct ipipe_domain *ipd;
+	unsigned long flags;
+	irq_desc_t *desc;
+
+	if (irq >= IPIPE_NR_IRQS)
+		return -EINVAL;
+
+	ipd = ipipe_current_domain;
+
+	if (ipd->irqs[irq].control & IPIPE_SYSTEM_MASK)
+		return -EPERM;
+
+	if (((setmask | clrmask) & IPIPE_SHARED_MASK) != 0)
+		return -EINVAL;
+
+	desc = irq_desc + irq;
+
+	if (ipd->irqs[irq].handler == NULL)
+		setmask &= ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);
+
+	if ((setmask & IPIPE_STICKY_MASK) != 0)
+		setmask |= IPIPE_HANDLE_MASK;
+
+	if ((clrmask & (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK)) != 0)	/* If one goes, both go. */
+		clrmask |= (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);
+
+	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);
+
+	ipd->irqs[irq].control &= ~clrmask;
+	ipd->irqs[irq].control |= setmask;
+
+	if ((setmask & IPIPE_ENABLE_MASK) != 0)
+		desc->handler->enable(irq);
+	else if ((clrmask & IPIPE_ENABLE_MASK) != 0)
+		desc->handler->disable(irq);
+
+	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);
+
+	return 0;
+}
+
+int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
+{
+	info->ncpus = num_online_cpus();
+	info->cpufreq = ipipe_cpu_freq();
+	info->archdep.tmirq = __ipipe_tick_irq;
+#ifdef CONFIG_X86_TSC
+	info->archdep.tmfreq = ipipe_cpu_freq();
+#else	/* !CONFIG_X86_TSC */
+	info->archdep.tmfreq = CLOCK_TICK_RATE;
+#endif	/* CONFIG_X86_TSC */
+
+	return 0;
+}
+
+int ipipe_tune_timer (unsigned long ns, int flags)
+
+{
+	unsigned hz, latch;
+	unsigned long x;
+
+	if (flags & IPIPE_RESET_TIMER)
+		latch = LATCH;
+	else {
+		hz = 1000000000 / ns;
+
+		if (hz < HZ)
+			return -EINVAL;
+
+		latch = (CLOCK_TICK_RATE + hz/2) / hz;
+	}
+
+	x = ipipe_critical_enter(NULL); /* Sync with all CPUs */
+
+	/* Shamelessly lifted from init_IRQ() in i8259.c */
+	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+	outb_p(latch & 0xff,0x40);	/* LSB */
+	outb(latch >> 8,0x40);	/* MSB */
+
+	ipipe_critical_exit(x);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(__ipipe_sync_stage);
+EXPORT_SYMBOL(__ipipe_tick_irq);
+EXPORT_SYMBOL(ipipe_critical_enter);
+EXPORT_SYMBOL(ipipe_critical_exit);
+EXPORT_SYMBOL(ipipe_trigger_irq);
+EXPORT_SYMBOL(ipipe_virtualize_irq);
+EXPORT_SYMBOL(ipipe_control_irq);
+EXPORT_SYMBOL(ipipe_get_sysinfo);
+EXPORT_SYMBOL(ipipe_tune_timer);
diff -uNrp linux-2.6.14.5/arch/i386/kernel/ipipe-root.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/ipipe-root.c
--- linux-2.6.14.5/arch/i386/kernel/ipipe-root.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/ipipe-root.c	2006-01-22 13:01:13.645394024 +0100
@@ -0,0 +1,602 @@
+/*   -*- linux-c -*-
+ *   linux/arch/i386/kernel/ipipe-root.c
+ *
+ *   Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Architecture-dependent I-PIPE support for x86.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/hw_irq.h>
+#include <asm/irq.h>
+#include <asm/desc.h>
+#include <asm/io.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/tlbflush.h>
+#include <asm/fixmap.h>
+#include <asm/bitops.h>
+#include <asm/mpspec.h>
+#ifdef CONFIG_X86_IO_APIC
+#include <asm/io_apic.h>
+#endif	/* CONFIG_X86_IO_APIC */
+#include <asm/apic.h>
+#include <mach_ipi.h>
+
+static int __ipipe_noack_irq(unsigned irq)
+{
+	return 1;
+}
+#endif	/* CONFIG_X86_LOCAL_APIC */
+
+fastcall unsigned int do_IRQ(struct pt_regs *regs);
+fastcall void smp_apic_timer_interrupt(struct pt_regs *regs);
+fastcall void smp_spurious_interrupt(struct pt_regs *regs);
+fastcall void smp_error_interrupt(struct pt_regs *regs);
+fastcall void smp_thermal_interrupt(struct pt_regs *regs);
+fastcall void smp_reschedule_interrupt(struct pt_regs *regs);
+fastcall void smp_invalidate_interrupt(struct pt_regs *regs);
+fastcall void smp_call_function_interrupt(struct pt_regs *regs);
+
+static int __ipipe_ack_common_irq(unsigned irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+	ipipe_declare_cpuid;
+
+	ipipe_load_cpuid();	/* hw interrupts are off. */
+	flags = ipipe_test_and_stall_pipeline();
+	preempt_disable();
+	desc->handler->ack(irq);
+	preempt_enable_no_resched();
+	ipipe_restore_pipeline_nosync(ipipe_percpu_domain[cpuid], flags, cpuid);
+
+	return 1;
+}
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+static void __ipipe_null_handler(unsigned irq)
+{
+	/* Nop. */
+}
+
+#ifdef CONFIG_SMP
+
+static int __ipipe_boot_cpuid(void)
+{
+	return 0;
+}
+
+u8 __ipipe_apicid_2_cpu[IPIPE_NR_CPUS];
+
+static int __ipipe_hard_cpuid(void)
+{
+	unsigned long flags;
+	int cpu;
+
+	local_irq_save_hw(flags);
+	cpu = __ipipe_apicid_2_cpu[GET_APIC_ID(apic_read(APIC_ID))];
+	local_irq_restore_hw(flags);
+	return cpu;
+}
+
+int (*__ipipe_logical_cpuid)(void) = &__ipipe_boot_cpuid;
+
+EXPORT_SYMBOL(__ipipe_logical_cpuid);
+
+#endif /* CONFIG_SMP */
+
+#endif	/* CONFIG_X86_LOCAL_APIC */
+
+/* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
+   interrupts are off, and secondary CPUs are still lost in space. */
+
+void __init __ipipe_enable_pipeline(void)
+{
+	unsigned irq;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+	/* Map the APIC system vectors. */
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     LOCAL_TIMER_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_apic_timer_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     SPURIOUS_APIC_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_spurious_interrupt,
+			     &__ipipe_noack_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     ERROR_APIC_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_error_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     IPIPE_SERVICE_VECTOR0 - FIRST_EXTERNAL_VECTOR,
+			     &__ipipe_null_handler,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     IPIPE_SERVICE_VECTOR1 - FIRST_EXTERNAL_VECTOR,
+			     &__ipipe_null_handler,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     IPIPE_SERVICE_VECTOR2 - FIRST_EXTERNAL_VECTOR,
+			     &__ipipe_null_handler,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     IPIPE_SERVICE_VECTOR3 - FIRST_EXTERNAL_VECTOR,
+			     &__ipipe_null_handler,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+#ifdef CONFIG_X86_MCE_P4THERMAL
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     THERMAL_APIC_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_thermal_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+#endif /* CONFIG_X86_MCE_P4THERMAL */
+
+	__ipipe_tick_irq =
+	    using_apic_timer ? LOCAL_TIMER_VECTOR - FIRST_EXTERNAL_VECTOR : 0;
+
+#else	/* !CONFIG_X86_LOCAL_APIC */
+
+	__ipipe_tick_irq = 0;
+
+#endif	/* CONFIG_X86_LOCAL_APIC */
+
+#ifdef CONFIG_SMP
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     RESCHEDULE_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_reschedule_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     INVALIDATE_TLB_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_invalidate_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	ipipe_virtualize_irq(ipipe_root_domain,
+			     CALL_FUNCTION_VECTOR - FIRST_EXTERNAL_VECTOR,
+			     (void (*)(unsigned))&smp_call_function_interrupt,
+			     &__ipipe_ack_system_irq,
+			     IPIPE_STDROOT_MASK);
+
+	/* Some guest O/S may run tasks over non-Linux stacks, so we
+	 * cannot rely on the regular definition of smp_processor_id()
+	 * on x86 to fetch the logical cpu id. We fix this by using
+	 * our own private physical apicid -> logicial cpuid mapping
+	 * as soon as the pipeline is enabled, so that
+	 * ipipe_processor_id() always do the right thing, regardless
+	 * of the current stack setup. Also note that the pipeline is
+	 * enabled after the APIC space has been mapped in
+	 * trap_init(), so it's safe to use it. */
+
+	__ipipe_logical_cpuid = &__ipipe_hard_cpuid;
+
+#endif	/* CONFIG_SMP */
+
+	/* Finally, virtualize the remaining ISA and IO-APIC
+	 * interrupts. Interrupts which have already been virtualized
+	 * will just beget a silent -EPERM error since
+	 * IPIPE_SYSTEM_MASK has been passed for them, that's ok. */
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		/* Fails for IPIPE_CRITICAL_IPI but that's ok. */
+		ipipe_virtualize_irq(ipipe_root_domain,
+				     irq,
+				     (void (*)(unsigned))&do_IRQ,
+				     &__ipipe_ack_common_irq,
+				     IPIPE_STDROOT_MASK);
+	}
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	/* Eventually allow these vectors to be reprogrammed. */
+	ipipe_root_domain->irqs[IPIPE_SERVICE_IPI0].control &= ~IPIPE_SYSTEM_MASK;
+	ipipe_root_domain->irqs[IPIPE_SERVICE_IPI1].control &= ~IPIPE_SYSTEM_MASK;
+	ipipe_root_domain->irqs[IPIPE_SERVICE_IPI2].control &= ~IPIPE_SYSTEM_MASK;
+	ipipe_root_domain->irqs[IPIPE_SERVICE_IPI3].control &= ~IPIPE_SYSTEM_MASK;
+#endif	/* CONFIG_X86_LOCAL_APIC */
+}
+
+static inline void __fixup_if(struct pt_regs *regs)
+{
+	ipipe_declare_cpuid;
+	unsigned long flags;
+
+	ipipe_get_cpu(flags);
+
+	if (ipipe_percpu_domain[cpuid] == ipipe_root_domain) {
+		/* Have the saved hw state look like the domain stall bit, so
+		   that __ipipe_unstall_iret_root() restores the proper
+		   pipeline state for the root stage upon exit. */
+
+		if (test_bit
+		    (IPIPE_STALL_FLAG,
+		     &ipipe_root_domain->cpudata[cpuid].status))
+			regs->eflags &= ~X86_EFLAGS_IF;
+		else
+			regs->eflags |= X86_EFLAGS_IF;
+	}
+
+	ipipe_put_cpu(flags);
+}
+
+/*  Check the interrupt flag to make sure the existing preemption
+    opportunity upon in-kernel resumption could be exploited. If the
+    pipeline is active, the stall bit of the root domain is checked,
+    otherwise, the EFLAGS register from the stacked interrupt frame is
+    tested. In case a rescheduling could take place in pipelined mode,
+    the root stage is stalled before the hw interrupts are
+    re-enabled. This routine must be called with hw interrupts off. */
+
+asmlinkage int __ipipe_kpreempt_root(struct pt_regs regs)
+{
+	ipipe_declare_cpuid;
+	unsigned long flags;
+
+	ipipe_get_cpu(flags);
+
+	if (test_bit
+	    (IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status)) {
+		ipipe_put_cpu(flags);
+		return 0;	/* Root stage is stalled: rescheduling denied. */
+	}
+
+	__ipipe_stall_root();
+	local_irq_enable_hw();
+
+	return 1;		/* Ok, may reschedule now. */
+}
+
+asmlinkage void __ipipe_unstall_iret_root(struct pt_regs regs)
+{
+	ipipe_declare_cpuid;
+
+	/* Emulate IRET's handling of the interrupt flag. */
+
+	local_irq_disable_hw();
+
+	ipipe_load_cpuid();
+
+	/* Restore the software state as it used to be on kernel
+	   entry. CAUTION: NMIs must *not* return through this
+	   emulation. */
+
+	if (!(regs.eflags & X86_EFLAGS_IF)) {
+		__set_bit(IPIPE_STALL_FLAG,
+			  &ipipe_root_domain->cpudata[cpuid].status);
+		ipipe_mark_domain_stall(ipipe_root_domain, cpuid);
+		regs.eflags |= X86_EFLAGS_IF;
+	} else {
+		__clear_bit(IPIPE_STALL_FLAG,
+			    &ipipe_root_domain->cpudata[cpuid].status);
+
+		ipipe_mark_domain_unstall(ipipe_root_domain, cpuid);
+
+		/* Only sync virtual IRQs here, so that we don't recurse
+		   indefinitely in case of an external interrupt flood. */
+
+		if ((ipipe_root_domain->cpudata[cpuid].
+		     irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0)
+			__ipipe_sync_stage(IPIPE_IRQMASK_VIRT);
+	}
+}
+
+asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
+{
+	ipipe_declare_cpuid;
+	unsigned long flags;
+
+	__fixup_if(&regs);
+
+	/* This routine either returns:
+	    0 -- if the syscall is to be passed to Linux;
+	   >0 -- if the syscall should not be passed to Linux, and no
+	   tail work should be performed;
+	   <0 -- if the syscall should not be passed to Linux but the
+	   tail work has to be performed (for handling signals etc). */
+
+	if (__ipipe_event_monitors[IPIPE_EVENT_SYSCALL] > 0 &&
+	    __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,&regs) > 0) {
+		/* We might enter here over a non-root domain and exit
+		 * over the root one as a result of the syscall
+		 * (i.e. by recycling the register set of the current
+		 * context across the migration), so we need to fixup
+		 * the interrupt flag upon return too, so that
+		 * __ipipe_unstall_iret_root() resets the correct
+		 * stall bit on exit. */
+		__fixup_if(&regs);
+
+		if (ipipe_current_domain == ipipe_root_domain && !in_atomic()) {
+			/* Sync pending VIRQs before _TIF_NEED_RESCHED
+			 * is tested. */
+			ipipe_lock_cpu(flags);
+			if ((ipipe_root_domain->cpudata[cpuid].irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0)
+				__ipipe_sync_stage(IPIPE_IRQMASK_VIRT);
+			ipipe_unlock_cpu(flags);
+			return -1;
+		}
+		return 1;
+	}
+
+    return 0;
+}
+
+static fastcall void do_machine_check_vector(struct pt_regs *regs, long error_code)
+{
+#ifdef CONFIG_X86_MCE
+	extern fastcall void (*machine_check_vector)(struct pt_regs *, long);
+	machine_check_vector(regs,error_code);
+#endif /* CONFIG_X86_MCE */
+}
+
+fastcall void do_divide_error(struct pt_regs *regs, long error_code);
+fastcall void do_overflow(struct pt_regs *regs, long error_code);
+fastcall void do_bounds(struct pt_regs *regs, long error_code);
+fastcall void do_invalid_op(struct pt_regs *regs, long error_code);
+fastcall void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
+fastcall void do_invalid_TSS(struct pt_regs *regs, long error_code);
+fastcall void do_segment_not_present(struct pt_regs *regs, long error_code);
+fastcall void do_stack_segment(struct pt_regs *regs, long error_code);
+fastcall void do_general_protection(struct pt_regs *regs, long error_code);
+fastcall void do_page_fault(struct pt_regs *regs, long error_code);
+fastcall void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code);
+fastcall void do_coprocessor_error(struct pt_regs *regs, long error_code);
+fastcall void do_alignment_check(struct pt_regs *regs, long error_code);
+fastcall void do_simd_coprocessor_error(struct pt_regs *regs, long error_code);
+fastcall void do_iret_error(struct pt_regs *regs, long error_code);
+
+/* Work around genksyms's issue with over-qualification in decls. */
+
+typedef fastcall void __ipipe_exhandler(struct pt_regs *, long);
+
+typedef __ipipe_exhandler *__ipipe_exptr;
+
+static __ipipe_exptr __ipipe_std_extable[] = {
+
+	[ex_do_divide_error] = &do_divide_error,
+	[ex_do_overflow] = &do_overflow,
+	[ex_do_bounds] = &do_bounds,
+	[ex_do_invalid_op] = &do_invalid_op,
+	[ex_do_coprocessor_segment_overrun] = &do_coprocessor_segment_overrun,
+	[ex_do_invalid_TSS] = &do_invalid_TSS,
+	[ex_do_segment_not_present] = &do_segment_not_present,
+	[ex_do_stack_segment] = &do_stack_segment,
+	[ex_do_general_protection] = do_general_protection,
+	[ex_do_page_fault] = &do_page_fault,
+	[ex_do_spurious_interrupt_bug] = &do_spurious_interrupt_bug,
+	[ex_do_coprocessor_error] = &do_coprocessor_error,
+	[ex_do_alignment_check] = &do_alignment_check,
+	[ex_machine_check_vector] = &do_machine_check_vector,
+	[ex_do_simd_coprocessor_error] = &do_simd_coprocessor_error,
+	[ex_do_iret_error] = &do_iret_error,
+};
+
+fastcall int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector)
+{
+	if (__ipipe_event_monitors[vector] == 0 ||
+	    __ipipe_dispatch_event(vector,regs) == 0) {
+		__ipipe_exptr handler = __ipipe_std_extable[vector];
+		handler(regs,error_code);
+		__fixup_if(regs);
+		return 0;
+	}
+
+	return 1;
+}
+
+fastcall int __ipipe_divert_exception(struct pt_regs *regs, int vector)
+{
+	if (__ipipe_event_monitors[vector] > 0 &&
+	    __ipipe_dispatch_event(vector,regs) != 0)
+		return 1;
+
+	__fixup_if(regs);
+
+	return 0;
+}
+
+/* __ipipe_walk_pipeline(): Plays interrupts pending in the log. Must
+   be called with local hw interrupts disabled. */
+
+static inline void __ipipe_walk_pipeline(struct list_head *pos, int cpuid)
+{
+	struct ipipe_domain *this_domain = ipipe_percpu_domain[cpuid];
+
+	while (pos != &__ipipe_pipeline) {
+		struct ipipe_domain *next_domain =
+		    list_entry(pos, struct ipipe_domain, p_link);
+
+		if (test_bit
+		    (IPIPE_STALL_FLAG, &next_domain->cpudata[cpuid].status))
+			break;	/* Stalled stage -- do not go further. */
+
+		if (next_domain->cpudata[cpuid].irq_pending_hi != 0) {
+
+			if (next_domain == this_domain)
+				__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+			else {
+				__ipipe_switch_to(this_domain, next_domain,
+						  cpuid);
+
+				ipipe_load_cpuid();	/* Processor might have changed. */
+
+				if (this_domain->cpudata[cpuid].
+				    irq_pending_hi != 0
+				    && !test_bit(IPIPE_STALL_FLAG,
+						 &this_domain->cpudata[cpuid].status))
+					__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+			}
+
+			break;
+		} else if (next_domain == this_domain)
+			break;
+
+		pos = next_domain->p_link.next;
+	}
+}
+
+/* __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic
+   interrupt protection log is maintained here for each domain.  Hw
+   interrupts are off on entry. */
+
+int __ipipe_handle_irq(struct pt_regs regs)
+{
+	struct ipipe_domain *this_domain;
+	unsigned irq = regs.orig_eax;
+	struct list_head *head, *pos;
+	ipipe_declare_cpuid;
+	int m_ack, s_ack;
+
+	if (regs.orig_eax < 0) {
+		irq &= 0xff;
+		m_ack = 0;
+	} else {
+		m_ack = 1;
+	}
+
+	ipipe_load_cpuid();
+
+	this_domain = ipipe_percpu_domain[cpuid];
+
+	s_ack = m_ack;
+
+	if (test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))
+		head = &this_domain->p_link;
+	else
+		head = __ipipe_pipeline.next;
+
+	/* Ack the interrupt. */
+
+	pos = head;
+
+	while (pos != &__ipipe_pipeline) {
+		struct ipipe_domain *next_domain =
+		    list_entry(pos, struct ipipe_domain, p_link);
+
+		/* For each domain handling the incoming IRQ, mark it as
+		   pending in its log. */
+
+		if (test_bit
+		    (IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
+			/* Domains that handle this IRQ are polled for
+			   acknowledging it by decreasing priority order. The
+			   interrupt must be made pending _first_ in the domain's
+			   status flags before the PIC is unlocked. */
+
+			next_domain->cpudata[cpuid].irq_hits[irq]++;
+			__ipipe_set_irq_bit(next_domain, cpuid, irq);
+			ipipe_mark_irq_receipt(next_domain, irq, cpuid);
+
+			/* Always get the first master acknowledge available. Once
+			   we've got it, allow slave acknowledge handlers to run
+			   (until one of them stops us). */
+
+			if (!m_ack)
+				m_ack = next_domain->irqs[irq].acknowledge(irq);
+			else if (test_bit
+				 (IPIPE_SHARED_FLAG,
+				  &next_domain->irqs[irq].control) && !s_ack)
+				s_ack = next_domain->irqs[irq].acknowledge(irq);
+		}
+
+		/* If the domain does not want the IRQ to be passed down the
+		   interrupt pipe, exit the loop now. */
+
+		if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
+			break;
+
+		pos = next_domain->p_link.next;
+	}
+
+	if (irq == __ipipe_tick_irq) {
+		__ipipe_tick_regs[cpuid].eflags = regs.eflags;
+		__ipipe_tick_regs[cpuid].eip = regs.eip;
+		__ipipe_tick_regs[cpuid].xcs = regs.xcs;
+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
+		/* Linux profiling code needs this. */
+		__ipipe_tick_regs[cpuid].ebp = regs.ebp;
+#endif	/* CONFIG_SMP && CONFIG_FRAME_POINTER */
+		if (__ipipe_pipeline_head_p(ipipe_root_domain) &&
+		    ipipe_root_domain->cpudata[cpuid].irq_hits[irq] > 1)
+			/* Emulate a loss of clock ticks if Linux is
+			 * owning the time source. The drift will be
+			 * compensated by the timer support code.*/
+			ipipe_root_domain->cpudata[cpuid].irq_hits[irq] = 1;
+	}
+
+	/* Now walk the pipeline, yielding control to the highest
+	   priority domain that has pending interrupt(s) or
+	   immediately to the current domain if the interrupt has been
+	   marked as 'sticky'. This search does not go beyond the
+	   current domain in the pipeline. */
+
+	__ipipe_walk_pipeline(head, cpuid);
+
+	ipipe_load_cpuid();
+
+	if (ipipe_percpu_domain[cpuid] != ipipe_root_domain ||
+	    test_bit(IPIPE_STALL_FLAG,
+		     &ipipe_root_domain->cpudata[cpuid].status))
+		return 0;
+
+#ifdef CONFIG_SMP
+	/* Prevent a spurious rescheduling from being triggered on
+	   preemptible kernels along the way out through ret_from_intr. */
+	if (regs.orig_eax < 0) {
+		__set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+		ipipe_mark_domain_stall(ipipe_root_domain, cpuid);
+	}
+#endif	/* CONFIG_SMP */
+
+	return 1;
+}
+
+EXPORT_SYMBOL_GPL(irq_desc);
+EXPORT_SYMBOL_GPL(default_ldt);
+EXPORT_SYMBOL_GPL(__switch_to);
+EXPORT_SYMBOL_GPL(show_stack);
+EXPORT_PER_CPU_SYMBOL_GPL(init_tss);
+#ifdef CONFIG_SMP
+EXPORT_PER_CPU_SYMBOL_GPL(cpu_tlbstate);
+#endif /* CONFIG_SMP */
diff -uNrp linux-2.6.14.5/arch/i386/kernel/Makefile linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/Makefile
--- linux-2.6.14.5/arch/i386/kernel/Makefile	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/Makefile	2006-01-22 13:01:13.000000000 +0100
@@ -30,6 +30,8 @@ obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-y				+= sysenter.o vsyscall.o
+obj-$(CONFIG_IPIPE)		+= ipipe-core.o ipipe-root.o
+obj-$(CONFIG_IPIPE_TRACE)	+= ipipe-mcount.o
 obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
 obj-$(CONFIG_HPET_TIMER) 	+= time_hpet.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
diff -uNrp linux-2.6.14.5/arch/i386/kernel/nmi.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/nmi.c
--- linux-2.6.14.5/arch/i386/kernel/nmi.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/nmi.c	2006-01-22 13:01:13.000000000 +0100
@@ -38,6 +38,7 @@ static unsigned int nmi_hz = HZ;
 static unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
 static unsigned int nmi_p4_cccr_val;
 extern void show_registers(struct pt_regs *regs);
+static void default_nmi_watchdog_tick (struct pt_regs * regs);
 
 /*
  * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -100,6 +101,11 @@ int nmi_active;
 	(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
 	 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
 
+static void delay_10_ticks(void *ignored)
+{
+	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+}
+
 static int __init check_nmi_watchdog(void)
 {
 	unsigned int prev_nmi_count[NR_CPUS];
@@ -113,7 +119,11 @@ static int __init check_nmi_watchdog(voi
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
-	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+#ifdef CONFIG_SMP
+	smp_call_function(delay_10_ticks, NULL, 0, 1);
+#else
+	delay_10_ticks(NULL);
+#endif
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
 #ifdef CONFIG_SMP
@@ -149,6 +159,7 @@ static int __init setup_nmi_watchdog(cha
 
 	if (nmi >= NMI_INVALID)
 		return 0;
+        nmi_watchdog_tick = default_nmi_watchdog_tick;
 	if (nmi == NMI_NONE)
 		nmi_watchdog = nmi;
 	/*
@@ -484,9 +495,7 @@ void touch_nmi_watchdog (void)
 	touch_softlockup_watchdog();
 }
 
-extern void die_nmi(struct pt_regs *, const char *msg);
-
-void nmi_watchdog_tick (struct pt_regs * regs)
+static void default_nmi_watchdog_tick (struct pt_regs * regs)
 {
 
 	/*
@@ -584,3 +593,4 @@ EXPORT_SYMBOL(reserve_lapic_nmi);
 EXPORT_SYMBOL(release_lapic_nmi);
 EXPORT_SYMBOL(disable_timer_nmi_watchdog);
 EXPORT_SYMBOL(enable_timer_nmi_watchdog);
+EXPORT_SYMBOL(touch_nmi_watchdog);
diff -uNrp linux-2.6.14.5/arch/i386/kernel/process.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/process.c
--- linux-2.6.14.5/arch/i386/kernel/process.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/process.c	2006-01-22 13:01:13.000000000 +0100
@@ -13,6 +13,7 @@
 
 #include <stdarg.h>
 
+#include <linux/ltt/ltt-facility-process.h>
 #include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -199,6 +200,7 @@ void cpu_idle(void)
 				play_dead();
 
 			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
+ 			ipipe_suspend_domain();
 			idle();
 		}
 		schedule();
@@ -343,6 +345,7 @@ __asm__(".section .text\n"
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	struct pt_regs regs;
+	long pid;
 
 	memset(&regs, 0, sizeof(regs));
 
@@ -357,7 +360,12 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 
 	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+	pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+#if (CONFIG_LTT)
+	if(pid >= 0)
+		trace_process_kernel_thread(pid, fn);
+#endif
+	return pid;
 }
 EXPORT_SYMBOL(kernel_thread);
 
diff -uNrp linux-2.6.14.5/arch/i386/kernel/smpboot.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/smpboot.c
--- linux-2.6.14.5/arch/i386/kernel/smpboot.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/smpboot.c	2006-01-22 13:01:13.000000000 +0100
@@ -874,6 +874,7 @@ static int __devinit do_boot_cpu(int api
 	unsigned short nmi_high = 0, nmi_low = 0;
 
 	++cpucount;
+ 	ipipe_note_apicid(apicid,cpu);
 
 	/*
 	 * We can't use kernel_thread since we must avoid to
@@ -1089,6 +1090,7 @@ static void __init smp_boot_cpus(unsigne
 	boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
 	boot_cpu_logical_apicid = logical_smp_processor_id();
 	x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+	ipipe_note_apicid(boot_cpu_physical_apicid,0);
 
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
diff -uNrp linux-2.6.14.5/arch/i386/kernel/smp.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/smp.c
--- linux-2.6.14.5/arch/i386/kernel/smp.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/smp.c	2006-01-22 13:01:13.000000000 +0100
@@ -132,6 +132,9 @@ void __send_IPI_shortcut(unsigned int sh
 	 * to the APIC.
 	 */
 	unsigned int cfg;
+	unsigned long flags;
+
+	local_irq_save_hw_cond(flags);
 
 	/*
 	 * Wait for idle.
@@ -147,6 +150,8 @@ void __send_IPI_shortcut(unsigned int sh
 	 * Send the IPI. The write to APIC_ICR fires this off.
 	 */
 	apic_write_around(APIC_ICR, cfg);
+
+	local_irq_restore_hw_cond(flags);
 }
 
 void fastcall send_IPI_self(int vector)
@@ -163,7 +168,7 @@ void send_IPI_mask_bitmask(cpumask_t cpu
 	unsigned long cfg;
 	unsigned long flags;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
 	/*
 	 * Wait for idle.
@@ -186,7 +191,7 @@ void send_IPI_mask_bitmask(cpumask_t cpu
 	 */
 	apic_write_around(APIC_ICR, cfg);
 
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 void send_IPI_mask_sequence(cpumask_t mask, int vector)
@@ -200,7 +205,7 @@ void send_IPI_mask_sequence(cpumask_t ma
 	 * should be modified to do 1 message per cluster ID - mbligh
 	 */ 
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 
 	for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
 		if (cpu_isset(query_cpu, mask)) {
@@ -227,7 +232,7 @@ void send_IPI_mask_sequence(cpumask_t ma
 			apic_write_around(APIC_ICR, cfg);
 		}
 	}
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 #include <mach_ipi.h> /* must come after the send_IPI functions above for inlining */
@@ -311,7 +316,9 @@ static inline void leave_mm (unsigned lo
 
 fastcall void smp_invalidate_interrupt(struct pt_regs *regs)
 {
-	unsigned long cpu;
+    	unsigned long cpu, flags;
+
+	local_irq_save_hw_cond(flags);
 
 	cpu = get_cpu();
 
@@ -341,6 +348,7 @@ fastcall void smp_invalidate_interrupt(s
 	smp_mb__after_clear_bit();
 out:
 	put_cpu_no_resched();
+	local_irq_restore_hw_cond(flags);
 }
 
 static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
@@ -401,14 +409,19 @@ void flush_tlb_current_task(void)
 {
 	struct mm_struct *mm = current->mm;
 	cpumask_t cpu_mask;
+	unsigned long flags;
 
 	preempt_disable();
+	local_irq_save_hw_cond(flags);
+
 	cpu_mask = mm->cpu_vm_mask;
 	cpu_clear(smp_processor_id(), cpu_mask);
 
 	local_flush_tlb();
 	if (!cpus_empty(cpu_mask))
 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+
+	local_irq_restore_hw_cond(flags);
 	preempt_enable();
 }
 
@@ -436,8 +449,11 @@ void flush_tlb_page(struct vm_area_struc
 {
 	struct mm_struct *mm = vma->vm_mm;
 	cpumask_t cpu_mask;
+	unsigned long flags;
 
 	preempt_disable();
+	local_irq_save_hw_cond(flags);
+
 	cpu_mask = mm->cpu_vm_mask;
 	cpu_clear(smp_processor_id(), cpu_mask);
 
@@ -448,6 +464,8 @@ void flush_tlb_page(struct vm_area_struc
 		 	leave_mm(smp_processor_id());
 	}
 
+	local_irq_restore_hw_cond(flags);
+
 	if (!cpus_empty(cpu_mask))
 		flush_tlb_others(cpu_mask, mm, va);
 
@@ -627,4 +645,3 @@ fastcall void smp_call_function_interrup
 		atomic_inc(&call_data->finished);
 	}
 }
-
diff -uNrp linux-2.6.14.5/arch/i386/kernel/sys_i386.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/sys_i386.c
--- linux-2.6.14.5/arch/i386/kernel/sys_i386.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/sys_i386.c	2006-01-22 13:01:13.000000000 +0100
@@ -6,6 +6,7 @@
  * platform.
  */
 
+#include <linux/ltt/ltt-facility-ipc.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -136,6 +137,8 @@ asmlinkage int sys_ipc (uint call, int f
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_ipc_call(call, first);
+
 	switch (call) {
 	case SEMOP:
 		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
diff -uNrp linux-2.6.14.5/arch/i386/kernel/time.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/time.c
--- linux-2.6.14.5/arch/i386/kernel/time.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/time.c	2006-01-22 13:01:13.000000000 +0100
@@ -259,11 +259,12 @@ static inline void do_timer_interrupt(in
 		 * This will also deassert NMI lines for the watchdog if run
 		 * on an 82489DX-based system.
 		 */
-		spin_lock(&i8259A_lock);
+		unsigned long flags;
+		spin_lock_irqsave_hw_cond(&i8259A_lock,flags);
 		outb(0x0c, PIC_MASTER_OCW3);
 		/* Ack the IRQ; AEOI will end it automatically. */
 		inb(PIC_MASTER_POLL);
-		spin_unlock(&i8259A_lock);
+		spin_unlock_irqrestore_hw_cond(&i8259A_lock,flags);
 	}
 #endif
 
diff -uNrp linux-2.6.14.5/arch/i386/kernel/timers/timer_pit.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/timers/timer_pit.c
--- linux-2.6.14.5/arch/i386/kernel/timers/timer_pit.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/timers/timer_pit.c	2006-01-22 13:01:13.000000000 +0100
@@ -98,6 +98,10 @@ static unsigned long get_offset_pit(void
 	 */
 	unsigned long jiffies_t;
 
+#ifdef CONFIG_IPIPE
+	if (!__ipipe_pipeline_head_p(ipipe_root_domain))
+		return 0;	/* We don't really own the PIT. */
+#endif /* CONFIG_IPIPE */
 	spin_lock_irqsave(&i8253_lock, flags);
 	/* timer count may underflow right here */
 	outb_p(0x00, PIT_MODE);	/* latch the count ASAP */
diff -uNrp linux-2.6.14.5/arch/i386/kernel/timers/timer_tsc.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/timers/timer_tsc.c
--- linux-2.6.14.5/arch/i386/kernel/timers/timer_tsc.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/timers/timer_tsc.c	2006-01-22 13:01:13.000000000 +0100
@@ -367,6 +367,20 @@ static void mark_offset_tsc(void)
 
 	rdtsc(last_tsc_low, last_tsc_high);
 
+#ifdef CONFIG_IPIPE
+	if (!__ipipe_pipeline_head_p(ipipe_root_domain)) {
+		/* If Linux does not actually own the timer, clock
+		   ticks will be posted by some higher level domain to
+		   us, and we expect it to do this right and never
+		   lose any of them; so we just need to update the
+		   monotonic base here. */
+		this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+		monotonic_base += cycles_2_ns(this_offset - last_offset);
+		write_sequnlock(&monotonic_lock);
+		return;
+	}
+#endif /* CONFIG_IPIPE */
+
 	spin_lock(&i8253_lock);
 	outb_p(0x00, PIT_MODE);     /* latch the count ASAP */
 
diff -uNrp linux-2.6.14.5/arch/i386/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/traps.c
--- linux-2.6.14.5/arch/i386/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/kernel/traps.c	2006-01-22 13:01:13.000000000 +0100
@@ -11,6 +11,8 @@
  * 'Traps.c' handles hardware traps and faults after we have saved some
  * state in 'asm.s'.
  */
+#include <linux/ltt/ltt-facility-kernel.h>
+#include <linux/ltt-core.h>
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -95,6 +97,9 @@ static int kstack_depth_to_print = 24;
 struct notifier_block *i386die_chain;
 static DEFINE_SPINLOCK(die_notifier_lock);
 
+void (*nmi_watchdog_tick) (struct pt_regs * regs);
+EXPORT_SYMBOL(nmi_watchdog_tick);
+
 int register_die_notifier(struct notifier_block *nb)
 {
 	int err = 0;
@@ -227,6 +232,11 @@ void show_registers(struct pt_regs *regs
 		regs->esi, regs->edi, regs->ebp, esp);
 	printk("ds: %04x   es: %04x   ss: %04x\n",
 		regs->xds & 0xffff, regs->xes & 0xffff, ss);
+#ifdef CONFIG_IPIPE
+	if (ipipe_current_domain != ipipe_root_domain)
+	    printk("I-pipe domain %s",ipipe_current_domain->name);
+	else
+#endif /* CONFIG_IPIPE */
 	printk("Process %s (pid: %d, threadinfo=%p task=%p)",
 		current->comm, current->pid, current_thread_info(), current);
 	/*
@@ -291,6 +301,79 @@ bug:
 	printk("Kernel BUG\n");
 }
 
+/* Trace related code */
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(struct pt_regs *regs)
+{
+	int use_depth;
+	int use_bounds;
+	int depth = 0;
+	int seek_depth;
+	unsigned long lower_bound;
+	unsigned long upper_bound;
+	unsigned long addr;
+	unsigned long *stack;
+	//ltt_syscall_entry trace_syscall_event;
+	unsigned long address;
+
+	/* Set the syscall ID */
+	//trace_syscall_event.syscall_id = (uint8_t) regs->orig_eax;
+
+	/* Set the address in any case */
+	address = regs->eip;
+
+	/* Are we in the kernel (This is a kernel thread)? */
+	if (!(regs->xcs & 3))
+		/* Don't go digining anywhere */
+		goto trace_syscall_end;
+#if 0
+	/* Get the trace configuration */
+	//FIXME : need to take configuration from trace info.
+	//if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth,
+	//			(void *) &lower_bound, (void *) &upper_bound) < 0)
+	if(1)
+		goto trace_syscall_end;
+
+	/* Do we have to search for an eip address range */
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		/* Start at the top of the stack (bottom address since stacks grow downward) */
+		stack = (unsigned long *) regs->esp;
+
+		/* Keep on going until we reach the end of the process' stack limit (wherever it may be) */
+		while (!get_user(addr, stack)) {
+			/* Does this LOOK LIKE an address in the program */
+			if ((addr > current->mm->start_code)
+			    && (addr < current->mm->end_code)) {
+				/* Does this address fit the description */
+				if (((use_depth == 1) && (depth == seek_depth))
+				    || ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) {
+					/* Set the address */
+					address = addr;
+
+					/* We're done */
+					goto trace_syscall_end;
+				} else
+					/* We're one depth more */
+					depth++;
+			}
+			/* Go on to the next address */
+			stack++;
+		}
+	}
+#endif //0
+trace_syscall_end:
+	/* Trace the event */
+	//ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+	trace_kernel_syscall_entry((uint8_t) regs->orig_eax, (void*)address);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+	//ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+	trace_kernel_syscall_exit();
+}
+#endif				/* (CONFIG_LTT) */
+
 /* This is gone through when something in the kernel
  * has done something bad and is about to be terminated.
 */
@@ -333,6 +416,10 @@ void die(const char * str, struct pt_reg
 #endif
 		if (nl)
 			printk("\n");
+#ifdef CONFIG_LTT
+		printk("LTT NESTING LEVEL : %u ", ltt_nesting[smp_processor_id()]);
+		printk("\n");
+#endif
 	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_registers(regs);
   	} else
@@ -370,6 +457,8 @@ static void __kprobes do_trap(int trapnr
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = trapnr;
 
+	trace_kernel_trap_entry(trapnr, (void*)regs->eip);
+
 	if (regs->eflags & VM_MASK) {
 		if (vm86)
 			goto vm86_trap;
@@ -384,20 +473,24 @@ static void __kprobes do_trap(int trapnr
 			force_sig_info(signr, info, tsk);
 		else
 			force_sig(signr, tsk);
+		trace_kernel_trap_exit();
 		return;
 	}
 
 	kernel_trap: {
 		if (!fixup_exception(regs))
 			die(str, regs, error_code);
+		trace_kernel_trap_exit();
 		return;
 	}
 
 	vm86_trap: {
 		int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
 		if (ret) goto trap_signal;
+		trace_kernel_trap_exit();
 		return;
 	}
+	trace_kernel_trap_exit();
 }
 
 #define DO_ERROR(trapnr, signr, str, name) \
@@ -504,12 +597,16 @@ fastcall void __kprobes do_general_prote
 
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
+	trace_kernel_trap_entry(13, (void*)regs->eip);
 	force_sig(SIGSEGV, current);
+	trace_kernel_trap_exit();
 	return;
 
 gp_in_vm86:
 	local_irq_enable();
+	trace_kernel_trap_entry(13, (void*)regs->eip);
 	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
+	trace_kernel_trap_exit();
 	return;
 
 gp_in_kernel:
@@ -595,6 +692,7 @@ void die_nmi (struct pt_regs *regs, cons
 
 	do_exit(SIGSEGV);
 }
+EXPORT_SYMBOL(die_nmi);
 
 static void default_do_nmi(struct pt_regs * regs)
 {
@@ -603,6 +701,12 @@ static void default_do_nmi(struct pt_reg
 	/* Only the BSP gets external NMIs from the system.  */
 	if (!smp_processor_id())
 		reason = get_nmi_reason();
+
+#ifndef CONFIG_X86_LOCAL_APIC
+/* On machines with APIC enabled, NMIs are used to implement a watchdog
+and will hang the machine if traced. */
+	trace_kernel_trap_entry(2, (void*)regs->eip);
+#endif
  
 	if (!(reason & 0xc0)) {
 		if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
@@ -619,6 +723,9 @@ static void default_do_nmi(struct pt_reg
 		}
 #endif
 		unknown_nmi_error(reason, regs);
+#ifndef CONFIG_X86_LOCAL_APIC
+		trace_kernel_trap_exit();
+#endif
 		return;
 	}
 	if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
@@ -632,6 +739,10 @@ static void default_do_nmi(struct pt_reg
 	 * as it's edge-triggered.
 	 */
 	reassert_nmi();
+
+#ifndef CONFIG_X86_LOCAL_APIC
+	trace_kernel_trap_exit();
+#endif
 }
 
 static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
@@ -752,7 +863,9 @@ fastcall void __kprobes do_debug(struct 
 	}
 
 	/* Ok, finally something we can handle */
+	trace_kernel_trap_entry(1, (void*)regs->eip);
 	send_sigtrap(tsk, regs, error_code);
+	trace_kernel_trap_exit();
 
 	/* Disable additional traps. They'll be re-enabled when
 	 * the signal is delivered.
@@ -762,7 +875,9 @@ clear_dr7:
 	return;
 
 debug_vm86:
+	trace_kernel_trap_entry(1, (void*)regs->eip);
 	handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+	trace_kernel_trap_exit();
 	return;
 
 clear_TF_reenable:
@@ -916,10 +1031,12 @@ fastcall void do_simd_coprocessor_error(
 fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
 					  long error_code)
 {
+	trace_kernel_trap_entry(16, (void*)regs->eip);
 #if 0
 	/* No need to warn about this any longer. */
 	printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
 #endif
+	trace_kernel_trap_exit();
 }
 
 fastcall void setup_x86_bogus_stack(unsigned char * stk)
@@ -981,12 +1098,15 @@ asmlinkage void math_state_restore(struc
 {
 	struct thread_info *thread = current_thread_info();
 	struct task_struct *tsk = thread->task;
+	unsigned long flags;
 
+	local_irq_save_hw_cond(flags);
 	clts();		/* Allow maths ops (or we recurse) */
 	if (!tsk_used_math(tsk))
 		init_fpu(tsk);
 	restore_fpu(tsk);
 	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
+	local_irq_restore_hw_cond(flags);
 }
 
 #ifndef CONFIG_MATH_EMULATION
@@ -995,8 +1115,10 @@ asmlinkage void math_emulate(long arg)
 {
 	printk("math-emulation not enabled and no coprocessor found.\n");
 	printk("killing %s.\n",current->comm);
+	trace_kernel_trap_entry(7, (void*)0);
 	force_sig(SIGFPE,current);
 	schedule();
+	trace_kernel_trap_exit();
 }
 
 #endif /* CONFIG_MATH_EMULATION */
@@ -1028,7 +1150,6 @@ do { \
 	 "3" ((char *) (addr)),"2" ((seg) << 16)); \
 } while (0)
 
-
 /*
  * This needs to use 'idt_table' rather than 'idt', and
  * thus use the _nonmapped_ version of the IDT, as the
diff -uNrp linux-2.6.14.5/arch/i386/mach-visws/visws_apic.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mach-visws/visws_apic.c
--- linux-2.6.14.5/arch/i386/mach-visws/visws_apic.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mach-visws/visws_apic.c	2006-01-22 13:01:13.000000000 +0100
@@ -198,7 +198,7 @@ static irqreturn_t piix4_master_intr(int
 	irq_desc_t *desc;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	spin_lock_irqsave_hw(&i8259A_lock, flags);
 
 	/* Find out what's interrupting in the PIIX4 master 8259 */
 	outb(0x0c, 0x20);		/* OCW3 Poll command */
@@ -235,7 +235,7 @@ static irqreturn_t piix4_master_intr(int
 		outb(0x60 + realirq, 0x20);
 	}
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 
 	desc = irq_desc + realirq;
 
@@ -253,7 +253,7 @@ static irqreturn_t piix4_master_intr(int
 	return IRQ_HANDLED;
 
 out_unlock:
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	spin_unlock_irqrestore_hw(&i8259A_lock, flags);
 	return IRQ_NONE;
 }
 
diff -uNrp linux-2.6.14.5/arch/i386/mm/fault.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mm/fault.c
--- linux-2.6.14.5/arch/i386/mm/fault.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mm/fault.c	2006-01-22 13:01:13.000000000 +0100
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995  Linus Torvalds
  */
 
+#include <linux/ltt/ltt-facility-kernel.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -237,6 +238,8 @@ fastcall void __kprobes do_page_fault(st
 	/* get the address */
         address = read_cr2();
 
+	local_irq_enable_hw_cond();
+
 	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 					SIGSEGV) == NOTIFY_STOP)
 		return;
@@ -280,6 +283,8 @@ fastcall void __kprobes do_page_fault(st
 	if (in_atomic() || !mm)
 		goto bad_area_nosemaphore;
 
+	trace_kernel_trap_entry(14, (void*)regs->eip);
+
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
 	 * kernel and should generate an OOPS.  Unfortunatly, in the case of an
@@ -377,6 +382,7 @@ good_area:
 			tsk->thread.screen_bitmap |= 1 << bit;
 	}
 	up_read(&mm->mmap_sem);
+	trace_kernel_trap_exit();
 	return;
 
 /*
@@ -415,6 +421,7 @@ bad_area_nosemaphore:
 
 		if (nr == 6) {
 			do_invalid_op(regs, 0);
+			trace_kernel_trap_exit();
 			return;
 		}
 	}
@@ -422,16 +429,20 @@ bad_area_nosemaphore:
 
 no_context:
 	/* Are we prepared to handle this kernel fault?  */
-	if (fixup_exception(regs))
+	if (fixup_exception(regs)) {
+		trace_kernel_trap_exit();
 		return;
+	}
 
 	/* 
 	 * Valid to do another page fault here, because if this fault
 	 * had been triggered by is_prefetch fixup_exception would have 
 	 * handled it.
 	 */
- 	if (is_prefetch(regs, address, error_code))
+ 	if (is_prefetch(regs, address, error_code)) {
+		trace_kernel_trap_exit();
  		return;
+	}
 
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
@@ -503,13 +514,16 @@ do_sigbus:
 		goto no_context;
 
 	/* User space => ok to do another page fault */
-	if (is_prefetch(regs, address, error_code))
+	if (is_prefetch(regs, address, error_code)) {
+		trace_kernel_trap_exit();
 		return;
+	}
 
 	tsk->thread.cr2 = address;
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = 14;
 	force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
+	trace_kernel_trap_exit();
 	return;
 
 vmalloc_fault:
@@ -555,6 +569,9 @@ vmalloc_fault:
 		pte_k = pte_offset_kernel(pmd_k, address);
 		if (!pte_present(*pte_k))
 			goto no_context;
+		trace_kernel_trap_entry(14, (void*)regs->eip);
+		trace_kernel_trap_exit();
 		return;
 	}
+	trace_kernel_trap_exit();
 }
diff -uNrp linux-2.6.14.5/arch/i386/mm/ioremap.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mm/ioremap.c
--- linux-2.6.14.5/arch/i386/mm/ioremap.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/i386/mm/ioremap.c	2006-01-22 13:01:13.000000000 +0100
@@ -17,6 +17,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 
 #define ISA_START_ADDRESS	0xa0000
 #define ISA_END_ADDRESS		0x100000
@@ -93,6 +94,7 @@ static int ioremap_page_range(unsigned l
 		err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
 		if (err)
 			break;
+		set_pgdir(addr, *pgd);
 	} while (pgd++, addr = next, addr != end);
 	spin_unlock(&init_mm.page_table_lock);
 	flush_tlb_all();
diff -uNrp linux-2.6.14.5/arch/mips/kernel/irq.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/irq.c
--- linux-2.6.14.5/arch/mips/kernel/irq.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/irq.c	2006-01-22 13:01:13.000000000 +0100
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/ltt-events.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/slab.h>
@@ -49,8 +50,12 @@ asmlinkage unsigned int do_IRQ(unsigned 
 {
 	irq_enter();
 
+	ltt_ev_irq_entry(irq, !(user_mode(regs)));
+
 	__do_IRQ(irq, regs);
 
+	ltt_ev_irq_exit();
+
 	irq_exit();
 
 	return 1;
diff -uNrp linux-2.6.14.5/arch/mips/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/traps.c
--- linux-2.6.14.5/arch/mips/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/traps.c	2006-01-22 13:01:13.000000000 +0100
@@ -13,12 +13,14 @@
  */
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/ltt-events.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/unistd.h>
 #include <linux/kallsyms.h>
 
 #include <asm/bootinfo.h>
@@ -231,7 +233,7 @@ void show_regs(struct pt_regs *regs)
 
 	printk("Cause : %08x\n", cause);
 
-	cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+	cause = CAUSE_EXCCODE(cause);
 	if (1 <= cause && cause <= 5)
 		printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
 
@@ -507,6 +509,7 @@ asmlinkage void do_ov(struct pt_regs *re
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
+	ltt_ev_trap_entry(CAUSE_EXCCODE(regs->cp0_cause), regs->cp0_epc);
 	if (fcr31 & FPU_CSR_UNI_X) {
 		int sig;
 
@@ -646,6 +649,8 @@ asmlinkage void do_cpu(struct pt_regs *r
 
 	die_if_kernel("do_cpu invoked from kernel context!", regs);
 
+	ltt_ev_trap_entry(CAUSE_EXCCODE(regs->cp0_cause), regs->cp0_epc);
+
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 
 	switch (cpid) {
@@ -1060,3 +1065,72 @@ void __init trap_init(void)
 
 	flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
 }
+
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(struct pt_regs * regs)
+{
+	unsigned long       addr;
+	int                 depth = 0;
+	unsigned long       end_code;
+	unsigned long       lower_bound;
+	int                 seek_depth;
+	unsigned long       *stack;
+	unsigned long       start_code;
+	unsigned long       *start_stack;
+	ltt_syscall_entry trace_syscall_event;
+	unsigned long       upper_bound;
+	int                 use_bounds;
+	int                 use_depth;
+
+	/* syscall_id will be negative for SVR4, IRIX5, BSD43, and POSIX
+	 * syscalls -- these are not supported at this point by LTT
+	 */
+	trace_syscall_event.syscall_id = (uint8_t) (regs->regs[2] - __NR_Linux);
+
+	trace_syscall_event.address  = regs->cp0_epc;
+
+	if (!user_mode(regs))
+		goto trace_syscall_end;
+
+	if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth,
+				 (void*)&lower_bound, (void*)&upper_bound) < 0)
+		goto trace_syscall_end;
+
+	/* Heuristic that might work:
+	 * (BUT DOESN'T WORK for any of the cases I tested...) zzz
+	 * Search through stack until a value is found that is within the
+	 * range start_code .. end_code.  (This is looking for a return
+	 * pointer to where a shared library was called from.)  If a stack
+	 * variable contains a valid code address then an incorrect
+	 * result will be generated.
+	 */
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		stack       = (unsigned long*) regs->regs[29];
+		end_code    = current->mm->end_code;
+		start_code  = current->mm->start_code;
+		start_stack = (unsigned long *)current->mm->start_stack;
+
+		while ((stack <= start_stack) && (!__get_user(addr, stack))) {
+			if ((addr > start_code) && (addr < end_code)) {
+				if (((use_depth  == 1) && (depth == seek_depth)) ||
+				    ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) {
+					trace_syscall_event.address = addr;
+					goto trace_syscall_end;
+				} else {
+					depth++;
+				}
+			}
+		stack++;
+		}
+	}
+
+trace_syscall_end:
+	ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+	ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif /* (CONFIG_LTT) */
diff -uNrp linux-2.6.14.5/arch/mips/kernel/unaligned.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/unaligned.c
--- linux-2.6.14.5/arch/mips/kernel/unaligned.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/kernel/unaligned.c	2006-01-22 13:01:13.000000000 +0100
@@ -78,6 +78,7 @@
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/ltt-events.h>
 
 #include <asm/asm.h>
 #include <asm/branch.h>
@@ -497,14 +498,18 @@ asmlinkage void do_ade(struct pt_regs *r
 	mm_segment_t seg;
 	unsigned long pc;
 
+	ltt_ev_trap_entry(CAUSE_EXCCODE(regs->cp0_cause), regs->cp0_epc);
+
 	/*
 	 * Address errors may be deliberately induced by the FPU emulator to
 	 * retake control of the CPU after executing the instruction in the
 	 * delay slot of an emulated branch.
 	 */
 	/* Terminate if exception was recognized as a delay slot return */
-	if (do_dsemulret(regs))
+	if (do_dsemulret(regs)) {
+		ltt_ev_trap_exit();
 		return;
+	}
 
 	/* Otherwise handle as normal */
 
@@ -538,6 +543,8 @@ asmlinkage void do_ade(struct pt_regs *r
 	}
 	set_fs(seg);
 
+	ltt_ev_trap_exit();
+
 	return;
 
 sigbus:
@@ -547,4 +554,6 @@ sigbus:
 	/*
 	 * XXX On return from the signal handler we should advance the epc
 	 */
+
+	ltt_ev_trap_exit();
 }
diff -uNrp linux-2.6.14.5/arch/mips/mm/fault.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/mm/fault.c
--- linux-2.6.14.5/arch/mips/mm/fault.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/mips/mm/fault.c	2006-01-22 13:01:13.000000000 +0100
@@ -13,6 +13,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/ltt-events.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -60,6 +61,8 @@ asmlinkage void do_page_fault(struct pt_
 	if (unlikely(address >= VMALLOC_START))
 		goto vmalloc_fault;
 
+	ltt_ev_trap_entry(CAUSE_EXCCODE(regs->cp0_cause), regs->cp0_epc);
+
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
@@ -114,6 +117,7 @@ survive:
 	}
 
 	up_read(&mm->mmap_sem);
+	ltt_ev_trap_exit();
 	return;
 
 /*
@@ -142,6 +146,7 @@ bad_area_nosemaphore:
 		/* info.si_code has been set above */
 		info.si_addr = (void *) address;
 		force_sig_info(SIGSEGV, &info, tsk);
+		ltt_ev_trap_exit();
 		return;
 	}
 
@@ -199,6 +204,7 @@ do_sigbus:
 	info.si_addr = (void *) address;
 	force_sig_info(SIGBUS, &info, tsk);
 
+	ltt_ev_trap_exit();
 	return;
 
 vmalloc_fault:
@@ -233,4 +239,5 @@ vmalloc_fault:
 			goto no_context;
 		return;
 	}
+	ltt_ev_trap_exit();
 }
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/entry.S linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/entry.S
--- linux-2.6.14.5/arch/ppc/kernel/entry.S	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/entry.S	2006-01-22 13:01:13.000000000 +0100
@@ -157,6 +157,33 @@ transfer_to_handler_cont:
 	SYNC
 	RFI				/* jump to handler, enable MMU */
 
+#if (CONFIG_LTT)
+#define TRACE_REAL_ASM_SYSCALL_ENTRY	\
+	SAVE_NVGPRS(r1);	\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;  	/* Put pointer to registers into r3 */	\
+	mflr	r29;				/* Save LR */ \
+	bl	trace_real_syscall_entry;	/* Call real trace function */ \
+	mtlr	r29;				/* Restore LR */ \
+	lwz	r0,GPR0(r1);			/* Restore original registers */ \
+	lwz	r3,GPR3(r1);	\
+	lwz	r4,GPR4(r1);	\
+	lwz	r5,GPR5(r1);	\
+	lwz	r6,GPR6(r1);	\
+	lwz	r7,GPR7(r1);	\
+	lwz	r8,GPR8(r1);	\
+	REST_NVGPRS(r1);
+#define TRACE_REAL_ASM_SYSCALL_EXIT \
+	bl	trace_real_syscall_exit;	/* Call real trace function */ \
+	lwz	r0,GPR0(r1);			/* Restore original registers */ \
+	lwz	r3,RESULT(r1); \
+	lwz	r4,GPR4(r1); \
+	lwz	r5,GPR5(r1); \
+	lwz	r6,GPR6(r1); \
+	lwz	r7,GPR7(r1); \
+	lwz	r8,GPR8(r1); \
+	addi	r9,r1,STACK_FRAME_OVERHEAD;
+#endif
+
 /*
  * On kernel stack overflow, load up an initial stack pointer
  * and call StackOverflow(regs), which should not return.
@@ -214,6 +241,9 @@ syscall_dotrace_cont:
 	bge-	66f
 	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
 	mtlr	r10
+#if (CONFIG_LTT)
+ 	TRACE_REAL_ASM_SYSCALL_ENTRY ;
+#endif
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 	PPC440EP_ERR42
 	blrl			/* Call handler */
@@ -222,6 +252,10 @@ ret_from_syscall:
 #ifdef SHOW_SYSCALLS
 	bl	do_show_syscall_exit
 #endif
+#if (CONFIG_LTT)
+	stw	r3,RESULT(r1)	/* Save result */
+ 	TRACE_REAL_ASM_SYSCALL_EXIT ;
+#endif
 	mr	r6,r3
 	li	r11,-_LAST_ERRNO
 	cmplw	0,r3,r11
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/misc.S linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/misc.S
--- linux-2.6.14.5/arch/ppc/kernel/misc.S	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/misc.S	2006-01-22 13:01:13.000000000 +0100
@@ -1128,7 +1128,11 @@ _GLOBAL(cvt_df)
  * Create a kernel thread
  *   kernel_thread(fn, arg, flags)
  */
+#if (CONFIG_LTT)
+_GLOBAL(original_kernel_thread)
+#else
 _GLOBAL(kernel_thread)
+#endif /* (CONFIG_LTT) */
 	stwu	r1,-16(r1)
 	stw	r30,8(r1)
 	stw	r31,12(r1)
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/process.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/process.c
--- linux-2.6.14.5/arch/ppc/kernel/process.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/process.c	2006-01-22 13:01:13.000000000 +0100
@@ -37,6 +37,7 @@
 #include <linux/kallsyms.h>
 #include <linux/mqueue.h>
 #include <linux/hardirq.h>
+#include <linux/ltt-events.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -353,6 +354,19 @@ void show_regs(struct pt_regs * regs)
 	show_stack(current, (unsigned long *) regs->gpr[1]);
 }
 
+#if (CONFIG_LTT)
+long original_kernel_thread(int (*fn) (void *), void* arg, unsigned long flags);
+long kernel_thread(int (*fn) (void *), void* arg, unsigned long flags)
+{
+        long   retval;
+
+	retval = original_kernel_thread(fn, arg, flags);
+	if (retval > 0)
+		ltt_ev_process(LTT_EV_PROCESS_KTHREAD, retval, (int) fn);
+	return retval;
+}
+#endif /* (CONFIG_LTT) */
+
 void exit_thread(void)
 {
 	if (last_task_used_math == current)
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/syscalls.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/syscalls.c
--- linux-2.6.14.5/arch/ppc/kernel/syscalls.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/syscalls.c	2006-01-22 13:01:13.000000000 +0100
@@ -36,6 +36,7 @@
 #include <linux/utsname.h>
 #include <linux/file.h>
 #include <linux/unistd.h>
+#include <linux/ltt-events.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -55,6 +56,8 @@ sys_ipc (uint call, int first, int secon
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
 	ret = -ENOSYS;
 	switch (call) {
 	case SEMOP:
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/time.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/time.c
--- linux-2.6.14.5/arch/ppc/kernel/time.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/time.c	2006-01-22 13:01:13.000000000 +0100
@@ -57,6 +57,7 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/profile.h>
+#include <linux/ltt-events.h>
 
 #include <asm/io.h>
 #include <asm/nvram.h>
@@ -136,6 +137,8 @@ void timer_interrupt(struct pt_regs * re
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
 
+ 	ltt_ev_trap_entry(regs->trap, instruction_pointer(regs));
+
 	irq_enter();
 
 	while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) {
@@ -188,6 +191,8 @@ void timer_interrupt(struct pt_regs * re
 		ppc_md.heartbeat();
 
 	irq_exit();
+
+ 	ltt_ev_trap_exit();
 }
 
 /*
diff -uNrp linux-2.6.14.5/arch/ppc/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/traps.c
--- linux-2.6.14.5/arch/ppc/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/kernel/traps.c	2006-01-22 13:01:13.000000000 +0100
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/prctl.h>
+#include <linux/ltt-events.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -739,6 +740,81 @@ void StackOverflow(struct pt_regs *regs)
 	panic("kernel stack overflow");
 }
 
+/* Trace related code */
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(struct pt_regs *regs)
+{
+	int use_depth;
+	int use_bounds;
+	int depth = 0;
+	int seek_depth;
+	unsigned long lower_bound;
+	unsigned long upper_bound;
+	unsigned long addr;
+	unsigned long *stack;
+	ltt_syscall_entry trace_syscall_event;
+
+	/* Set the syscall ID */
+	trace_syscall_event.syscall_id = (uint8_t) regs->gpr[0];
+
+	/* Set the address in any case */
+	trace_syscall_event.address = instruction_pointer(regs);
+
+	/* Are we in the kernel (This is a kernel thread)? */
+	if (!user_mode(regs))
+		/* Don't go digining anywhere */
+		goto trace_syscall_end;
+
+	/* Get the trace configuration */
+	if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth,
+				(void *) &lower_bound, (void *) &upper_bound) < 0)
+		goto trace_syscall_end;
+
+	/* Do we have to search for an eip address range */
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		/* Start at the top of the stack (bottom address since stacks grow downward) */
+		stack = (unsigned long *) regs->gpr[1];
+
+		/* Skip over first stack frame as the return address isn't valid */
+		if (get_user(addr, stack))
+			goto trace_syscall_end;
+		stack = (unsigned long *) addr;
+
+		/* Keep on going until we reach the end of the process' stack limit (wherever it may be) */
+		while (!get_user(addr, stack + 1)) {	/* "stack + 1", since this is where the IP is */
+			/* Does this LOOK LIKE an address in the program */
+			if ((addr > current->mm->start_code)
+			    && (addr < current->mm->end_code)) {
+				/* Does this address fit the description */
+				if (((use_depth == 1) && (depth == seek_depth))
+				    || ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) {
+					/* Set the address */
+					trace_syscall_event.address = addr;
+
+					/* We're done */
+					goto trace_syscall_end;
+				} else
+					/* We're one depth more */
+					depth++;
+			}
+			/* Go on to the next address */
+			if (get_user(addr, stack))
+				goto trace_syscall_end;
+			stack = (unsigned long *) addr;
+		}
+	}
+trace_syscall_end:
+	/* Trace the event */
+	ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+	ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif				/* (CONFIG_LTT) */
+
 void nonrecoverable_exception(struct pt_regs *regs)
 {
 	printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
diff -uNrp linux-2.6.14.5/arch/ppc/mm/fault.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/mm/fault.c
--- linux-2.6.14.5/arch/ppc/mm/fault.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/ppc/mm/fault.c	2006-01-22 13:01:13.000000000 +0100
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/ltt-events.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -116,22 +117,29 @@ int do_page_fault(struct pt_regs *regs, 
 		is_write = error_code & 0x02000000;
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
 
+	ltt_ev_trap_entry(regs->trap, instruction_pointer(regs));
+
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
 	if (debugger_fault_handler && TRAP(regs) == 0x300) {
 		debugger_fault_handler(regs);
+		ltt_ev_trap_exit();
 		return 0;
 	}
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
 	if (error_code & 0x00400000) {
 		/* DABR match */
-		if (debugger_dabr_match(regs))
+		if (debugger_dabr_match(regs)) {
+			ltt_ev_trap_exit();;
 			return 0;
+		}
 	}
 #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
 #endif /* CONFIG_XMON || CONFIG_KGDB */
 
-	if (in_atomic() || mm == NULL)
+	if (in_atomic() || mm == NULL) {
+		ltt_ev_trap_exit();
 		return SIGSEGV;
+	}
 
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
@@ -228,6 +236,7 @@ good_area:
 			_tlbie(address);
 			pte_unmap(ptep);
 			up_read(&mm->mmap_sem);
+			ltt_ev_trap_exit();
 			return 0;
 		}
 		if (ptep != NULL)
@@ -279,6 +288,7 @@ bad_area:
 	/* User mode accesses cause a SIGSEGV */
 	if (user_mode(regs)) {
 		_exception(SIGSEGV, regs, code, address);
+		ltt_ev_trap_exit();
 		return 0;
 	}
 
@@ -298,6 +308,7 @@ out_of_memory:
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
+	ltt_ev_trap_exit();
 	return SIGKILL;
 
 do_sigbus:
@@ -307,6 +318,7 @@ do_sigbus:
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void __user *)address;
 	force_sig_info (SIGBUS, &info, current);
+	ltt_ev_trap_exit();
 	if (!user_mode(regs))
 		return SIGBUS;
 	return 0;
diff -uNrp linux-2.6.14.5/arch/s390/kernel/entry.S linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/entry.S
--- linux-2.6.14.5/arch/s390/kernel/entry.S	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/entry.S	2006-01-22 13:01:14.000000000 +0100
@@ -8,6 +8,8 @@
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>
+ *  Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie,
+ *	IBM Corporation
  */
 
 #include <linux/sys.h>
@@ -229,6 +231,13 @@ sysc_do_restart:
                                   # ATTENTION: check sys_execve_glue before
                                   # changing anything here !!
 
+#if (CONFIG_LTT) /* tjh - ltt port */
+        /* add call to trace_real_syscall_exit */
+        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
+        l       %r1,BASED(.Ltracesysext)
+        basr    %r14,%r1
+        lm      %r0,%r6,SP_R0(%r15) /* restore call clobbered regs */
+#endif
 sysc_return:
 	tm	SP_PSW+1(%r15),0x01	# returning to user ?
 	bno	BASED(sysc_leave)
diff -uNrp linux-2.6.14.5/arch/s390/kernel/sys_s390.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/sys_s390.c
--- linux-2.6.14.5/arch/s390/kernel/sys_s390.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/sys_s390.c	2006-01-22 13:01:14.000000000 +0100
@@ -151,6 +151,8 @@ asmlinkage long sys_ipc(uint call, int f
         struct ipc_kludge tmp;
 	int ret;
 
+        ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
         switch (call) {
         case SEMOP:
 		return sys_semtimedop(first, (struct sembuf __user *)ptr,
diff -uNrp linux-2.6.14.5/arch/s390/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/traps.c
--- linux-2.6.14.5/arch/s390/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/kernel/traps.c	2006-01-22 13:01:14.000000000 +0100
@@ -5,6 +5,7 @@
  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *  Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation
  *
  *  Derived from "arch/i386/kernel/traps.c"
  *    Copyright (C) 1991, 1992 Linus Torvalds
@@ -30,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/kallsyms.h>
 #include <linux/reboot.h>
+#include <linux/ltt-events.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -312,6 +314,9 @@ report_user_fault(long interruption_code
 static void inline do_trap(long interruption_code, int signr, char *str,
                            struct pt_regs *regs, siginfo_t *info)
 {
+         trapid_t ltt_interruption_code;
+         char * ic_ptr = (char *) &ltt_interruption_code;
+
 	/*
 	 * We got all needed information from the lowcore and can
 	 * now safely switch on interrupts.
@@ -319,6 +324,10 @@ static void inline do_trap(long interrup
         if (regs->psw.mask & PSW_MASK_PSTATE)
 		local_irq_enable();
 
+	memset(&ltt_interruption_code,0,sizeof(ltt_interruption_code));
+	memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code));
+	ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN));
+
         if (regs->psw.mask & PSW_MASK_PSTATE) {
                 struct task_struct *tsk = current;
 
@@ -333,6 +342,7 @@ static void inline do_trap(long interrup
                 else
                         die(str, regs, interruption_code);
         }
+	ltt_ev_trap_exit();
 }
 
 static inline void *get_check_address(struct pt_regs *regs)
@@ -429,6 +439,8 @@ asmlinkage void illegal_op(struct pt_reg
 	siginfo_t info;
         __u8 opcode[6];
 	__u16 *location;
+        trapid_t ltt_interruption_code;
+        char * ic_ptr = (char *) &ltt_interruption_code;
 	int signal = 0;
 
 	location = (__u16 *) get_check_address(regs);
@@ -491,6 +503,7 @@ asmlinkage void illegal_op(struct pt_reg
 		do_trap(interruption_code, signal,
 			"illegal operation", regs, &info);
 	}
+	ltt_ev_trap_exit();
 }
 
 
@@ -500,6 +513,8 @@ specification_exception(struct pt_regs *
 {
         __u8 opcode[6];
 	__u16 *location = NULL;
+        trapid_t ltt_interruption_code;
+        char * ic_ptr = (char *) &ltt_interruption_code;
 	int signal = 0;
 
 	location = (__u16 *) get_check_address(regs);
@@ -555,6 +570,7 @@ specification_exception(struct pt_regs *
 		do_trap(interruption_code, signal, 
 			"specification exception", regs, &info);
 	}
+	ltt_ev_trap_exit();
 }
 #else
 DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
@@ -564,6 +580,8 @@ DO_ERROR_INFO(SIGILL, "specification exc
 asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
 {
 	__u16 *location;
+        trapid_t ltt_interruption_code;
+        char * ic_ptr = (char *) &ltt_interruption_code;
 	int signal = 0;
 
 	location = (__u16 *) get_check_address(regs);
@@ -575,6 +593,10 @@ asmlinkage void data_exception(struct pt
 	if (regs->psw.mask & PSW_MASK_PSTATE)
 		local_irq_enable();
 
+	memset(&ltt_interruption_code,0,sizeof(ltt_interruption_code));
+	memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code));
+	ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN));
+
 	if (MACHINE_HAS_IEEE)
 		__asm__ volatile ("stfpc %0\n\t" 
 				  : "=m" (current->thread.fp_regs.fpc));
@@ -650,6 +672,7 @@ asmlinkage void data_exception(struct pt
 		do_trap(interruption_code, signal, 
 			"data exception", regs, &info);
 	}
+	ltt_ev_trap_exit();
 }
 
 asmlinkage void space_switch_exception(struct pt_regs * regs, long int_code)
diff -uNrp linux-2.6.14.5/arch/s390/mm/fault.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/mm/fault.c
--- linux-2.6.14.5/arch/s390/mm/fault.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/s390/mm/fault.c	2006-01-22 13:01:14.000000000 +0100
@@ -5,6 +5,7 @@
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com)
  *               Ulrich Weigand (uweigand@de.ibm.com)
+ *  Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation
  *
  *  Derived from "arch/i386/mm/fault.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -170,6 +171,8 @@ do_exception(struct pt_regs *regs, unsig
 	int user_address;
 	const struct exception_table_entry *fixup;
 	int si_code = SEGV_MAPERR;
+	trapid_t ltt_interruption_code;
+	char * ic_ptr = (char *) &ltt_interruption_code;
 
         tsk = current;
         mm = tsk->mm;
@@ -217,6 +220,9 @@ do_exception(struct pt_regs *regs, unsig
 	 */
 	local_irq_enable();
 
+        memset(&ltt_interruption_code,0,sizeof(ltt_interruption_code));
+        memcpy(ic_ptr+4,&error_code,sizeof(error_code));
+        ltt_ev_trap_entry(ltt_interruption_code,(regs->psw.addr & PSW_ADDR_INSN));
         down_read(&mm->mmap_sem);
 
         vma = find_vma(mm, address);
@@ -284,6 +290,7 @@ bad_area:
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
 		do_sigsegv(regs, error_code, si_code, address);
+                ltt_ev_trap_exit();
                 return;
 	}
 
@@ -339,6 +346,8 @@ do_sigbus:
 	/* Kernel mode? Handle exceptions or die */
 	if (!(regs->psw.mask & PSW_MASK_PSTATE))
 		goto no_context;
+
+	ltt_ev_trap_exit();
 }
 
 void do_protection_exception(struct pt_regs *regs, unsigned long error_code)
diff -uNrp linux-2.6.14.5/arch/sh/kernel/irq.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/irq.c
--- linux-2.6.14.5/arch/sh/kernel/irq.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/irq.c	2006-01-22 13:01:14.000000000 +0100
@@ -32,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
 #include <linux/bitops.h>
+#include <linux/ltt-events.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
diff -uNrp linux-2.6.14.5/arch/sh/kernel/process.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/process.c
--- linux-2.6.14.5/arch/sh/kernel/process.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/process.c	2006-01-22 13:01:14.000000000 +0100
@@ -20,6 +20,7 @@
 #include <linux/ptrace.h>
 #include <linux/platform.h>
 #include <linux/kallsyms.h>
+#include <linux/ltt-events.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff -uNrp linux-2.6.14.5/arch/sh/kernel/sys_sh.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/sys_sh.c
--- linux-2.6.14.5/arch/sh/kernel/sys_sh.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/sys_sh.c	2006-01-22 13:01:14.000000000 +0100
@@ -21,6 +21,7 @@
 #include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
+#include <linux/ltt-events.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -174,6 +175,8 @@ asmlinkage int sys_ipc(uint call, int fi
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
 	if (call <= SEMCTL)
 		switch (call) {
 		case SEMOP:
diff -uNrp linux-2.6.14.5/arch/sh/kernel/traps.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/traps.c
--- linux-2.6.14.5/arch/sh/kernel/traps.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/kernel/traps.c	2006-01-22 13:01:14.000000000 +0100
@@ -27,6 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/ltt-events.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -500,6 +501,8 @@ asmlinkage void do_address_error(struct 
 
 	asm volatile("stc       r2_bank,%0": "=r" (error_code));
 
+	ltt_ev_trap_entry(error_code >> 5, regs->pc);
+
 	oldfs = get_fs();
 
 	if (user_mode(regs)) {
@@ -523,8 +526,10 @@ asmlinkage void do_address_error(struct 
 		tmp = handle_unaligned_access(instruction, regs);
 		set_fs(oldfs);
 
-		if (tmp==0)
-			return; /* sorted */
+		if (tmp==0) {
+			ltt_ev_trap_exit();
+ 			return; /* sorted */
+		}
 
 	uspace_segv:
 		printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm);
@@ -545,6 +550,7 @@ asmlinkage void do_address_error(struct 
 		handle_unaligned_access(instruction, regs);
 		set_fs(oldfs);
 	}
+	ltt_ev_trap_exit();
 }
 
 #ifdef CONFIG_SH_DSP
@@ -704,6 +710,74 @@ void show_task(unsigned long *sp)
 {
 	show_stack(NULL, sp);
 }
+/* Trace related code */
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(struct pt_regs *regs)
+{
+	int use_depth;
+	int use_bounds;
+	int depth = 0;
+	int seek_depth;
+	unsigned long lower_bound;
+	unsigned long upper_bound;
+	unsigned long addr;
+	unsigned long *stack;
+	ltt_syscall_entry trace_syscall_event;
+
+	/* Set the syscall ID */
+	trace_syscall_event.syscall_id = (uint8_t) regs->regs[REG_REG0 + 3];
+
+	/* Set the address in any case */
+	trace_syscall_event.address = regs->pc;
+
+	/* Are we in the kernel (This is a kernel thread)? */
+	if (!user_mode(regs))
+		/* Don't go digining anywhere */
+		goto trace_syscall_end;
+
+	/* Get the trace configuration */
+	if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth,
+				(void *) &lower_bound, (void *) &upper_bound) < 0)
+		goto trace_syscall_end;
+
+	/* Do we have to search for an eip address range */
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		/* Start at the top of the stack (bottom address since stacks grow downward) */
+		stack = (unsigned long *) regs->regs[REG_REG15];
+
+		/* Keep on going until we reach the end of the process' stack limit (wherever it may be) */
+		while (!get_user(addr, stack)) {
+			/* Does this LOOK LIKE an address in the program */
+			/* TODO: does this work with shared libraries?? - Greg Banks */
+			if ((addr > current->mm->start_code) && (addr < current->mm->end_code)) {
+				/* Does this address fit the description */
+				if (((use_depth == 1) && (depth == seek_depth))
+				    || ((use_bounds == 1) && (addr > lower_bound)
+					&& (addr < upper_bound))) {
+					/* Set the address */
+					trace_syscall_event.address = addr;
+
+					/* We're done */
+					goto trace_syscall_end;
+				} else
+					/* We're one depth more */
+					depth++;
+			}
+			/* Go on to the next address */
+			stack++;
+		}
+	}
+trace_syscall_end:
+	/* Trace the event */
+	ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+	ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif				/* (CONFIG_LTT) */
 
 void dump_stack(void)
 {
diff -uNrp linux-2.6.14.5/arch/sh/mm/fault.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/mm/fault.c
--- linux-2.6.14.5/arch/sh/mm/fault.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/arch/sh/mm/fault.c	2006-01-22 13:01:14.000000000 +0100
@@ -21,6 +21,7 @@
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/ltt-events.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -53,6 +54,14 @@ asmlinkage void do_page_fault(struct pt_
 	tsk = current;
 	mm = tsk->mm;
 
+#if (CONFIG_LTT)
+	{
+		unsigned long trapnr;
+		asm volatile("stc       r2_bank,%0": "=r" (trapnr));
+		ltt_ev_trap_entry(trapnr >> 5, regs->pc);  /* trap 4,5 or 6 */
+	}
+#endif
+
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
@@ -106,6 +115,7 @@ survive:
 	}
 
 	up_read(&mm->mmap_sem);
+	ltt_ev_trap_exit();
 	return;
 
 /*
@@ -119,6 +129,7 @@ bad_area:
 		tsk->thread.address = address;
 		tsk->thread.error_code = writeaccess;
 		force_sig(SIGSEGV, tsk);
+		ltt_ev_trap_exit();
 		return;
 	}
 
@@ -185,6 +196,8 @@ do_sigbus:
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
 		goto no_context;
+
+	ltt_ev_trap_exit();
 }
 
 /*
diff -uNrp linux-2.6.14.5/Documentation/ioctl-number.txt linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/Documentation/ioctl-number.txt
--- linux-2.6.14.5/Documentation/ioctl-number.txt	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/Documentation/ioctl-number.txt	2006-01-22 13:01:14.155316504 +0100
@@ -194,3 +194,5 @@ Code	Seq#	Include File		Comments
 					<mailto:aherrman@de.ibm.com>
 0xF3	00-3F	video/sisfb.h		sisfb (in development)
 					<mailto:thomas@winischhofer.net>
+0xF4	00-3F	linux/relayfs_fs.h RelayFS
+
diff -uNrp linux-2.6.14.5/fs/buffer.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/buffer.c
--- linux-2.6.14.5/fs/buffer.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/buffer.c	2006-01-22 13:01:14.000000000 +0100
@@ -18,6 +18,7 @@
  * async buffer flushing, 1999 Andrea Arcangeli <andrea@suse.de>
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/syscalls.h>
@@ -89,7 +90,9 @@ void fastcall unlock_buffer(struct buffe
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
+	trace_fs_buf_wait_start((void*)bh);
 	wait_on_bit(&bh->b_state, BH_Lock, sync_buffer, TASK_UNINTERRUPTIBLE);
+	trace_fs_buf_wait_end((void*)bh);
 }
 
 static void
diff -uNrp linux-2.6.14.5/fs/exec.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/exec.c
--- linux-2.6.14.5/fs/exec.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/exec.c	2006-01-22 13:01:14.000000000 +0100
@@ -22,6 +22,7 @@
  * formats. 
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/file.h>
@@ -1147,6 +1148,7 @@ int do_execve(char * filename,
 	struct file *file;
 	int retval;
 	int i;
+	lttng_sequence_fs_exec_filename lttng_name;
 
 	retval = -ENOMEM;
 	bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
@@ -1159,6 +1161,10 @@ int do_execve(char * filename,
 	if (IS_ERR(file))
 		goto out_kfree;
 
+	lttng_name.len = file->f_dentry->d_name.len;
+	lttng_name.array = file->f_dentry->d_name.name;
+	trace_fs_exec(&lttng_name);
+
 	sched_exec();
 
 	bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
diff -uNrp linux-2.6.14.5/fs/ioctl.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/ioctl.c
--- linux-2.6.14.5/fs/ioctl.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/ioctl.c	2006-01-22 13:01:14.000000000 +0100
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/config.h>
 #include <linux/syscalls.h>
 #include <linux/mm.h>
@@ -60,7 +61,6 @@ static int file_ioctl(struct file *filp,
 				return -EPERM;
 			if ((error = get_user(block, p)) != 0)
 				return error;
-
 			lock_kernel();
 			res = mapping->a_ops->bmap(mapping, block);
 			unlock_kernel();
@@ -166,6 +166,8 @@ asmlinkage long sys_ioctl(unsigned int f
 	if (!filp)
 		goto out;
 
+	trace_fs_ioctl(fd, cmd, arg);
+
 	error = security_file_ioctl(filp, cmd, arg);
 	if (error)
 		goto out_fput;
diff -uNrp linux-2.6.14.5/fs/open.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/open.c
--- linux-2.6.14.5/fs/open.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/open.c	2006-01-22 13:01:14.000000000 +0100
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/utime.h>
@@ -19,6 +20,7 @@
 #include <linux/security.h>
 #include <linux/mount.h>
 #include <linux/vfs.h>
+
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/personality.h>
@@ -957,6 +959,8 @@ long do_sys_open(const char __user *file
 	char *tmp = getname(filename);
 	int fd = PTR_ERR(tmp);
 
+	lttng_sequence_fs_open_filename lttng_name;
+
 	if (!IS_ERR(tmp)) {
 		fd = get_unused_fd();
 		if (fd >= 0) {
@@ -966,6 +970,10 @@ long do_sys_open(const char __user *file
 				fd = PTR_ERR(f);
 			} else {
 				fsnotify_open(f->f_dentry);
+				lttng_name.len = f->f_dentry->d_name.len;
+				lttng_name.array = f->f_dentry->d_name.name;
+				trace_fs_open(&lttng_name,
+						fd);
 				fd_install(fd, f);
 			}
 		}
@@ -1038,6 +1046,7 @@ asmlinkage long sys_close(unsigned int f
 	filp = fdt->fd[fd];
 	if (!filp)
 		goto out_unlock;
+	trace_fs_close(fd);
 	rcu_assign_pointer(fdt->fd[fd], NULL);
 	FD_CLR(fd, fdt->close_on_exec);
 	__put_unused_fd(files, fd);
diff -uNrp linux-2.6.14.5/fs/read_write.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/read_write.c
--- linux-2.6.14.5/fs/read_write.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/read_write.c	2006-01-22 13:01:14.000000000 +0100
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/slab.h> 
 #include <linux/stat.h>
 #include <linux/fcntl.h>
@@ -142,6 +143,9 @@ asmlinkage off_t sys_lseek(unsigned int 
 		if (res != (loff_t)retval)
 			retval = -EOVERFLOW;	/* LFS: should only happen on 32 bit platforms */
 	}
+
+	trace_fs_seek(fd, offset, origin);
+
 	fput_light(file, fput_needed);
 bad:
 	return retval;
@@ -169,6 +173,8 @@ asmlinkage long sys_llseek(unsigned int 
 	offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
 			origin);
 
+	trace_fs_seek(fd, offset, origin);
+
 	retval = (int)offset;
 	if (offset >= 0) {
 		retval = -EFAULT;
@@ -334,6 +340,7 @@ asmlinkage ssize_t sys_read(unsigned int
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		loff_t pos = file_pos_read(file);
+		trace_fs_read(fd, count);
 		ret = vfs_read(file, buf, count, &pos);
 		file_pos_write(file, pos);
 		fput_light(file, fput_needed);
@@ -352,6 +359,7 @@ asmlinkage ssize_t sys_write(unsigned in
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		loff_t pos = file_pos_read(file);
+		trace_fs_write(fd, count);
 		ret = vfs_write(file, buf, count, &pos);
 		file_pos_write(file, pos);
 		fput_light(file, fput_needed);
@@ -373,8 +381,11 @@ asmlinkage ssize_t sys_pread64(unsigned 
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		ret = -ESPIPE;
-		if (file->f_mode & FMODE_PREAD)
+		if (file->f_mode & FMODE_PREAD) {
+			trace_fs_read(fd, count);
 			ret = vfs_read(file, buf, count, &pos);
+		}
+
 		fput_light(file, fput_needed);
 	}
 
@@ -394,8 +405,10 @@ asmlinkage ssize_t sys_pwrite64(unsigned
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		ret = -ESPIPE;
-		if (file->f_mode & FMODE_PWRITE)  
+ 		if (file->f_mode & FMODE_PWRITE) {
+			trace_fs_write(fd, count);
 			ret = vfs_write(file, buf, count, &pos);
+		}
 		fput_light(file, fput_needed);
 	}
 
@@ -590,6 +603,7 @@ sys_readv(unsigned long fd, const struct
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		loff_t pos = file_pos_read(file);
+		trace_fs_read(fd, vlen);
 		ret = vfs_readv(file, vec, vlen, &pos);
 		file_pos_write(file, pos);
 		fput_light(file, fput_needed);
@@ -611,6 +625,7 @@ sys_writev(unsigned long fd, const struc
 	file = fget_light(fd, &fput_needed);
 	if (file) {
 		loff_t pos = file_pos_read(file);
+		trace_fs_write(fd, vlen);
 		ret = vfs_writev(file, vec, vlen, &pos);
 		file_pos_write(file, pos);
 		fput_light(file, fput_needed);
diff -uNrp linux-2.6.14.5/fs/relayfs/inode.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/relayfs/inode.c
--- linux-2.6.14.5/fs/relayfs/inode.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/relayfs/inode.c	2006-01-22 13:01:14.000000000 +0100
@@ -61,7 +61,7 @@ static struct inode *relayfs_get_inode(s
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	switch (mode & S_IFMT) {
 	case S_IFREG:
-		inode->i_fop = &relayfs_file_operations;
+		inode->i_fop = &chan->fops;
 		RELAYFS_I(inode)->buf = buf;
 		break;
 	case S_IFDIR:
@@ -206,10 +206,10 @@ int relayfs_remove(struct dentry *dentry
 	parent = dget(parent);
 	down(&parent->d_inode->i_sem);
 	if (dentry->d_inode) {
-		if (S_ISDIR(dentry->d_inode->i_mode))
-			error = simple_rmdir(parent->d_inode, dentry);
-		else
-			error = simple_unlink(parent->d_inode, dentry);
+		//if (S_ISDIR(dentry->d_inode->i_mode))
+		//	error = simple_rmdir(parent->d_inode, dentry);
+		//else
+		error = simple_unlink(parent->d_inode, dentry);
 		if (!error)
 			d_delete(dentry);
 	}
@@ -232,6 +232,9 @@ int relayfs_remove(struct dentry *dentry
  */
 int relayfs_remove_dir(struct dentry *dentry)
 {
+	if (!dentry)
+		return -EINVAL;
+
 	return relayfs_remove(dentry);
 }
 
@@ -245,6 +248,12 @@ int relayfs_remove_dir(struct dentry *de
 static int relayfs_open(struct inode *inode, struct file *filp)
 {
 	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+
+	if(!atomic_dec_and_test(&buf->open_count)) {
+		atomic_inc(&buf->open_count);
+		return -EACCES;
+	}
+	
 	kref_get(&buf->kref);
 
 	return 0;
@@ -288,6 +297,7 @@ static unsigned int relayfs_poll(struct 
 	return mask;
 }
 
+
 /**
  *	relayfs_release - release file op for relayfs files
  *	@inode: the inode
@@ -299,6 +309,9 @@ static unsigned int relayfs_poll(struct 
 static int relayfs_release(struct inode *inode, struct file *filp)
 {
 	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+
+	atomic_inc(&buf->open_count);
+	
 	kref_put(&buf->kref, relay_remove_buf);
 
 	return 0;
@@ -444,6 +457,13 @@ static size_t relayfs_read_end_pos(struc
 	return end_pos;
 }
 
+int relayfs_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	printk(KERN_WARNING "Relayfs ioctl unimplemented\n");
+	return -EPERM;
+}
+
 /**
  *	relayfs_read - read file op for relayfs files
  *	@filp: the file
@@ -518,14 +538,34 @@ static void init_once(void *p, kmem_cach
 		inode_init_once(&i->vfs_inode);
 }
 
-struct file_operations relayfs_file_operations = {
-	.open		= relayfs_open,
-	.poll		= relayfs_poll,
-	.mmap		= relayfs_mmap,
-	.read		= relayfs_read,
-	.llseek		= no_llseek,
-	.release	= relayfs_release,
-};
+void setup_fileops(struct rchan *chan,
+				   struct file_operations *fops)
+{
+	memset(&chan->fops, 0, sizeof(chan->fops));
+	
+	chan->fops.open = fops->open;
+	chan->fops.poll = fops->poll;
+	chan->fops.mmap = fops->mmap;
+	chan->fops.release = fops->release;
+	chan->fops.ioctl = fops->ioctl;
+	chan->fops.llseek = fops->llseek;
+	chan->fops.read = fops->read;
+	
+	if (!chan->fops.open)
+		chan->fops.open = relayfs_open;
+	if (!chan->fops.poll)
+		chan->fops.poll = relayfs_poll;
+	if (!chan->fops.mmap)
+		chan->fops.mmap = relayfs_mmap;
+	if (!chan->fops.read)
+		chan->fops.read = relayfs_read;
+	if (!chan->fops.llseek)
+		chan->fops.llseek = no_llseek;
+	if (!chan->fops.release)
+		chan->fops.release = relayfs_release;
+	if (!chan->fops.ioctl)
+		chan->fops.ioctl = relayfs_ioctl;
+}
 
 static struct super_operations relayfs_ops = {
 	.statfs		= simple_statfs,
@@ -573,10 +613,16 @@ static struct file_system_type relayfs_f
 	.kill_sb	= kill_litter_super,
 };
 
+#ifdef CONFIG_IPIPE
+extern unsigned relay_wakeup_virq;
+void relay_wakeup_trampoline(unsigned virq);
+#endif /* CONFIG_IPIPE */
+
 static int __init init_relayfs_fs(void)
 {
 	int err;
 
+	printk(KERN_DEBUG "relayfs init\n");
 	relayfs_inode_cachep = kmem_cache_create("relayfs_inode_cache",
 				sizeof(struct relayfs_inode_info), 0,
 				0, init_once, NULL);
@@ -587,19 +633,38 @@ static int __init init_relayfs_fs(void)
 	if (err)
 		kmem_cache_destroy(relayfs_inode_cachep);
 
+#ifdef CONFIG_IPIPE
+	relay_wakeup_virq = ipipe_alloc_virq();
+
+	if (!relay_wakeup_virq) {
+	    printk(KERN_ERR "relayfs: no virtual interrupt available.\n");
+	    err = -EBUSY;
+	}
+	else
+	  err = ipipe_virtualize_irq(ipipe_root_domain,
+				     relay_wakeup_virq,
+				     &relay_wakeup_trampoline,
+				     NULL,
+				     IPIPE_HANDLE_MASK);
+#endif /* CONFIG_IPIPE */
+
 	return err;
 }
 
+
 static void __exit exit_relayfs_fs(void)
 {
+#ifdef CONFIG_IPIPE
+  ipipe_virtualize_irq(ipipe_root_domain,relay_wakeup_virq,NULL,NULL,0);
+  ipipe_free_virq(relay_wakeup_virq);
+#endif /* CONFIG_IPIPE */
 	unregister_filesystem(&relayfs_fs_type);
 	kmem_cache_destroy(relayfs_inode_cachep);
 }
 
-module_init(init_relayfs_fs)
+fs_initcall(init_relayfs_fs);
 module_exit(exit_relayfs_fs)
 
-EXPORT_SYMBOL_GPL(relayfs_file_operations);
 EXPORT_SYMBOL_GPL(relayfs_create_dir);
 EXPORT_SYMBOL_GPL(relayfs_remove_dir);
 
diff -uNrp linux-2.6.14.5/fs/relayfs/relay.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/relayfs/relay.c
--- linux-2.6.14.5/fs/relayfs/relay.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/relayfs/relay.c	2006-01-22 13:01:14.000000000 +0100
@@ -18,6 +18,12 @@
 #include "relay.h"
 #include "buffers.h"
 
+#ifdef CONFIG_IPIPE
+LIST_HEAD(relay_wakeup_queue);
+unsigned relay_wakeup_virq;
+spinlock_t relay_wakeup_spinlock = SPIN_LOCK_UNLOCKED;
+#endif /* CONFIG_IPIPE */
+
 /**
  *	relay_buf_empty - boolean, is the channel buffer empty?
  *	@buf: channel buffer
@@ -65,6 +71,15 @@ static int subbuf_start_default_callback
 }
 
 /*
+ * deliver() default callback.  Does nothing.
+ */
+static void deliver_default_callback (struct rchan_buf *buf,
+				      unsigned subbuf_idx,
+				      void *subbuf)
+{
+}
+
+/*
  * buf_mapped() default callback.  Does nothing.
  */
 static void buf_mapped_default_callback(struct rchan_buf *buf,
@@ -80,11 +95,32 @@ static void buf_unmapped_default_callbac
 {
 }
 
+/*
+ * buf_full() default callback.  Does nothing.
+ */
+static void buf_full_default_callback(struct rchan_buf *buf,
+				      unsigned subbuf_idx,
+				      void *subbuf)
+{
+}
+
+/*
+ * buf_unfull() default callback.  Does nothing.
+ */
+static void buf_unfull_default_callback(struct rchan_buf *buf,
+				      unsigned subbuf_idx,
+				      void *subbuf)
+{
+}
+
 /* relay channel default callbacks */
 static struct rchan_callbacks default_channel_callbacks = {
 	.subbuf_start = subbuf_start_default_callback,
+	.deliver = deliver_default_callback,
 	.buf_mapped = buf_mapped_default_callback,
 	.buf_unmapped = buf_unmapped_default_callback,
+	.buf_full = buf_full_default_callback,
+	.buf_unfull = buf_unfull_default_callback,
 };
 
 /**
@@ -101,10 +137,48 @@ static void wakeup_readers(void *private
 	wake_up_interruptible(&buf->read_wait);
 }
 
+#ifdef CONFIG_IPIPE
+
+void relay_wakeup_trampoline (unsigned virq)
+{
+    struct list_head *pos, *npos;
+    unsigned long flags;
+
+    spin_lock_irqsave_hw(&relay_wakeup_spinlock,flags);
+
+    list_for_each_safe(pos,npos,&relay_wakeup_queue) {
+        struct rchan_buf *buf = list_entry(pos,struct rchan_buf,wake_link);
+	list_del(&buf->wake_link);
+	spin_unlock_irqrestore_hw(&relay_wakeup_spinlock,flags);
+	PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf);
+	clear_bit(0,&buf->wake_posted);
+	schedule_delayed_work(&buf->wake_readers, 1);
+	spin_lock_irqsave_hw(&relay_wakeup_spinlock,flags);
+    }
+
+    spin_unlock_irqrestore_hw(&relay_wakeup_spinlock,flags);
+}
+
+#endif /* CONFIG_IPIPE */
+
+/**
+ *	get_next_subbuf - return next sub-buffer within channel buffer
+ *	@buf: channel buffer
+ */
+static inline void *get_next_subbuf(struct rchan_buf *buf)
+{
+	void *next = buf->data + buf->chan->subbuf_size;
+	if (next >= buf->start + buf->chan->subbuf_size * buf->chan->n_subbufs)
+		next = buf->start;
+
+	return next;
+}
+
 /**
  *	__relay_reset - reset a channel buffer
  *	@buf: the channel buffer
  *	@init: 1 if this is a first-time initialization
+ *	@subbufs_count number of subbuffers
  *
  *	See relay_reset for description of effect.
  */
@@ -116,6 +190,10 @@ static inline void __relay_reset(struct 
 		init_waitqueue_head(&buf->read_wait);
 		kref_init(&buf->kref);
 		INIT_WORK(&buf->wake_readers, NULL, NULL);
+#ifdef CONFIG_IPIPE
+		INIT_LIST_HEAD(&buf->wake_link);
+		buf->wake_posted = 0;
+#endif /* CONFIG_IPIPE */
 	} else {
 		cancel_delayed_work(&buf->wake_readers);
 		flush_scheduled_work();
@@ -124,9 +202,11 @@ static inline void __relay_reset(struct 
 	buf->subbufs_produced = 0;
 	buf->subbufs_consumed = 0;
 	buf->bytes_consumed = 0;
+	atomic_set(&buf->full, 0);
 	buf->finalized = 0;
 	buf->data = buf->start;
 	buf->offset = 0;
+	atomic_set(&buf->open_count, 1);
 
 	for (i = 0; i < buf->chan->n_subbufs; i++)
 		buf->padding[i] = 0;
@@ -138,6 +218,8 @@ static inline void __relay_reset(struct 
  *	relay_reset - reset the channel
  *	@chan: the channel
  *
+ *	Returns 0 if successful, negative if not.
+ *
  *	This has the effect of erasing all data from all channel buffers
  *	and restarting the channel in its initial state.  The buffers
  *	are not freed, so any mappings are still in effect.
@@ -195,8 +277,8 @@ static inline void relay_close_buf(struc
 {
 	buf->finalized = 1;
 	buf->chan->cb = &default_channel_callbacks;
-	cancel_delayed_work(&buf->wake_readers);
-	flush_scheduled_work();
+	//cancel_delayed_work(&buf->wake_readers);
+	//flush_scheduled_work();
 	kref_put(&buf->kref, relay_remove_buf);
 }
 
@@ -210,10 +292,16 @@ static inline void setup_callbacks(struc
 
 	if (!cb->subbuf_start)
 		cb->subbuf_start = subbuf_start_default_callback;
+	if (!cb->deliver)
+		cb->deliver = deliver_default_callback;
 	if (!cb->buf_mapped)
 		cb->buf_mapped = buf_mapped_default_callback;
 	if (!cb->buf_unmapped)
 		cb->buf_unmapped = buf_unmapped_default_callback;
+	if (!cb->buf_full)
+		cb->buf_full = buf_full_default_callback;
+	if (!cb->buf_unfull)
+		cb->buf_unfull = buf_unfull_default_callback;
 	chan->cb = cb;
 }
 
@@ -223,7 +311,11 @@ static inline void setup_callbacks(struc
  *	@parent: dentry of parent directory, NULL for root directory
  *	@subbuf_size: size of sub-buffers
  *	@n_subbufs: number of sub-buffers
+ *	@overwrite: overwrite buffer when full?
  *	@cb: client callback functions
+ *	@fops: client file operations (override relayfs). NULL for default.
+ *	@client_data: client specific data
+ *	@free_client_data_cb: callback function to free the client data.
  *
  *	Returns channel pointer if successful, NULL otherwise.
  *
@@ -231,12 +323,18 @@ static inline void setup_callbacks(struc
  *	attributes specified.  The created channel buffer files
  *	will be named base_filename0...base_filenameN-1.  File
  *	permissions will be S_IRUSR.
+ *	relay_open increments the usage count of the client_module.
  */
 struct rchan *relay_open(const char *base_filename,
 			 struct dentry *parent,
 			 size_t subbuf_size,
 			 size_t n_subbufs,
-			 struct rchan_callbacks *cb)
+			 int overwrite,
+			 struct module *client_module,
+			 struct rchan_callbacks *cb,
+			 struct file_operations *fops,
+			 void *client_data,
+			 void (*free_client_data_cb)(void*))
 {
 	unsigned int i;
 	struct rchan *chan;
@@ -253,10 +351,19 @@ struct rchan *relay_open(const char *bas
 		return NULL;
 
 	chan->version = RELAYFS_CHANNEL_VERSION;
+	chan->overwrite = overwrite;
 	chan->n_subbufs = n_subbufs;
 	chan->subbuf_size = subbuf_size;
 	chan->alloc_size = FIX_SIZE(subbuf_size * n_subbufs);
+	chan->client_module = client_module;
+	if(!try_module_get(client_module)) {
+		printk(KERN_ERR "RelayFS : cannot increment client module refcount\n");
+		return NULL;
+	}
+	chan->client_data = client_data;
+	chan->free_client_data_cb = free_client_data_cb;
 	setup_callbacks(chan, cb);
+	setup_fileops(chan, fops);
 	kref_init(&chan->kref);
 
 	tmpname = kmalloc(NAME_MAX + 1, GFP_KERNEL);
@@ -264,7 +371,7 @@ struct rchan *relay_open(const char *bas
 		goto free_chan;
 
 	for_each_online_cpu(i) {
-		sprintf(tmpname, "%s%d", base_filename, i);
+		sprintf(tmpname, "%s_%d", base_filename, i);
 		chan->buf[i] = relay_open_buf(chan, tmpname, parent);
 		chan->buf[i]->cpu = i;
 		if (!chan->buf[i])
@@ -311,8 +418,24 @@ size_t relay_switch_subbuf(struct rchan_
 		buf->padding[old_subbuf] = buf->prev_padding;
 		buf->subbufs_produced++;
 		if (waitqueue_active(&buf->read_wait)) {
-			PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf);
-			schedule_delayed_work(&buf->wake_readers, 1);
+#ifdef CONFIG_IPIPE
+		  if (ipipe_current_domain != ipipe_root_domain) {
+		      if (!test_and_set_bit(0,&buf->wake_posted)) {
+			unsigned long flags;
+			spin_lock_irqsave_hw(&relay_wakeup_spinlock,flags);
+			list_add_tail(&buf->wake_link,&relay_wakeup_queue);
+			spin_unlock_irqrestore_hw(&relay_wakeup_spinlock,flags);
+			ipipe_propagate_irq(relay_wakeup_virq);
+		      }
+		    }
+		  else {
+		      PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf);
+		      schedule_delayed_work(&buf->wake_readers, 1);	      
+		    }
+#else /* !CONFIG_IPIPE */
+		  PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf);
+		  schedule_delayed_work(&buf->wake_readers, 1);
+#endif /* CONFIG_IPIPE */
 		}
 	}
 
@@ -333,7 +456,10 @@ size_t relay_switch_subbuf(struct rchan_
 	return length;
 
 toobig:
-	printk(KERN_WARNING "relayfs: event too large (%Zd)\n", length);
+	/* Fixme : we cannot, never ever, call a printk from LTT schedule and
+	 * wakeup instrumentation! A deadlock would occur. We must find another
+	 * way to print debug messages. */
+	//printk(KERN_WARNING "relayfs: event too large (%Zd)\n", length);
 	WARN_ON(1);
 	return 0;
 }
@@ -377,6 +503,9 @@ void relay_subbufs_consumed(struct rchan
 void relay_destroy_channel(struct kref *kref)
 {
 	struct rchan *chan = container_of(kref, struct rchan, kref);
+	module_put(chan->client_module);
+	if(chan->free_client_data_cb)
+		chan->free_client_data_cb(chan->client_data);
 	kfree(chan);
 }
 
diff -uNrp linux-2.6.14.5/fs/select.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/select.c
--- linux-2.6.14.5/fs/select.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/fs/select.c	2006-01-22 13:01:14.000000000 +0100
@@ -14,6 +14,7 @@
  *     of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
  */
 
+#include <linux/ltt/ltt-facility-fs.h>
 #include <linux/syscalls.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -228,6 +229,8 @@ int do_select(int n, fd_set_bits *fds, l
 				file = fget(i);
 				if (file) {
 					f_op = file->f_op;
+					trace_fs_select(i, /* The fd */
+													__timeout);
 					mask = DEFAULT_POLLMASK;
 					if (f_op && f_op->poll)
 						mask = (*f_op->poll)(file, retval ? NULL : wait);
@@ -420,6 +423,7 @@ static void do_pollfd(unsigned int num, 
 			struct file * file = fget(fd);
 			mask = POLLNVAL;
 			if (file != NULL) {
+				trace_fs_poll(fd);
 				mask = DEFAULT_POLLMASK;
 				if (file->f_op && file->f_op->poll)
 					mask = file->f_op->poll(file, *pwait);
diff -uNrp linux-2.6.14.5/include/asm-alpha/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-alpha/ltt.h
--- linux-2.6.14.5/include/asm-alpha/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-alpha/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef _ASM_ALPHA_LTT_H
+#define _ASM_ALPHA_LTT_H
+/*
+ * linux/include/asm-alpha/ltt.h
+ *
+ * Copyright (C) 2005 - Mathiey Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
+ * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
+ *
+ * alpha architecture specific definitions for ltt
+ */
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-arm/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-arm/ltt.h
--- linux-2.6.14.5/include/asm-arm/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-arm/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * ARM definitions for tracing system
+ */
+
+#ifndef _ASM_ARM_LTT_H
+#define _ASM_ARM_LTT_H
+
+#include <asm-generic/ltt.h>
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-arm26/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-arm26/ltt.h
--- linux-2.6.14.5/include/asm-arm26/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-arm26/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_ARM26_LTT_H
+#define _ASM_ARM26_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-cris/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-cris/ltt.h
--- linux-2.6.14.5/include/asm-cris/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-cris/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_CRIS_LTT_H
+#define _ASM_CRIS_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-frv/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-frv/ltt.h
--- linux-2.6.14.5/include/asm-frv/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-frv/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_FRV_LTT_H
+#define _ASM_FRV_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-generic/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-generic/ltt.h
--- linux-2.6.14.5/include/asm-generic/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-generic/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _ASM_GENERIC_LTT_H
+#define _ASM_GENERIC_LTT_H
+/*
+ * linux/include/asm-generic/ltt.h
+ *
+ * Copyright (C) 2005 - Mathiey Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
+ * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
+ *
+ * Architecture dependent definitions for ltt
+ * Architecture without TSC
+ */
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-h8300/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-h8300/ltt.h
--- linux-2.6.14.5/include/asm-h8300/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-h8300/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_H8300_LTT_H
+#define _ASM_H8300_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-i386/apic.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/apic.h
--- linux-2.6.14.5/include/asm-i386/apic.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/apic.h	2006-01-22 13:01:14.000000000 +0100
@@ -82,7 +82,13 @@ int get_physical_broadcast(void);
 # define apic_write_around(x,y) apic_write_atomic((x),(y))
 #endif
 
+#ifdef CONFIG_IPIPE
+#define ack_APIC_irq() do { } while(0)
+static inline void __ack_APIC_irq(void)
+#else /* !CONFIG_IPIPE */
+#define __ack_APIC_irq() ack_APIC_irq()
 static inline void ack_APIC_irq(void)
+#endif /* CONFIG_IPIPE */
 {
 	/*
 	 * ack_APIC_irq() actually gets compiled as a single instruction:
@@ -117,7 +123,7 @@ extern int reserve_lapic_nmi(void);
 extern void release_lapic_nmi(void);
 extern void disable_timer_nmi_watchdog(void);
 extern void enable_timer_nmi_watchdog(void);
-extern void nmi_watchdog_tick (struct pt_regs * regs);
+extern void (*nmi_watchdog_tick) (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
 extern void disable_APIC_timer(void);
 extern void enable_APIC_timer(void);
diff -uNrp linux-2.6.14.5/include/asm-i386/io_apic.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/io_apic.h
--- linux-2.6.14.5/include/asm-i386/io_apic.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/io_apic.h	2006-01-22 13:01:14.000000000 +0100
@@ -16,8 +16,14 @@
 #ifdef CONFIG_PCI_MSI
 static inline int use_pci_vector(void)	{return 1;}
 static inline void disable_edge_ioapic_vector(unsigned int vector) { }
+#ifdef CONFIG_IPIPE
+#ifndef CONFIG_IRQBALANCE
+static inline void end_edge_ioapic_vector (unsigned int vector) { }
+#endif /* !CONFIG_IRQBALANCE */
+#else /* !CONFIG_IPIPE */
 static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
 static inline void end_edge_ioapic_vector (unsigned int vector) { }
+#endif /* CONFIG_IPIPE */
 #define startup_level_ioapic	startup_level_ioapic_vector
 #define shutdown_level_ioapic	mask_IO_APIC_vector
 #define enable_level_ioapic	unmask_IO_APIC_vector
@@ -35,8 +41,14 @@ static inline void end_edge_ioapic_vecto
 #else
 static inline int use_pci_vector(void)	{return 0;}
 static inline void disable_edge_ioapic_irq(unsigned int irq) { }
+#ifdef CONFIG_IPIPE
+#ifndef CONFIG_IRQBALANCE
+static inline void end_edge_ioapic_irq (unsigned int irq) { }
+#endif /* !CONFIG_IRQBALANCE */
+#else /* CONFIG_IPIPE */
 static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
 static inline void end_edge_ioapic_irq (unsigned int irq) { }
+#endif /* CONFIG_IPIPE */
 #define startup_level_ioapic	startup_level_ioapic_irq
 #define shutdown_level_ioapic	mask_IO_APIC_irq
 #define enable_level_ioapic	unmask_IO_APIC_irq
diff -uNrp linux-2.6.14.5/include/asm-i386/ipipe.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/ipipe.h
--- linux-2.6.14.5/include/asm-i386/ipipe.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/ipipe.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,207 @@
+/*   -*- linux-c -*-
+ *   include/asm-i386/ipipe.h
+ *
+ *   Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __I386_IPIPE_H
+#define __I386_IPIPE_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IPIPE
+
+#include <linux/threads.h>
+#include <irq_vectors.h>
+
+#define IPIPE_ARCH_STRING	"1.1-00"
+#define IPIPE_MAJOR_NUMBER	1
+#define IPIPE_MINOR_NUMBER	1
+#define IPIPE_PATCH_NUMBER	0
+
+#ifdef CONFIG_X86_LOCAL_APIC
+/* We want to cover the whole IRQ space when the APIC is enabled. */
+#ifdef CONFIG_PCI_MSI
+#define IPIPE_NR_XIRQS NR_IRQS
+#else	/* CONFIG_PCI_MSI */
+#define IPIPE_NR_XIRQS   224
+#endif	/* CONFIG_PCI_MSI */
+/* If the APIC is enabled, then we expose four service vectors in the
+   APIC space which are freely available to domains. */
+#define IPIPE_SERVICE_VECTOR0	0xf5
+#define IPIPE_SERVICE_IPI0	(IPIPE_SERVICE_VECTOR0 - FIRST_EXTERNAL_VECTOR)
+#define IPIPE_SERVICE_VECTOR1	0xf6
+#define IPIPE_SERVICE_IPI1	(IPIPE_SERVICE_VECTOR1 - FIRST_EXTERNAL_VECTOR)
+#define IPIPE_SERVICE_VECTOR2	0xf7
+#define IPIPE_SERVICE_IPI2	(IPIPE_SERVICE_VECTOR2 - FIRST_EXTERNAL_VECTOR)
+#define IPIPE_SERVICE_VECTOR3	0xf8
+#define IPIPE_SERVICE_IPI3	(IPIPE_SERVICE_VECTOR3 - FIRST_EXTERNAL_VECTOR)
+#else	/* !CONFIG_X86_LOCAL_APIC */
+#define IPIPE_NR_XIRQS		NR_IRQS
+#endif	/* CONFIG_X86_LOCAL_APIC */
+
+#define IPIPE_IRQ_ISHIFT  	5	/* 2^5 for 32bits arch. */
+#define NR_XIRQS		IPIPE_NR_XIRQS
+
+#define ex_do_divide_error		0
+#define ex_do_debug			1
+/* NMI not pipelined. */
+#define ex_do_int3			3
+#define ex_do_overflow			4
+#define ex_do_bounds			5
+#define ex_do_invalid_op		6
+#define ex_device_not_available		7
+/* Double fault not pipelined. */
+#define ex_do_coprocessor_segment_overrun 9
+#define ex_do_invalid_TSS		10
+#define ex_do_segment_not_present	11
+#define ex_do_stack_segment		12
+#define ex_do_general_protection	13
+#define ex_do_page_fault		14
+#define ex_do_spurious_interrupt_bug	15
+#define ex_do_coprocessor_error		16
+#define ex_do_alignment_check		17
+#define ex_machine_check_vector		18
+#define ex_do_simd_coprocessor_error	19
+#define ex_do_iret_error		32
+
+#ifndef __ASSEMBLY__
+
+#include <linux/cpumask.h>
+#include <linux/list.h>
+#include <linux/threads.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_SMP
+
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <mach_apicdef.h>
+#include <linux/thread_info.h>
+
+#define IPIPE_CRITICAL_VECTOR  0xf9	/* Used by ipipe_critical_enter/exit() */
+#define IPIPE_CRITICAL_IPI     (IPIPE_CRITICAL_VECTOR - FIRST_EXTERNAL_VECTOR)
+
+static inline int ipipe_processor_id(void)
+{
+	extern int (*__ipipe_logical_cpuid)(void);
+	return __ipipe_logical_cpuid();
+}
+
+extern u8 __ipipe_apicid_2_cpu[];
+
+#define ipipe_note_apicid(apicid,cpu)  \
+do {	\
+	__ipipe_apicid_2_cpu[apicid] = cpu; \
+} while(0)
+
+#else	/* !CONFIG_SMP */
+
+#define ipipe_note_apicid(apicid,cpu)  do { } while(0)
+#define ipipe_processor_id()    0
+
+#endif	/* CONFIG_SMP */
+
+#define prepare_arch_switch(next) \
+do { \
+	__ipipe_dispatch_event(IPIPE_EVENT_SCHEDULE,next);	\
+	local_irq_disable_hw();					\
+} while(0)
+
+#define task_hijacked(p)	\
+  ({ int x = ipipe_current_domain != ipipe_root_domain; \
+     __clear_bit(IPIPE_SYNC_FLAG,&ipipe_root_domain->cpudata[task_cpu(p)].status); \
+     local_irq_enable_hw(); x; })
+
+/* IDT fault vectors */
+#define IPIPE_NR_FAULTS		33 /* 32 from IDT + iret_error */
+/* Pseudo-vectors used for kernel events */
+#define IPIPE_FIRST_EVENT	IPIPE_NR_FAULTS
+#define IPIPE_EVENT_SYSCALL	(IPIPE_FIRST_EVENT)
+#define IPIPE_EVENT_SCHEDULE	(IPIPE_FIRST_EVENT + 1)
+#define IPIPE_EVENT_SIGWAKE	(IPIPE_FIRST_EVENT + 2)
+#define IPIPE_EVENT_SETSCHED	(IPIPE_FIRST_EVENT + 3)
+#define IPIPE_EVENT_EXIT	(IPIPE_FIRST_EVENT + 4)
+#define IPIPE_LAST_EVENT	IPIPE_EVENT_EXIT
+#define IPIPE_NR_EVENTS		(IPIPE_LAST_EVENT + 1)
+
+struct ipipe_domain;
+
+struct ipipe_sysinfo {
+
+	int ncpus;		/* Number of CPUs on board */
+	u64 cpufreq;		/* CPU frequency (in Hz) */
+
+	/* Arch-dependent block */
+
+	struct {
+		unsigned tmirq;	/* Timer tick IRQ */
+		u64 tmfreq;	/* Timer frequency */
+	} archdep;
+};
+
+#define ipipe_read_tsc(t)  __asm__ __volatile__("rdtsc" : "=A" (t))
+#define ipipe_cpu_freq() ({ unsigned long long __freq = cpu_has_tsc?(1000LL * cpu_khz):CLOCK_TICK_RATE; __freq; })
+
+#define ipipe_tsc2ns(t) \
+({ \
+	unsigned long long delta = (t)*1000; \
+	do_div(delta, cpu_khz/1000+1); \
+	(unsigned long)delta; \
+})
+
+#define ipipe_tsc2us(t) \
+({ \
+    unsigned long long delta = (t); \
+    do_div(delta, cpu_khz/1000+1); \
+    (unsigned long)delta; \
+})
+
+/* Private interface -- Internal use only */
+
+#define __ipipe_check_platform() do { } while(0)
+
+#define __ipipe_init_platform() do { } while(0)
+
+void __ipipe_enable_pipeline(void);
+
+void fastcall __ipipe_sync_stage(unsigned long syncmask);
+
+int __ipipe_ack_system_irq(unsigned irq);
+
+int __ipipe_handle_irq(struct pt_regs regs);
+
+void __ipipe_do_critical_sync(unsigned irq);
+
+extern struct pt_regs __ipipe_tick_regs[];
+
+extern int __ipipe_tick_irq;
+
+#endif /* __ASSEMBLY__ */
+
+#else /* !CONFIG_IPIPE */
+
+#define task_hijacked(p)	0
+
+#define NR_XIRQS NR_IRQS
+
+#define ipipe_note_apicid(apicid,cpu)  do { } while(0)
+
+#endif /* CONFIG_IPIPE */
+
+#endif	/* !__I386_IPIPE_H */
diff -uNrp linux-2.6.14.5/include/asm-i386/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/ltt.h
--- linux-2.6.14.5/include/asm-i386/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,117 @@
+#ifndef _ASM_I386_LTT_H
+#define _ASM_I386_LTT_H
+/*
+ * linux/include/asm-i386/ltt.h
+ *
+ * Copyright (C) 2005 - Mathiey Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
+ * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
+ *
+ * i386 time and TSC definitions for ltt
+ */
+
+#include <linux/time.h>
+
+#include <asm/timex.h>
+#include <asm/processor.h>
+
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_I386
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
+
+#define LTT_TSC_READY
+
+/**
+ *	calc_time_delta - utility function for time delta calculation
+ *	@now: current time
+ *	@start: start time
+ *
+ *	Returns the time delta produced by subtracting start time from now.
+ */
+static inline u64
+calc_time_delta(struct timeval *now,
+		struct timeval *start)
+{
+	return (now->tv_sec - start->tv_sec) * USEC_PER_SEC
+		+ (now->tv_usec - start->tv_usec);
+}
+
+/**
+ *	get_time_delta - utility function for getting time delta
+ *	@now: pointer to a timeval struct that may be given current time
+ *	@start: the previous time
+ *
+ *	Returns either the TSC if TSCs are being used, or the time and the
+ *	time difference between the current time and the buffer start time
+ *	if TSCs are not being used.
+ *
+ *	We use the same validation as get_cycles() from asm-i386/timex.h : we cannot
+ *	rely on get_cycles() returning 0, because it is a possible value of the TSC.
+ */
+static inline u64
+get_time_delta(struct timeval *now, struct timeval *start)
+{
+	u64 time_delta;
+
+#ifndef CONFIG_X86_TSC
+	if (!cpu_has_tsc) {
+		do_gettimeofday(now);
+		time_delta = calc_time_delta(now, start);
+		return time_delta;
+	}
+#endif
+
+#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC)
+	time_delta = (u64)get_cycles();
+#else
+	do_gettimeofday(now);
+	time_delta = calc_time_delta(now, start);
+#endif
+	return time_delta;
+}
+
+/**
+ *	get_timestamp - utility function for getting a time and TSC pair
+ *	@now: current time
+ *	@tsc: the TSC associated with now
+ *
+ *	Sets the value pointed to by now to the current time and the value
+ *	pointed to by tsc to the tsc associated with that time, if the
+ *	platform supports TSC.
+ */
+static inline void
+get_timestamp(struct timeval *now,
+	      u64 *tsc)
+{
+	do_gettimeofday(now);
+	
+	*tsc = (u64)get_cycles();
+}
+
+/**
+ *	get_time_or_tsc - utility function for getting a time or a TSC
+ *	@now: current time
+ *	@tsc: current TSC
+ *
+ *	Sets the value pointed to by now to the current time or the value
+ *	pointed to by tsc to the current tsc, depending on whether we're
+ *	using TSCs or not.
+ */
+static inline void
+get_time_or_tsc(struct timeval *now,
+		u64 *tsc)
+{
+#ifndef CONFIG_X86_TSC
+	if (!cpu_has_tsc) {
+		do_gettimeofday(now);
+		return;
+	}
+#endif
+
+#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC)
+	*tsc = (u64)get_cycles();
+#else
+	do_gettimeofday(now);
+#endif
+}
+
+#endif //_ASM_I386_LTT_H
diff -uNrp linux-2.6.14.5/include/asm-i386/mach-default/do_timer.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mach-default/do_timer.h
--- linux-2.6.14.5/include/asm-i386/mach-default/do_timer.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mach-default/do_timer.h	2006-01-22 13:01:14.000000000 +0100
@@ -50,14 +50,15 @@ static inline void do_timer_interrupt_ho
 static inline int do_timer_overflow(int count)
 {
 	int i;
+	unsigned long flags;
 
-	spin_lock(&i8259A_lock);
+	spin_lock_irqsave_hw_cond(&i8259A_lock, flags);
 	/*
 	 * This is tricky when I/O APICs are used;
 	 * see do_timer_interrupt().
 	 */
 	i = inb(0x20);
-	spin_unlock(&i8259A_lock);
+	spin_unlock_irqrestore_hw_cond(&i8259A_lock, flags);
 	
 	/* assumption about timer being IRQ0 */
 	if (i & 0x01) {
diff -uNrp linux-2.6.14.5/include/asm-i386/mach-visws/do_timer.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mach-visws/do_timer.h
--- linux-2.6.14.5/include/asm-i386/mach-visws/do_timer.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mach-visws/do_timer.h	2006-01-22 13:01:14.000000000 +0100
@@ -29,14 +29,15 @@ static inline void do_timer_interrupt_ho
 static inline int do_timer_overflow(int count)
 {
 	int i;
+	unsigned long flags;
 
-	spin_lock(&i8259A_lock);
+	spin_lock_irqsave_hw_cond(&i8259A_lock, flags);
 	/*
 	 * This is tricky when I/O APICs are used;
 	 * see do_timer_interrupt().
 	 */
 	i = inb(0x20);
-	spin_unlock(&i8259A_lock);
+	spin_unlock_irqrestore_hw_cond(&i8259A_lock, flags);
 	
 	/* assumption about timer being IRQ0 */
 	if (i & 0x01) {
diff -uNrp linux-2.6.14.5/include/asm-i386/mmu_context.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mmu_context.h
--- linux-2.6.14.5/include/asm-i386/mmu_context.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/mmu_context.h	2006-01-22 13:01:14.000000000 +0100
@@ -67,6 +67,11 @@ static inline void switch_mm(struct mm_s
 	asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
 
 #define activate_mm(prev, next) \
-	switch_mm((prev),(next),NULL)
+do { \
+	unsigned long flags; \
+	local_irq_save_hw_cond(flags); \
+	switch_mm((prev),(next),NULL);		   \
+	local_irq_restore_hw_cond(flags);	   \
+} while(0)
 
 #endif
diff -uNrp linux-2.6.14.5/include/asm-i386/nmi.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/nmi.h
--- linux-2.6.14.5/include/asm-i386/nmi.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/nmi.h	2006-01-22 13:01:14.000000000 +0100
@@ -25,4 +25,6 @@ void set_nmi_callback(nmi_callback_t cal
  */
 void unset_nmi_callback(void);
  
+void die_nmi(struct pt_regs *, const char *msg);
+
 #endif /* ASM_NMI_H */
diff -uNrp linux-2.6.14.5/include/asm-i386/pgalloc.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/pgalloc.h
--- linux-2.6.14.5/include/asm-i386/pgalloc.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/pgalloc.h	2006-01-22 13:01:14.000000000 +0100
@@ -47,4 +47,27 @@ static inline void pte_free(struct page 
 
 #define check_pgt_cache()	do { } while (0)
 
+static inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+#ifdef CONFIG_IPIPE
+	struct task_struct * p;
+	struct page *page;
+	pgd_t *pgd;
+
+	read_lock(&tasklist_lock);
+
+	for_each_process(p) {
+		if(p->mm) 
+		    *pgd_offset(p->mm,address) = entry;
+	}
+
+	read_unlock(&tasklist_lock);
+
+	for (page = pgd_list; page; page = (struct page *)page->index) {
+		pgd = (pgd_t *)page_address(page);
+		pgd[address >> PGDIR_SHIFT] = entry;
+	}
+#endif /* CONFIG_IPIPE */
+}
+
 #endif /* _I386_PGALLOC_H */
diff -uNrp linux-2.6.14.5/include/asm-i386/spinlock.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/spinlock.h
--- linux-2.6.14.5/include/asm-i386/spinlock.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/spinlock.h	2006-01-22 13:01:14.000000000 +0100
@@ -32,6 +32,9 @@
 	"jmp 1b\n" \
 	"3:\n\t"
 
+#ifdef CONFIG_IPIPE
+#define __raw_spin_lock_string_flags __raw_spin_lock_string
+#else /* !CONFIG_IPIPE */
 #define __raw_spin_lock_string_flags \
 	"\n1:\t" \
 	"lock ; decb %0\n\t" \
@@ -47,6 +50,7 @@
 	"cli\n\t" \
 	"jmp 1b\n" \
 	"4:\n\t"
+#endif /* CONFIG_IPIPE */
 
 static inline void __raw_spin_lock(raw_spinlock_t *lock)
 {
diff -uNrp linux-2.6.14.5/include/asm-i386/system.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/system.h
--- linux-2.6.14.5/include/asm-i386/system.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-i386/system.h	2006-01-22 13:01:14.000000000 +0100
@@ -459,6 +459,51 @@ struct alt_instr { 
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* interrupt control.. */
+#ifdef CONFIG_IPIPE
+
+#include <linux/linkage.h>
+
+void __ipipe_stall_root(void);
+
+void __ipipe_unstall_root(void);
+
+unsigned long __ipipe_test_root(void);
+
+unsigned long __ipipe_test_and_stall_root(void);
+
+void fastcall __ipipe_restore_root(unsigned long flags);
+
+#define local_save_flags(x)	((x) = (!__ipipe_test_root()) << 9)
+#define local_irq_save(x)	((x) = (!__ipipe_test_and_stall_root()) << 9)
+#define local_irq_restore(x)	__ipipe_restore_root(!(x & 0x200))
+#define local_irq_disable()	__ipipe_stall_root()
+#define local_irq_enable()	__ipipe_unstall_root()
+
+#define irqs_disabled()		__ipipe_test_root()
+
+#define safe_halt() do { \
+    __ipipe_unstall_root(); \
+    __asm__ __volatile__("sti; hlt": : :"memory"); \
+} while(0)
+
+#define halt()	__asm__ __volatile__("hlt": : :"memory")
+
+#define ipipe_hw_save_flags_and_sti(x)	__asm__ __volatile__("pushfl ; popl %0 ; sti":"=g" (x): /* no input */ :"memory")
+#define local_irq_disable_hw() 			__asm__ __volatile__("cli": : :"memory")
+#define local_irq_enable_hw()			__asm__ __volatile__("sti": : :"memory")
+#define local_irq_save_hw(x)    __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
+#define local_irq_restore_hw(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
+#define local_save_flags_hw(x)   __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
+#define local_test_iflag_hw(x)   ((x) & (1<<9))
+#define irqs_disabled_hw()	\
+({					\
+	unsigned long flags;		\
+	local_save_flags_hw(flags);	\
+	!local_test_iflag_hw(flags);	\
+})
+
+#else /* !CONFIG_IPIPE */
+
 #define local_save_flags(x)	do { typecheck(unsigned long,x); __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */); } while (0)
 #define local_irq_restore(x) 	do { typecheck(unsigned long,x); __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc"); } while (0)
 #define local_irq_disable() 	__asm__ __volatile__("cli": : :"memory")
@@ -478,6 +523,13 @@ struct alt_instr { 
 /* For spinlocks etc */
 #define local_irq_save(x)	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
 
+#define local_irq_save_hw(flags)	local_irq_save(flags)
+#define local_irq_restore_hw(flags)	local_irq_restore(flags)
+#define local_irq_enable_hw()		local_irq_enable()
+#define local_irq_disable_hw(flags)	local_irq_disable()
+
+#endif /* CONFIG_IPIPE */
+
 /*
  * disable hlt during certain critical i/o operations
  */
diff -uNrp linux-2.6.14.5/include/asm-ia64/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ia64/ltt.h
--- linux-2.6.14.5/include/asm-ia64/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ia64/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_IA64_LTT_H
+#define _ASM_IA64_LTT_H
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-m32r/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m32r/ltt.h
--- linux-2.6.14.5/include/asm-m32r/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m32r/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_M32R_LTT_H
+#define _ASM_M32R_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-m68k/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m68k/ltt.h
--- linux-2.6.14.5/include/asm-m68k/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m68k/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_M68K_LTT_H
+#define _ASM_M68K_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-m68knommu/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m68knommu/ltt.h
--- linux-2.6.14.5/include/asm-m68knommu/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-m68knommu/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_M68KNOMMU_LTT_H
+#define _ASM_M68KNOMMU_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-mips/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-mips/ltt.h
--- linux-2.6.14.5/include/asm-mips/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-mips/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-mips/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * MIPS definitions for tracing system
+ */
+
+#ifndef _ASM_MIPS_LTT_H
+#define _ASM_MIPS_LTT_H
+
+#define LTT_HAS_TSC
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_MIPS
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-mips/mipsregs.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-mips/mipsregs.h
--- linux-2.6.14.5/include/asm-mips/mipsregs.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-mips/mipsregs.h	2006-01-22 13:01:14.000000000 +0100
@@ -369,6 +369,7 @@
  */
 #define  CAUSEB_EXCCODE		2
 #define  CAUSEF_EXCCODE		(_ULCAST_(31)  <<  2)
+#define  CAUSE_EXCCODE(cause)	(((cause) & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE)
 #define  CAUSEB_IP		8
 #define  CAUSEF_IP		(_ULCAST_(255) <<  8)
 #define  CAUSEB_IP0		8
diff -uNrp linux-2.6.14.5/include/asm-parisc/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-parisc/ltt.h
--- linux-2.6.14.5/include/asm-parisc/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-parisc/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_PARISC_LTT_H
+#define _ASM_PARISC_LTT_H
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-ppc/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ppc/ltt.h
--- linux-2.6.14.5/include/asm-ppc/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ppc/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * linux/include/asm-ppc/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * PowerPC definitions for tracing system
+ */
+
+#ifndef _ASM_PPC_LTT_H
+#define _ASM_PPC_LTT_H
+
+#include <linux/config.h>
+
+#define LTT_HAS_TSC
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_PPC
+
+/* PowerPC variants */
+#define LTT_ARCH_VARIANT_PPC_4xx          1   /* 4xx systems (IBM embedded series) */
+#define LTT_ARCH_VARIANT_PPC_6xx          2   /* 6xx/7xx/74xx/8260/POWER3 systems (desktop flavor) */
+#define LTT_ARCH_VARIANT_PPC_8xx          3   /* 8xx system (Motoral embedded series) */
+#define LTT_ARCH_VARIANT_PPC_ISERIES      4   /* 8xx system (iSeries) */
+
+/* Current variant type */
+#if defined(CONFIG_4xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_4xx
+#elif defined(CONFIG_6xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_6xx
+#elif defined(CONFIG_8xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_8xx
+#elif defined(CONFIG_PPC_ISERIES)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_ISERIES
+#endif
+#endif //_ASM_PPC_LTT_H
diff -uNrp linux-2.6.14.5/include/asm-ppc64/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ppc64/ltt.h
--- linux-2.6.14.5/include/asm-ppc64/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-ppc64/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_PPC64_LTT_H
+#define _ASM_PPC64_LTT_H
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-s390/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-s390/ltt.h
--- linux-2.6.14.5/include/asm-s390/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-s390/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-s390/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * S/390 definitions for tracing system
+ */
+
+#ifndef _ASM_S390_LTT_H
+#define _ASM_S390_LTT_H
+
+#define LTT_HAS_TSC
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_S390
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
+
+#endif//_ASM_S390_LTT_H
diff -uNrp linux-2.6.14.5/include/asm-sh/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sh/ltt.h
--- linux-2.6.14.5/include/asm-sh/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sh/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-sh/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * SuperH definitions for tracing system
+ */
+
+#ifndef _ASM_SH_LTT_H
+#define _ASM_SH_LTT_H
+
+#include <asm-generic/ltt.h>
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-sh64/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sh64/ltt.h
--- linux-2.6.14.5/include/asm-sh64/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sh64/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-sh64/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * SuperH definitions for tracing system
+ */
+
+#ifndef _ASM_SH_LTT_H
+#define _ASM_SH_LTT_H
+
+#include <asm-generic/ltt.h>
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-sparc/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sparc/ltt.h
--- linux-2.6.14.5/include/asm-sparc/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sparc/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_SPARC_LTT_H
+#define _ASM_SPARC_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-sparc64/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sparc64/ltt.h
--- linux-2.6.14.5/include/asm-sparc64/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-sparc64/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef _ASM_SPARC64_LTT_H
+#define _ASM_SPARC64_LTT_H
+/*
+ * linux/include/asm-sparc64/ltt.h
+ *
+ * Copyright (C) 2005 - Mathiey Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
+ * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
+ *
+ * sparc64 time and TSC definitions for ltt
+ */
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-um/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-um/ltt.h
--- linux-2.6.14.5/include/asm-um/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-um/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-um/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ * 
+ */
+
+#ifndef _ASM_SH_LTT_H
+#define _ASM_SH_LTT_H
+
+#include <asm-generic/ltt.h>
+
+#endif
diff -uNrp linux-2.6.14.5/include/asm-v850/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-v850/ltt.h
--- linux-2.6.14.5/include/asm-v850/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-v850/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _ASM_V850_LTT_H
+#define _ASM_V850_LTT_H
+
+#include <asm-generic/ltt.h>
+#endif
diff -uNrp linux-2.6.14.5/include/asm-x86_64/ltt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-x86_64/ltt.h
--- linux-2.6.14.5/include/asm-x86_64/ltt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/asm-x86_64/ltt.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_X86_64_LTT_H
+#define _ASM_X86_64_LTT_H
+
+#define LTT_HAS_TSC
+
+#endif
diff -uNrp linux-2.6.14.5/include/linux/hardirq.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/hardirq.h
--- linux-2.6.14.5/include/linux/hardirq.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/hardirq.h	2006-01-22 13:01:14.000000000 +0100
@@ -87,8 +87,21 @@ extern void synchronize_irq(unsigned int
 # define synchronize_irq(irq)	barrier()
 #endif
 
+#ifdef CONFIG_IPIPE
+#define nmi_enter() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	irq_enter(); \
+} while(0)
+#define nmi_exit() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	sub_preempt_count(HARDIRQ_OFFSET); \
+} while(0)
+#else /* !CONFIG_IPIPE */
 #define nmi_enter()		irq_enter()
 #define nmi_exit()		sub_preempt_count(HARDIRQ_OFFSET)
+#endif /* CONFIG_IPIPE */
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 static inline void account_user_vtime(struct task_struct *tsk)
diff -uNrp linux-2.6.14.5/include/linux/ipipe.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ipipe.h
--- linux-2.6.14.5/include/linux/ipipe.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ipipe.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,768 @@
+/* -*- linux-c -*-
+ * include/linux/ipipe.h
+ *
+ * Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LINUX_IPIPE_H
+#define __LINUX_IPIPE_H
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <asm/ipipe.h>
+
+#ifdef CONFIG_IPIPE
+
+#define IPIPE_VERSION_STRING	IPIPE_ARCH_STRING
+#define IPIPE_RELEASE_NUMBER	((IPIPE_MAJOR_NUMBER << 16) | \
+				 (IPIPE_MINOR_NUMBER <<  8) | \
+				 (IPIPE_PATCH_NUMBER))
+
+#ifndef BROKEN_BUILTIN_RETURN_ADDRESS
+#define __BUILTIN_RETURN_ADDRESS0 ((unsigned long)__builtin_return_address(0))
+#define __BUILTIN_RETURN_ADDRESS1 ((unsigned long)__builtin_return_address(1))
+#endif /* !BUILTIN_RETURN_ADDRESS */
+
+#define IPIPE_ROOT_PRIO		100
+#define IPIPE_ROOT_ID		0
+#define IPIPE_ROOT_NPTDKEYS	4	/* Must be <= BITS_PER_LONG */
+
+#define IPIPE_RESET_TIMER	0x1
+#define IPIPE_GRAB_TIMER	0x2
+#define IPIPE_SAME_HANDLER	((void (*)(unsigned))(-1))
+
+/* Global domain flags */
+#define IPIPE_SPRINTK_FLAG	0	/* Synchronous printk() allowed */
+
+#define IPIPE_STALL_FLAG	0	/* Stalls a pipeline stage */
+#define IPIPE_SYNC_FLAG		1	/* The interrupt syncer is running for the domain */
+
+#define IPIPE_HANDLE_FLAG	0
+#define IPIPE_PASS_FLAG		1
+#define IPIPE_ENABLE_FLAG	2
+#define IPIPE_DYNAMIC_FLAG	IPIPE_HANDLE_FLAG
+#define IPIPE_STICKY_FLAG	3
+#define IPIPE_SYSTEM_FLAG	4
+#define IPIPE_LOCK_FLAG		5
+#define IPIPE_SHARED_FLAG	6
+#define IPIPE_EXCLUSIVE_FLAG	31	/* ipipe_catch_event() is the reason why. */
+
+#define IPIPE_HANDLE_MASK	(1 << IPIPE_HANDLE_FLAG)
+#define IPIPE_PASS_MASK		(1 << IPIPE_PASS_FLAG)
+#define IPIPE_ENABLE_MASK	(1 << IPIPE_ENABLE_FLAG)
+#define IPIPE_DYNAMIC_MASK	IPIPE_HANDLE_MASK
+#define IPIPE_EXCLUSIVE_MASK	(1 << IPIPE_EXCLUSIVE_FLAG)
+#define IPIPE_STICKY_MASK	(1 << IPIPE_STICKY_FLAG)
+#define IPIPE_SYSTEM_MASK	(1 << IPIPE_SYSTEM_FLAG)
+#define IPIPE_LOCK_MASK		(1 << IPIPE_LOCK_FLAG)
+#define IPIPE_SHARED_MASK	(1 << IPIPE_SHARED_FLAG)
+#define IPIPE_SYNC_MASK		(1 << IPIPE_SYNC_FLAG)
+
+#define IPIPE_DEFAULT_MASK	(IPIPE_HANDLE_MASK|IPIPE_PASS_MASK)
+#define IPIPE_STDROOT_MASK	(IPIPE_HANDLE_MASK|IPIPE_PASS_MASK|IPIPE_SYSTEM_MASK)
+
+/* Number of virtual IRQs */
+#define IPIPE_NR_VIRQS		BITS_PER_LONG
+/* First virtual IRQ # */
+#define IPIPE_VIRQ_BASE		(((IPIPE_NR_XIRQS + BITS_PER_LONG - 1) / BITS_PER_LONG) * BITS_PER_LONG)
+/* Total number of IRQ slots */
+#define IPIPE_NR_IRQS		(IPIPE_VIRQ_BASE + IPIPE_NR_VIRQS)
+/* Number of indirect words needed to map the whole IRQ space. */
+#define IPIPE_IRQ_IWORDS	((IPIPE_NR_IRQS + BITS_PER_LONG - 1) / BITS_PER_LONG)
+#define IPIPE_IRQ_IMASK		(BITS_PER_LONG - 1)
+#define IPIPE_IRQMASK_ANY	(~0L)
+#define IPIPE_IRQMASK_VIRT	(IPIPE_IRQMASK_ANY << (IPIPE_VIRQ_BASE / BITS_PER_LONG))
+
+#ifdef CONFIG_SMP
+
+#define IPIPE_NR_CPUS		NR_CPUS
+#define ipipe_declare_cpuid	int cpuid
+#define ipipe_load_cpuid()	do { \
+					(cpuid) = ipipe_processor_id();	\
+				} while(0)
+#define ipipe_lock_cpu(flags)	do { \
+					local_irq_save_hw(flags); \
+					(cpuid) = ipipe_processor_id(); \
+				} while(0)
+#define ipipe_unlock_cpu(flags)	local_irq_restore_hw(flags)
+#define ipipe_get_cpu(flags)	ipipe_lock_cpu(flags)
+#define ipipe_put_cpu(flags)	ipipe_unlock_cpu(flags)
+#define ipipe_current_domain	(ipipe_percpu_domain[ipipe_processor_id()])
+
+#else /* !CONFIG_SMP */
+
+#define IPIPE_NR_CPUS		1
+#define ipipe_declare_cpuid	const int cpuid = 0
+#define ipipe_load_cpuid()	do { } while(0)
+#define ipipe_lock_cpu(flags)	local_irq_save_hw(flags)
+#define ipipe_unlock_cpu(flags)	local_irq_restore_hw(flags)
+#define ipipe_get_cpu(flags)	do { flags = 0; } while(0)
+#define ipipe_put_cpu(flags)	do { } while(0)
+#define ipipe_current_domain	(ipipe_percpu_domain[0])
+
+#endif /* CONFIG_SMP */
+
+#define ipipe_virtual_irq_p(irq)	((irq) >= IPIPE_VIRQ_BASE && \
+					 (irq) < IPIPE_NR_IRQS)
+struct ipipe_domain {
+
+	struct list_head p_link;	/* Link in pipeline */
+
+	struct ipcpudata {
+		unsigned long status;
+		unsigned long irq_pending_hi;
+		unsigned long irq_pending_lo[IPIPE_IRQ_IWORDS];
+		unsigned long irq_hits[IPIPE_NR_IRQS];
+	} cpudata[IPIPE_NR_CPUS];
+
+	struct {
+		int (*acknowledge) (unsigned irq);
+		void (*handler) (unsigned irq);
+		unsigned long control;
+	} irqs[IPIPE_NR_IRQS];
+
+	int (*evhand[IPIPE_NR_EVENTS])(unsigned event,
+				       struct ipipe_domain *from,
+				       void *data); /* Event handlers. */
+	unsigned long evexcl;	/* Exclusive event bits. */
+
+#ifdef CONFIG_IPIPE_STATS
+	struct ipipe_stats { /* All in timebase units. */
+		unsigned long long last_stall_date;
+		unsigned long last_stall_eip;
+		unsigned long max_stall_time;
+		unsigned long max_stall_eip;
+		struct ipipe_irq_stats {
+			unsigned long long last_receipt_date;
+			unsigned long max_delivery_time;
+		} irq_stats[IPIPE_NR_IRQS];
+	} stats[IPIPE_NR_CPUS];
+#endif /* CONFIG_IPIPE_STATS */
+	unsigned long flags;
+	unsigned domid;
+	const char *name;
+	int priority;
+	void *pdd;
+};
+
+struct ipipe_domain_attr {
+
+	unsigned domid;		/* Domain identifier -- Magic value set by caller */
+	const char *name;	/* Domain name -- Warning: won't be dup'ed! */
+	int priority;		/* Priority in interrupt pipeline */
+	void (*entry) (void);	/* Domain entry point */
+	void *pdd;		/* Per-domain (opaque) data pointer */
+};
+
+/* The following macros must be used hw interrupts off. */
+
+#define __ipipe_set_irq_bit(ipd,cpuid,irq) \
+do { \
+	if (!test_bit(IPIPE_LOCK_FLAG,&(ipd)->irqs[irq].control)) { \
+		__set_bit(irq & IPIPE_IRQ_IMASK,&(ipd)->cpudata[cpuid].irq_pending_lo[irq >> IPIPE_IRQ_ISHIFT]); \
+		__set_bit(irq >> IPIPE_IRQ_ISHIFT,&(ipd)->cpudata[cpuid].irq_pending_hi); \
+	} \
+} while(0)
+
+#define __ipipe_clear_pend(ipd,cpuid,irq) \
+do { \
+	__clear_bit(irq & IPIPE_IRQ_IMASK,&(ipd)->cpudata[cpuid].irq_pending_lo[irq >> IPIPE_IRQ_ISHIFT]); \
+	if ((ipd)->cpudata[cpuid].irq_pending_lo[irq >> IPIPE_IRQ_ISHIFT] == 0) \
+		__clear_bit(irq >> IPIPE_IRQ_ISHIFT,&(ipd)->cpudata[cpuid].irq_pending_hi); \
+} while(0)
+
+#define __ipipe_lock_irq(ipd,cpuid,irq) \
+do { \
+	if (!test_and_set_bit(IPIPE_LOCK_FLAG,&(ipd)->irqs[irq].control)) \
+		__ipipe_clear_pend(ipd,cpuid,irq); \
+} while(0)
+
+#define __ipipe_unlock_irq(ipd,irq) \
+do { \
+	int __cpuid, __nr_cpus = num_online_cpus(); \
+	if (test_and_clear_bit(IPIPE_LOCK_FLAG,&(ipd)->irqs[irq].control)) \
+		for (__cpuid = 0; __cpuid < __nr_cpus; __cpuid++) \
+			if ((ipd)->cpudata[__cpuid].irq_hits[irq] > 0) { /* We need atomic ops next. */ \
+				set_bit(irq & IPIPE_IRQ_IMASK,&(ipd)->cpudata[__cpuid].irq_pending_lo[irq >> IPIPE_IRQ_ISHIFT]); \
+				set_bit(irq >> IPIPE_IRQ_ISHIFT,&(ipd)->cpudata[__cpuid].irq_pending_hi); \
+			} \
+} while(0)
+
+#define __ipipe_clear_irq(ipd,irq) \
+do { \
+	int __cpuid, __nr_cpus = num_online_cpus(); \
+	clear_bit(IPIPE_LOCK_FLAG,&(ipd)->irqs[irq].control); \
+	for (__cpuid = 0; __cpuid < __nr_cpus; __cpuid++) { \
+		(ipd)->cpudata[__cpuid].irq_hits[irq] = 0; \
+		__ipipe_clear_pend(ipd,__cpuid,irq); \
+	} \
+} while(0)
+
+#ifdef __RAW_SPIN_LOCK_UNLOCKED
+#define spin_lock_hw(x)			_raw_spin_lock(x)
+#define spin_trylock_hw(x)		_raw_spin_trylock(x)
+#define spin_unlock_hw(x)		_raw_spin_unlock(x)
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#define write_lock_hw(x)		_raw_write_lock(x)
+#define write_trylock_hw(x)		_raw_write_trylock(x)
+#define write_unlock_hw(x)		_raw_write_unlock(x)
+#define read_lock_hw(x)			_raw_read_lock(x)
+#define read_trylock_hw(x)		_raw_read_trylock(x)
+#define read_unlock_hw(x)		_raw_read_unlock(x)
+#else /* UP non-debug */
+#define write_lock_hw(lock)		do { (void)(lock); } while (0)
+#define write_trylock_hw(lock)		({ (void)(lock); 1; })
+#define write_unlock_hw(lock)		do { (void)(lock); } while (0)
+#define read_lock_hw(lock)		do { (void)(lock); } while (0)
+#define read_trylock_hw(lock)		({ (void)(lock); 1; })
+#define read_unlock_hw(lock)		do { (void)(lock); } while (0)
+#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */
+#else	/* !__RAW_SPIN_LOCK_UNLOCKED */
+#define spin_lock_hw(x)			_spin_lock(x)
+#define spin_unlock_hw(x)		_spin_unlock(x)
+#define spin_trylock_hw(x)		_spin_trylock(x)
+#define write_lock_hw(x)		_write_lock(x)
+#define write_unlock_hw(x)		_write_unlock(x)
+#define write_trylock_hw(x)		_write_trylock(x)
+#define read_lock_hw(x)			_read_lock(x)
+#define read_unlock_hw(x)		_read_unlock(x)
+#endif	/* __RAW_SPIN_LOCK_UNLOCKED */
+
+typedef spinlock_t			ipipe_spinlock_t;
+typedef rwlock_t			ipipe_rwlock_t;
+#define IPIPE_SPIN_LOCK_UNLOCKED	SPIN_LOCK_UNLOCKED
+#define IPIPE_RW_LOCK_UNLOCKED		RW_LOCK_UNLOCKED
+
+#define spin_lock_irqsave_hw(x,flags)		\
+do {						\
+	local_irq_save_hw(flags);		\
+	spin_lock_hw(x);			\
+} while (0)
+
+#define spin_unlock_irqrestore_hw(x,flags)	\
+do {						\
+	spin_unlock_hw(x);			\
+	local_irq_restore_hw(flags);		\
+} while (0)
+
+#define spin_lock_irq_hw(x)			\
+do {						\
+	local_irq_disable_hw();			\
+	spin_lock_hw(x);			\
+} while (0)
+
+#define spin_unlock_irq_hw(x)			\
+do {						\
+	spin_unlock_hw(x);			\
+	local_irq_enable_hw();			\
+} while (0)
+
+#define read_lock_irqsave_hw(lock, flags)	\
+do {						\
+	local_irq_save_hw(flags);		\
+	read_lock_hw(lock);			\
+} while (0)
+
+#define read_unlock_irqrestore_hw(lock, flags)	\
+do {						\
+	read_unlock_hw(lock);			\
+	local_irq_restore_hw(flags);		\
+} while (0)
+
+#define write_lock_irqsave_hw(lock, flags)	\
+do {						\
+	local_irq_save_hw(flags);		\
+	write_lock_hw(lock);			\
+} while (0)
+
+#define write_unlock_irqrestore_hw(lock, flags)	\
+do {						\
+	write_unlock_hw(lock);			\
+	local_irq_restore_hw(flags);		\
+} while (0)
+
+extern struct ipipe_domain *ipipe_percpu_domain[], *ipipe_root_domain;
+
+extern unsigned __ipipe_printk_virq;
+
+extern unsigned long __ipipe_virtual_irq_map;
+
+extern struct list_head __ipipe_pipeline;
+
+extern ipipe_spinlock_t __ipipe_pipelock;
+
+extern int __ipipe_event_monitors[];
+
+/* Private interface */
+
+void ipipe_init(void);
+
+#ifdef CONFIG_PROC_FS
+void ipipe_init_proc(void);
+
+#ifdef CONFIG_IPIPE_TRACE
+void __ipipe_init_trace_proc(void);
+#else /* !CONFIG_IPIPE_TRACE */
+#define __ipipe_init_trace_proc()   do { } while(0)
+#endif /* CONFIG_IPIPE_TRACE */
+
+#else	/* !CONFIG_PROC_FS */
+#define ipipe_init_proc()	do { } while(0)
+#endif	/* CONFIG_PROC_FS */
+
+void __ipipe_init_stage(struct ipipe_domain *ipd);
+
+void __ipipe_cleanup_domain(struct ipipe_domain *ipd);
+
+void __ipipe_add_domain_proc(struct ipipe_domain *ipd);
+
+void __ipipe_remove_domain_proc(struct ipipe_domain *ipd);
+
+void __ipipe_flush_printk(unsigned irq);
+
+void __ipipe_stall_root(void);
+
+void __ipipe_unstall_root(void);
+
+unsigned long __ipipe_test_root(void);
+
+unsigned long __ipipe_test_and_stall_root(void);
+
+void fastcall __ipipe_restore_root(unsigned long flags);
+
+int fastcall __ipipe_schedule_irq(unsigned irq, struct list_head *head);
+
+int fastcall __ipipe_dispatch_event(unsigned event, void *data);
+
+#define __ipipe_pipeline_head_p(ipd) (&(ipd)->p_link == __ipipe_pipeline.next)
+
+#ifdef CONFIG_SMP
+
+cpumask_t __ipipe_set_irq_affinity(unsigned irq,
+				   cpumask_t cpumask);
+
+int fastcall __ipipe_send_ipi(unsigned ipi,
+			      cpumask_t cpumask);
+
+#endif /* CONFIG_SMP */
+
+/* Called with hw interrupts off. */
+static inline void __ipipe_switch_to(struct ipipe_domain *out,
+				     struct ipipe_domain *in, int cpuid)
+{
+	void ipipe_suspend_domain(void);
+
+	/*
+	 * "in" is guaranteed to be closer than "out" from the head of the
+	 * pipeline (and obviously different).
+	 */
+
+	ipipe_percpu_domain[cpuid] = in;
+
+	ipipe_suspend_domain();	/* Sync stage and propagate interrupts. */
+	ipipe_load_cpuid();	/* Processor might have changed. */
+
+	if (ipipe_percpu_domain[cpuid] == in)
+		/*
+		 * Otherwise, something has changed the current domain under
+		 * our feet recycling the register set; do not override.
+		 */
+		ipipe_percpu_domain[cpuid] = out;
+}
+
+static inline void ipipe_sigwake_notify(struct task_struct *p)
+{
+	if (__ipipe_event_monitors[IPIPE_EVENT_SIGWAKE] > 0)
+		__ipipe_dispatch_event(IPIPE_EVENT_SIGWAKE,p);
+}
+
+static inline void ipipe_setsched_notify(struct task_struct *p)
+{
+	if (__ipipe_event_monitors[IPIPE_EVENT_SETSCHED] > 0)
+		__ipipe_dispatch_event(IPIPE_EVENT_SETSCHED,p);
+}
+
+static inline void ipipe_exit_notify(struct task_struct *p)
+{
+	if (__ipipe_event_monitors[IPIPE_EVENT_EXIT] > 0)
+		__ipipe_dispatch_event(IPIPE_EVENT_EXIT,p);
+}
+
+static inline int ipipe_trap_notify(int ex, struct pt_regs *regs)
+{
+	return __ipipe_event_monitors[ex] ? __ipipe_dispatch_event(ex,regs) : 0;
+}
+
+#ifdef CONFIG_IPIPE_STATS
+
+#define ipipe_mark_domain_stall(ipd, cpuid)			\
+do {								\
+	__label__ here;						\
+	struct ipipe_stats *ips;				\
+here:								\
+	ips = (ipd)->stats + cpuid;				\
+	if (ips->last_stall_date == 0) {			\
+		ipipe_read_tsc(ips->last_stall_date);		\
+		ips->last_stall_eip = (unsigned long)&&here;	\
+	}							\
+} while(0)
+
+static inline void ipipe_mark_domain_unstall(struct ipipe_domain *ipd, int cpuid)
+{ /* Called w/ hw interrupts off. */
+	struct ipipe_stats *ips = ipd->stats + cpuid;
+	unsigned long long t, d;
+
+	if (ips->last_stall_date != 0) {
+		ipipe_read_tsc(t);
+		d = t - ips->last_stall_date;
+		if (d > ips->max_stall_time) {
+			ips->max_stall_time = d;
+			ips->max_stall_eip = ips->last_stall_eip;
+		}
+		ips->last_stall_date = 0;
+	}
+}
+
+static inline void ipipe_mark_irq_receipt(struct ipipe_domain *ipd, unsigned irq, int cpuid)
+{
+	struct ipipe_stats *ips = ipd->stats + cpuid;
+
+	if (ips->irq_stats[irq].last_receipt_date == 0) {
+		ipipe_read_tsc(ips->irq_stats[irq].last_receipt_date);
+	}
+}
+
+static inline void ipipe_mark_irq_delivery(struct ipipe_domain *ipd, unsigned irq, int cpuid)
+{ /* Called w/ hw interrupts off. */
+	struct ipipe_stats *ips = ipd->stats + cpuid;
+	unsigned long long t, d;
+
+	if (ips->irq_stats[irq].last_receipt_date != 0) {
+		ipipe_read_tsc(t);
+		d = t - ips->irq_stats[irq].last_receipt_date;
+		ips->irq_stats[irq].last_receipt_date = 0;
+		if (d > ips->irq_stats[irq].max_delivery_time)
+			ips->irq_stats[irq].max_delivery_time = d;
+	}
+}
+
+static inline void ipipe_reset_stats (void)
+{
+	int cpu, irq;
+	for_each_online_cpu(cpu) {
+		ipipe_root_domain->stats[cpu].last_stall_date = 0LL;
+		for (irq = 0; irq < IPIPE_NR_IRQS; irq++)
+			ipipe_root_domain->stats[cpu].irq_stats[irq].last_receipt_date = 0LL;
+	}
+}
+
+#else /* !CONFIG_IPIPE_STATS */
+
+#define ipipe_mark_domain_stall(ipd,cpuid)	do { } while(0)
+#define ipipe_mark_domain_unstall(ipd,cpuid)	do { } while(0)
+#define ipipe_mark_irq_receipt(ipd,irq,cpuid)	do { } while(0)
+#define ipipe_mark_irq_delivery(ipd,irq,cpuid)	do { } while(0)
+#define ipipe_reset_stats()			do { } while(0)
+
+#endif /* CONFIG_IPIPE_STATS */
+
+/* Public interface */
+
+int ipipe_register_domain(struct ipipe_domain *ipd,
+			  struct ipipe_domain_attr *attr);
+
+int ipipe_unregister_domain(struct ipipe_domain *ipd);
+
+void ipipe_suspend_domain(void);
+
+int ipipe_virtualize_irq(struct ipipe_domain *ipd,
+			 unsigned irq,
+			 void (*handler) (unsigned irq),
+			 int (*acknowledge) (unsigned irq),
+			 unsigned modemask);
+
+static inline int ipipe_share_irq(unsigned irq,
+				  int (*acknowledge) (unsigned irq))
+{
+	return ipipe_virtualize_irq(ipipe_current_domain,
+				    irq,
+				    IPIPE_SAME_HANDLER,
+				    acknowledge,
+				    IPIPE_SHARED_MASK | IPIPE_HANDLE_MASK |
+				    IPIPE_PASS_MASK);
+}
+
+int ipipe_control_irq(unsigned irq,
+		      unsigned clrmask,
+		      unsigned setmask);
+
+unsigned ipipe_alloc_virq(void);
+
+int ipipe_free_virq(unsigned virq);
+
+int fastcall ipipe_trigger_irq(unsigned irq);
+
+static inline int ipipe_propagate_irq(unsigned irq)
+{
+
+	return __ipipe_schedule_irq(irq, ipipe_current_domain->p_link.next);
+}
+
+static inline int ipipe_schedule_irq(unsigned irq)
+{
+
+	return __ipipe_schedule_irq(irq, &ipipe_current_domain->p_link);
+}
+
+static inline void ipipe_stall_pipeline_from(struct ipipe_domain *ipd)
+{
+	ipipe_declare_cpuid;
+#ifdef CONFIG_SMP
+	unsigned long flags;
+
+	ipipe_lock_cpu(flags); /* Care for migration. */
+
+	__set_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_mark_domain_stall(ipd, cpuid);
+
+	if (!__ipipe_pipeline_head_p(ipd))
+		ipipe_unlock_cpu(flags);
+#else	/* CONFIG_SMP */
+	set_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_mark_domain_stall(ipd, cpuid);
+
+	if (__ipipe_pipeline_head_p(ipd))
+		local_irq_disable_hw();
+#endif	/* CONFIG_SMP */
+}
+
+static inline unsigned long ipipe_test_pipeline_from(struct ipipe_domain *ipd)
+{
+	unsigned long flags, s;
+	ipipe_declare_cpuid;
+
+	ipipe_get_cpu(flags);
+	s = test_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_put_cpu(flags);
+
+	return s;
+}
+
+static inline unsigned long ipipe_test_and_stall_pipeline_from(struct
+							       ipipe_domain
+							       *ipd)
+{
+	ipipe_declare_cpuid;
+	unsigned long s;
+#ifdef CONFIG_SMP
+	unsigned long flags;
+
+	ipipe_lock_cpu(flags); /* Care for migration. */
+
+	s = __test_and_set_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_mark_domain_stall(ipd, cpuid);
+
+	if (!__ipipe_pipeline_head_p(ipd))
+		ipipe_unlock_cpu(flags);
+#else	/* CONFIG_SMP */
+	s = test_and_set_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_mark_domain_stall(ipd, cpuid);
+
+	if (__ipipe_pipeline_head_p(ipd))
+		local_irq_disable_hw();
+#endif	/* CONFIG_SMP */
+
+	return s;
+}
+
+void fastcall ipipe_unstall_pipeline_from(struct ipipe_domain *ipd);
+
+static inline unsigned long ipipe_test_and_unstall_pipeline_from(struct
+								 ipipe_domain
+								 *ipd)
+{
+	unsigned long flags, s;
+	ipipe_declare_cpuid;
+
+	ipipe_get_cpu(flags);
+	s = test_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+	ipipe_unstall_pipeline_from(ipd);
+	ipipe_put_cpu(flags);
+
+	return s;
+}
+
+static inline void ipipe_unstall_pipeline(void)
+{
+	ipipe_unstall_pipeline_from(ipipe_current_domain);
+}
+
+static inline unsigned long ipipe_test_and_unstall_pipeline(void)
+{
+	return ipipe_test_and_unstall_pipeline_from(ipipe_current_domain);
+}
+
+static inline unsigned long ipipe_test_pipeline(void)
+{
+	return ipipe_test_pipeline_from(ipipe_current_domain);
+}
+
+static inline unsigned long ipipe_test_and_stall_pipeline(void)
+{
+	return ipipe_test_and_stall_pipeline_from(ipipe_current_domain);
+}
+
+static inline void ipipe_restore_pipeline_from(struct ipipe_domain *ipd,
+					       unsigned long flags)
+{
+	if (flags)
+		ipipe_stall_pipeline_from(ipd);
+	else
+		ipipe_unstall_pipeline_from(ipd);
+}
+
+static inline void ipipe_stall_pipeline(void)
+{
+	ipipe_stall_pipeline_from(ipipe_current_domain);
+}
+
+static inline void ipipe_restore_pipeline(unsigned long flags)
+{
+	ipipe_restore_pipeline_from(ipipe_current_domain, flags);
+}
+
+static inline void ipipe_restore_pipeline_nosync(struct ipipe_domain *ipd,
+						 unsigned long flags, int cpuid)
+{
+	/*
+	 * If cpuid is current, then it must be held on entry
+	 * (ipipe_get_cpu/local_irq_save_hw/local_irq_disable_hw).
+	 */
+
+	if (flags) {
+		__set_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+		ipipe_mark_domain_stall(ipd,cpuid);
+	}
+	else {
+		__clear_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+		ipipe_mark_domain_unstall(ipd,cpuid);
+	}
+}
+
+void ipipe_init_attr(struct ipipe_domain_attr *attr);
+
+int ipipe_get_sysinfo(struct ipipe_sysinfo *sysinfo);
+
+int ipipe_tune_timer(unsigned long ns,
+		     int flags);
+
+unsigned long ipipe_critical_enter(void (*syncfn) (void));
+
+void ipipe_critical_exit(unsigned long flags);
+
+static inline void ipipe_set_printk_sync(struct ipipe_domain *ipd)
+{
+	set_bit(IPIPE_SPRINTK_FLAG, &ipd->flags);
+}
+
+static inline void ipipe_set_printk_async(struct ipipe_domain *ipd)
+{
+	clear_bit(IPIPE_SPRINTK_FLAG, &ipd->flags);
+}
+
+int ipipe_catch_event(struct ipipe_domain *ipd,
+		      unsigned event,
+		      int (*handler)(unsigned event,
+				     struct ipipe_domain *ipd,
+				     void *data));
+
+cpumask_t ipipe_set_irq_affinity(unsigned irq,
+				 cpumask_t cpumask);
+
+int fastcall ipipe_send_ipi(unsigned ipi,
+			    cpumask_t cpumask);
+
+int ipipe_setscheduler_root(struct task_struct *p,
+			    int policy,
+			    int prio);
+
+int ipipe_reenter_root(struct task_struct *prev,
+		       int policy,
+		       int prio);
+
+int ipipe_alloc_ptdkey(void);
+
+int ipipe_free_ptdkey(int key);
+
+int fastcall ipipe_set_ptd(int key,
+			   void *value);
+
+void fastcall *ipipe_get_ptd(int key);
+
+#define local_irq_enable_hw_cond()		local_irq_enable_hw()
+#define local_irq_disable_hw_cond()		local_irq_disable_hw()
+#define local_irq_save_hw_cond(flags)		local_irq_save_hw(flags)
+#define local_irq_restore_hw_cond(flags)	local_irq_restore_hw(flags)
+#define spin_lock_irqsave_hw_cond(lock,flags)	spin_lock_irqsave_hw(lock,flags)
+#define spin_unlock_irqrestore_hw_cond(lock,flags) spin_unlock_irqrestore_hw(lock,flags)
+
+#define ipipe_irq_lock(irq)						\
+	do {								\
+		ipipe_declare_cpuid;					\
+		ipipe_load_cpuid();					\
+		__ipipe_lock_irq(ipipe_percpu_domain[cpuid], cpuid, irq);\
+	} while(0)
+
+#define ipipe_irq_unlock(irq)						\
+	do {								\
+		ipipe_declare_cpuid;					\
+		ipipe_load_cpuid();					\
+		__ipipe_unlock_irq(ipipe_percpu_domain[cpuid], irq);	\
+	} while(0)
+
+#else	/* !CONFIG_IPIPE */
+
+#define ipipe_init()				do { } while(0)
+#define ipipe_suspend_domain()			do { } while(0)
+#define ipipe_sigwake_notify(p)			do { } while(0)
+#define ipipe_setsched_notify(p)		do { } while(0)
+#define ipipe_exit_notify(p)			do { } while(0)
+#define ipipe_init_proc()			do { } while(0)
+#define ipipe_reset_stats()			do { } while(0)
+#define ipipe_trap_notify(t,r)			0
+
+#define spin_lock_hw(lock)			spin_lock(lock)
+#define spin_unlock_hw(lock)			spin_unlock(lock)
+#define spin_lock_irq_hw(lock)			spin_lock_irq(lock)
+#define spin_unlock_irq_hw(lock)		spin_unlock_irq(lock)
+#define spin_lock_irqsave_hw(lock,flags)	spin_lock_irqsave(lock, flags)
+#define spin_unlock_irqrestore_hw(lock,flags)	spin_unlock_irqrestore(lock, flags)
+
+#define local_irq_enable_hw_cond()		do { } while(0)
+#define local_irq_disable_hw_cond()		do { } while(0)
+#define local_irq_save_hw_cond(flags)		do { (void)(flags); } while(0)
+#define local_irq_restore_hw_cond(flags)	do { } while(0)
+#define spin_lock_irqsave_hw_cond(lock,flags)	do { (void)(flags); spin_lock(lock); } while(0)
+#define spin_unlock_irqrestore_hw_cond(lock,flags)	spin_unlock(lock)
+
+#define ipipe_irq_lock(irq)			do { } while(0)
+#define ipipe_irq_unlock(irq)			do { } while(0)
+
+#endif	/* CONFIG_IPIPE */
+
+#endif	/* !__LINUX_IPIPE_H */
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-core.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-core.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-core.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-core.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,915 @@
+#ifndef _LTT_FACILITY_CORE_H_
+#define _LTT_FACILITY_CORE_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-core.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+struct lttng_timestamp {
+	unsigned int seconds;
+	unsigned int nanoseconds;
+	unsigned int cycle_count;
+} LTT_ALIGN;
+
+static inline size_t lttng_get_alignment_struct_timestamp(
+		struct lttng_timestamp *obj)
+{
+	size_t align=0, localign;
+	localign = sizeof(unsigned int);
+	align = max(align, localign);
+
+	localign = sizeof(unsigned int);
+	align = max(align, localign);
+
+	localign = sizeof(unsigned int);
+	align = max(align, localign);
+
+	return align;
+}
+
+static inline void lttng_write_struct_timestamp(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		struct lttng_timestamp *obj)
+{
+	size_t size;
+	size_t align;
+
+	align = lttng_get_alignment_struct_timestamp(obj);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains only fixed size fields : use compiler sizeof() */
+
+	size = sizeof(struct lttng_timestamp);
+	*len += size;
+}
+
+/* Event facility_load structures */
+static inline void lttng_write_string_core_facility_load_name(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+
+/* Event facility_load logging function */
+static inline void trace_core_facility_load(
+		const char * lttng_param_name,
+		unsigned int lttng_param_checksum,
+		unsigned int lttng_param_id,
+		unsigned int lttng_param_int_size,
+		unsigned int lttng_param_long_size,
+		unsigned int lttng_param_pointer_size,
+		unsigned int lttng_param_size_t_size,
+		unsigned int lttng_param_has_alignment)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_name;
+	lttng_write_string_core_facility_load_name(buffer, to_base, to, from, len, lttng_param_name);
+
+	*from = &lttng_param_checksum;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_id;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_int_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_long_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_pointer_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_size_t_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_has_alignment;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_core_F1C514F,
+						event_core_facility_load);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_core_F1C514F, event_core_facility_load,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_name;
+		lttng_write_string_core_facility_load_name(buffer, to_base, to, from, len, lttng_param_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_checksum;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_id;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_int_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_long_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_pointer_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_size_t_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_has_alignment;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+
+
+/* Event facility_unload structures */
+
+/* Event facility_unload logging function */
+static inline void trace_core_facility_unload(
+		unsigned int lttng_param_id)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_id;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_core_F1C514F,
+						event_core_facility_unload);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_core_F1C514F, event_core_facility_unload,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_id;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+
+
+/* Event time_heartbeat structures */
+
+/* Event time_heartbeat logging function */
+static inline void trace_core_time_heartbeat(
+unsigned int tracefile_index,
+		struct lttng_timestamp * lttng_param_timestamp)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_timestamp;
+	lttng_write_struct_timestamp(buffer, to_base, to, from, len, lttng_param_timestamp);
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = tracefile_index;
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_core_F1C514F, event_core_time_heartbeat,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_timestamp;
+		lttng_write_struct_timestamp(buffer, to_base, to, from, len, lttng_param_timestamp);
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+
+
+/* Event state_dump_facility_load structures */
+static inline void lttng_write_string_core_state_dump_facility_load_name(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+
+/* Event state_dump_facility_load logging function */
+static inline void trace_core_state_dump_facility_load(
+		struct ltt_trace_struct *dest_trace,
+		const char * lttng_param_name,
+		unsigned int lttng_param_checksum,
+		unsigned int lttng_param_id,
+		unsigned int lttng_param_int_size,
+		unsigned int lttng_param_long_size,
+		unsigned int lttng_param_pointer_size,
+		unsigned int lttng_param_size_t_size,
+		unsigned int lttng_param_has_alignment)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_name;
+	lttng_write_string_core_state_dump_facility_load_name(buffer, to_base, to, from, len, lttng_param_name);
+
+	*from = &lttng_param_checksum;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_id;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_int_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_long_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_pointer_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_size_t_size;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_has_alignment;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_core_F1C514F,
+						event_core_state_dump_facility_load);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		if(dest_trace != trace) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_core_F1C514F, event_core_state_dump_facility_load,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_name;
+		lttng_write_string_core_state_dump_facility_load_name(buffer, to_base, to, from, len, lttng_param_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_checksum;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_id;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_int_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_long_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_pointer_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_size_t_size;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_has_alignment;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_CORE))
+
+
+#endif //_LTT_FACILITY_CORE_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-fs.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-fs.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-fs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-fs.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,1493 @@
+#ifndef _LTT_FACILITY_FS_H_
+#define _LTT_FACILITY_FS_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-fs.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event buf_wait_start structures */
+
+/* Event buf_wait_start logging function */
+static inline void trace_fs_buf_wait_start(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_buf_wait_start);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_buf_wait_start,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event buf_wait_end structures */
+
+/* Event buf_wait_end logging function */
+static inline void trace_fs_buf_wait_end(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_buf_wait_end);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_buf_wait_end,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event exec structures */
+typedef struct lttng_sequence_fs_exec_filename lttng_sequence_fs_exec_filename;
+struct lttng_sequence_fs_exec_filename {
+	unsigned int len;
+	const unsigned char *array;
+};
+
+static inline size_t lttng_get_alignment_sequence_fs_exec_filename(
+		lttng_sequence_fs_exec_filename *obj)
+{
+	size_t align=0, localign;
+	localign = sizeof(unsigned int);
+	align = max(align, localign);
+
+	localign = sizeof(unsigned char);
+	align = max(align, localign);
+
+	return align;
+}
+
+static inline void lttng_write_sequence_fs_exec_filename(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		lttng_sequence_fs_exec_filename *obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = lttng_get_alignment_sequence_fs_exec_filename(obj);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	/* Copy members */
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, &obj->len, *len);
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(unsigned char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned char);
+
+	*len = obj->len * (*len);
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj->array, *len);
+	*to += *len;
+	*len = 0;
+
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C sequence */
+	*from = obj+1;
+}
+
+
+/* Event exec logging function */
+static inline void trace_fs_exec(
+		lttng_sequence_fs_exec_filename * lttng_param_filename)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_filename;
+	lttng_write_sequence_fs_exec_filename(buffer, to_base, to, from, len, lttng_param_filename);
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_exec);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_exec,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_filename;
+		lttng_write_sequence_fs_exec_filename(buffer, to_base, to, from, len, lttng_param_filename);
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event open structures */
+typedef struct lttng_sequence_fs_open_filename lttng_sequence_fs_open_filename;
+struct lttng_sequence_fs_open_filename {
+	unsigned int len;
+	const unsigned char *array;
+};
+
+static inline size_t lttng_get_alignment_sequence_fs_open_filename(
+		lttng_sequence_fs_open_filename *obj)
+{
+	size_t align=0, localign;
+	localign = sizeof(unsigned int);
+	align = max(align, localign);
+
+	localign = sizeof(unsigned char);
+	align = max(align, localign);
+
+	return align;
+}
+
+static inline void lttng_write_sequence_fs_open_filename(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		lttng_sequence_fs_open_filename *obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = lttng_get_alignment_sequence_fs_open_filename(obj);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	/* Copy members */
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, &obj->len, *len);
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(unsigned char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned char);
+
+	*len = obj->len * (*len);
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj->array, *len);
+	*to += *len;
+	*len = 0;
+
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C sequence */
+	*from = obj+1;
+}
+
+
+/* Event open logging function */
+static inline void trace_fs_open(
+		lttng_sequence_fs_open_filename * lttng_param_filename,
+		unsigned int lttng_param_fd)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_filename;
+	lttng_write_sequence_fs_open_filename(buffer, to_base, to, from, len, lttng_param_filename);
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_open);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_open,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_filename;
+		lttng_write_sequence_fs_open_filename(buffer, to_base, to, from, len, lttng_param_filename);
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event close structures */
+
+/* Event close logging function */
+static inline void trace_fs_close(
+		unsigned int lttng_param_fd)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_close);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_close,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event read structures */
+
+/* Event read logging function */
+static inline void trace_fs_read(
+		unsigned int lttng_param_fd,
+		size_t lttng_param_count)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_count;
+	align = sizeof(size_t);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(size_t);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_read);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_read,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_count;
+		align = sizeof(size_t);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(size_t);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event write structures */
+
+/* Event write logging function */
+static inline void trace_fs_write(
+		unsigned int lttng_param_fd,
+		size_t lttng_param_count)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_count;
+	align = sizeof(size_t);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(size_t);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_write);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_write,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_count;
+		align = sizeof(size_t);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(size_t);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event seek structures */
+
+/* Event seek logging function */
+static inline void trace_fs_seek(
+		unsigned int lttng_param_fd,
+		off_t lttng_param_offset,
+		unsigned int lttng_param_origin)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_offset;
+	align = sizeof(off_t);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(off_t);
+
+	*from = &lttng_param_origin;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_seek);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_seek,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_offset;
+		align = sizeof(off_t);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(off_t);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_origin;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event ioctl structures */
+
+/* Event ioctl logging function */
+static inline void trace_fs_ioctl(
+		unsigned int lttng_param_fd,
+		unsigned int lttng_param_cmd,
+		unsigned int lttng_param_arg)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_cmd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_arg;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_ioctl);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_ioctl,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_cmd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_arg;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event select structures */
+
+/* Event select logging function */
+static inline void trace_fs_select(
+		unsigned int lttng_param_fd,
+		unsigned long lttng_param_timeout)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_timeout;
+	align = sizeof(unsigned long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned long);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_select);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_select,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_timeout;
+		align = sizeof(unsigned long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+/* Event poll structures */
+
+/* Event poll logging function */
+static inline void trace_fs_poll(
+		unsigned int lttng_param_fd)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_fs_40A645EC,
+						event_fs_poll);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_fs_40A645EC, event_fs_poll,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_FS))
+
+
+#endif //_LTT_FACILITY_FS_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-core.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-core.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-core.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-core.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _LTT_FACILITY_ID_CORE_H_
+#define _LTT_FACILITY_ID_CORE_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_core_F1C514F;
+extern ltt_facility_t ltt_facility_core;
+
+
+/****  event index  ****/
+
+enum core_event {
+	event_core_facility_load,
+	event_core_facility_unload,
+	event_core_time_heartbeat,
+	event_core_state_dump_facility_load,
+	facility_core_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_CORE_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-fs.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-fs.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-fs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-fs.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _LTT_FACILITY_ID_FS_H_
+#define _LTT_FACILITY_ID_FS_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_fs_40A645EC;
+extern ltt_facility_t ltt_facility_fs;
+
+
+/****  event index  ****/
+
+enum fs_event {
+	event_fs_buf_wait_start,
+	event_fs_buf_wait_end,
+	event_fs_exec,
+	event_fs_open,
+	event_fs_close,
+	event_fs_read,
+	event_fs_write,
+	event_fs_seek,
+	event_fs_ioctl,
+	event_fs_select,
+	event_fs_poll,
+	facility_fs_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_FS_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-ipc.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-ipc.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-ipc.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _LTT_FACILITY_ID_IPC_H_
+#define _LTT_FACILITY_ID_IPC_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_ipc_14120A9A;
+extern ltt_facility_t ltt_facility_ipc;
+
+
+/****  event index  ****/
+
+enum ipc_event {
+	event_ipc_call,
+	event_ipc_msg_create,
+	event_ipc_sem_create,
+	event_ipc_shm_create,
+	facility_ipc_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_IPC_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-kernel.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-kernel.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-kernel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-kernel.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,30 @@
+#ifndef _LTT_FACILITY_ID_KERNEL_H_
+#define _LTT_FACILITY_ID_KERNEL_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_kernel_E78275BF;
+extern ltt_facility_t ltt_facility_kernel;
+
+
+/****  event index  ****/
+
+enum kernel_event {
+	event_kernel_syscall_entry,
+	event_kernel_syscall_exit,
+	event_kernel_trap_entry,
+	event_kernel_trap_exit,
+	event_kernel_soft_irq_entry,
+	event_kernel_soft_irq_exit,
+	event_kernel_tasklet_entry,
+	event_kernel_tasklet_exit,
+	event_kernel_irq_entry,
+	event_kernel_irq_exit,
+	facility_kernel_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_KERNEL_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-memory.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-memory.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-memory.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef _LTT_FACILITY_ID_MEMORY_H_
+#define _LTT_FACILITY_ID_MEMORY_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_memory_D63D41C7;
+extern ltt_facility_t ltt_facility_memory;
+
+
+/****  event index  ****/
+
+enum memory_event {
+	event_memory_page_alloc,
+	event_memory_page_free,
+	event_memory_swap_in,
+	event_memory_swap_out,
+	event_memory_page_wait_start,
+	event_memory_page_wait_end,
+	facility_memory_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_MEMORY_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-network.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-network.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-network.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-network.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef _LTT_FACILITY_ID_NETWORK_H_
+#define _LTT_FACILITY_ID_NETWORK_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_network_8B91EC6C;
+extern ltt_facility_t ltt_facility_network;
+
+
+/****  event index  ****/
+
+enum network_event {
+	event_network_packet_in,
+	event_network_packet_out,
+	facility_network_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_NETWORK_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-process.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-process.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-process.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-process.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef _LTT_FACILITY_ID_PROCESS_H_
+#define _LTT_FACILITY_ID_PROCESS_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_process_F7697017;
+extern ltt_facility_t ltt_facility_process;
+
+
+/****  event index  ****/
+
+enum process_event {
+	event_process_fork,
+	event_process_kernel_thread,
+	event_process_exit,
+	event_process_wait,
+	event_process_free,
+	event_process_kill,
+	event_process_signal,
+	event_process_wakeup,
+	event_process_schedchange,
+	facility_process_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_PROCESS_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-socket.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-socket.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-socket.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _LTT_FACILITY_ID_SOCKET_H_
+#define _LTT_FACILITY_ID_SOCKET_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_socket_5E76ED18;
+extern ltt_facility_t ltt_facility_socket;
+
+
+/****  event index  ****/
+
+enum socket_event {
+	event_socket_call,
+	event_socket_create,
+	event_socket_sendmsg,
+	event_socket_recvmsg,
+	facility_socket_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_SOCKET_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-statedump.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-statedump.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-statedump.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-statedump.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _LTT_FACILITY_ID_STATEDUMP_H_
+#define _LTT_FACILITY_ID_STATEDUMP_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_statedump_31582B7A;
+extern ltt_facility_t ltt_facility_statedump;
+
+
+/****  event index  ****/
+
+enum statedump_event {
+	event_statedump_enumerate_file_descriptors,
+	event_statedump_enumerate_vm_maps,
+	event_statedump_enumerate_modules,
+	event_statedump_enumerate_interrupts,
+	event_statedump_statedump_end,
+	facility_statedump_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_STATEDUMP_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-id-timer.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-timer.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-id-timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-id-timer.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _LTT_FACILITY_ID_TIMER_H_
+#define _LTT_FACILITY_ID_TIMER_H_
+
+#ifdef CONFIG_LTT
+#include <linux/ltt-facilities.h>
+
+/****  facility handle  ****/
+
+extern ltt_facility_t ltt_facility_timer_5EACEACA;
+extern ltt_facility_t ltt_facility_timer;
+
+
+/****  event index  ****/
+
+enum timer_event {
+	event_timer_expired,
+	event_timer_softirq,
+	event_timer_set_itimer,
+	facility_timer_num_events
+};
+
+#endif //CONFIG_LTT
+#endif //_LTT_FACILITY_ID_TIMER_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-ipc.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-ipc.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-ipc.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,530 @@
+#ifndef _LTT_FACILITY_IPC_H_
+#define _LTT_FACILITY_IPC_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-ipc.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event call structures */
+
+/* Event call logging function */
+static inline void trace_ipc_call(
+		unsigned int lttng_param_call_number,
+		int lttng_param_first)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_call_number;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_first;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_ipc_14120A9A,
+						event_ipc_call);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_ipc_14120A9A, event_ipc_call,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_call_number;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_first;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+
+
+/* Event msg_create structures */
+
+/* Event msg_create logging function */
+static inline void trace_ipc_msg_create(
+		long lttng_param_id,
+		int lttng_param_flags)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_id;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	*from = &lttng_param_flags;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_ipc_14120A9A,
+						event_ipc_msg_create);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_ipc_14120A9A, event_ipc_msg_create,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_id;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_flags;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+
+
+/* Event sem_create structures */
+
+/* Event sem_create logging function */
+static inline void trace_ipc_sem_create(
+		long lttng_param_id,
+		int lttng_param_flags)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_id;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	*from = &lttng_param_flags;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_ipc_14120A9A,
+						event_ipc_sem_create);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_ipc_14120A9A, event_ipc_sem_create,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_id;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_flags;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+
+
+/* Event shm_create structures */
+
+/* Event shm_create logging function */
+static inline void trace_ipc_shm_create(
+		long lttng_param_id,
+		int lttng_param_flags)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_id;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	*from = &lttng_param_flags;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_ipc_14120A9A,
+						event_ipc_shm_create);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_ipc_14120A9A, event_ipc_shm_create,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_id;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_flags;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_IPC))
+
+
+#endif //_LTT_FACILITY_IPC_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-kernel.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-kernel.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-kernel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-kernel.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,1134 @@
+#ifndef _LTT_FACILITY_KERNEL_H_
+#define _LTT_FACILITY_KERNEL_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-kernel.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+enum lttng_tasklet_priority {
+	LTTNG_LOW = 0,
+	LTTNG_HIGH = 1,
+};
+
+enum lttng_irq_mode {
+	LTTNG_user = 0,
+	LTTNG_kernel = 1,
+};
+
+/* Event syscall_entry structures */
+
+/* Event syscall_entry logging function */
+static inline void trace_kernel_syscall_entry(
+		unsigned int lttng_param_syscall_id,
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_syscall_id;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_syscall_entry);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_syscall_entry,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_syscall_id;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event syscall_exit structures */
+
+/* Event syscall_exit logging function */
+static inline void trace_kernel_syscall_exit(
+		void)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_syscall_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_syscall_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event trap_entry structures */
+
+/* Event trap_entry logging function */
+static inline void trace_kernel_trap_entry(
+		long lttng_param_trap_id,
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_trap_id;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_trap_entry);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_trap_entry,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_trap_id;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event trap_exit structures */
+
+/* Event trap_exit logging function */
+static inline void trace_kernel_trap_exit(
+		void)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_trap_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_trap_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event soft_irq_entry structures */
+
+/* Event soft_irq_entry logging function */
+static inline void trace_kernel_soft_irq_entry(
+		const void * lttng_param_softirq_id)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_softirq_id;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_soft_irq_entry);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_soft_irq_entry,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_softirq_id;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event soft_irq_exit structures */
+
+/* Event soft_irq_exit logging function */
+static inline void trace_kernel_soft_irq_exit(
+		const void * lttng_param_softirq_id)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_softirq_id;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_soft_irq_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_soft_irq_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_softirq_id;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event tasklet_entry structures */
+
+/* Event tasklet_entry logging function */
+static inline void trace_kernel_tasklet_entry(
+		enum lttng_tasklet_priority lttng_param_priority,
+		const void * lttng_param_address,
+		unsigned long lttng_param_data)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_priority;
+	align = sizeof(enum lttng_tasklet_priority);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_tasklet_priority);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_data;
+	align = sizeof(unsigned long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned long);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_tasklet_entry);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_tasklet_entry,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_priority;
+		align = sizeof(enum lttng_tasklet_priority);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_tasklet_priority);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_data;
+		align = sizeof(unsigned long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event tasklet_exit structures */
+
+/* Event tasklet_exit logging function */
+static inline void trace_kernel_tasklet_exit(
+		enum lttng_tasklet_priority lttng_param_priority,
+		const void * lttng_param_address,
+		unsigned long lttng_param_data)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_priority;
+	align = sizeof(enum lttng_tasklet_priority);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_tasklet_priority);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_data;
+	align = sizeof(unsigned long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned long);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_tasklet_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_tasklet_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_priority;
+		align = sizeof(enum lttng_tasklet_priority);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_tasklet_priority);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_data;
+		align = sizeof(unsigned long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event irq_entry structures */
+
+/* Event irq_entry logging function */
+static inline void trace_kernel_irq_entry(
+		unsigned int lttng_param_irq_id,
+		enum lttng_irq_mode lttng_param_mode)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_irq_id;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_mode;
+	align = sizeof(enum lttng_irq_mode);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_irq_mode);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_irq_entry);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_irq_entry,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_irq_id;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_mode;
+		align = sizeof(enum lttng_irq_mode);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_irq_mode);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+/* Event irq_exit structures */
+
+/* Event irq_exit logging function */
+static inline void trace_kernel_irq_exit(
+		void)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_kernel_E78275BF,
+						event_kernel_irq_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_kernel_E78275BF, event_kernel_irq_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_KERNEL))
+
+
+#endif //_LTT_FACILITY_KERNEL_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-memory.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-memory.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-memory.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,670 @@
+#ifndef _LTT_FACILITY_MEMORY_H_
+#define _LTT_FACILITY_MEMORY_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-memory.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event page_alloc structures */
+
+/* Event page_alloc logging function */
+static inline void trace_memory_page_alloc(
+		unsigned int lttng_param_order,
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_order;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_page_alloc);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_page_alloc,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_order;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+/* Event page_free structures */
+
+/* Event page_free logging function */
+static inline void trace_memory_page_free(
+		unsigned int lttng_param_order,
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_order;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_page_free);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_page_free,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_order;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+/* Event swap_in structures */
+
+/* Event swap_in logging function */
+static inline void trace_memory_swap_in(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_swap_in);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_swap_in,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+/* Event swap_out structures */
+
+/* Event swap_out logging function */
+static inline void trace_memory_swap_out(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_swap_out);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_swap_out,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+/* Event page_wait_start structures */
+
+/* Event page_wait_start logging function */
+static inline void trace_memory_page_wait_start(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_page_wait_start);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_page_wait_start,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+/* Event page_wait_end structures */
+
+/* Event page_wait_end logging function */
+static inline void trace_memory_page_wait_end(
+		const void * lttng_param_address)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_address;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_memory_D63D41C7,
+						event_memory_page_wait_end);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_memory_D63D41C7, event_memory_page_wait_end,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_address;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_MEMORY))
+
+
+#endif //_LTT_FACILITY_MEMORY_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-network.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-network.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-network.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-network.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,270 @@
+#ifndef _LTT_FACILITY_NETWORK_H_
+#define _LTT_FACILITY_NETWORK_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-network.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event packet_in structures */
+
+/* Event packet_in logging function */
+static inline void trace_network_packet_in(
+		const void * lttng_param_skbuff,
+		unsigned int lttng_param_protocol)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_NETWORK))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_skbuff;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_protocol;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_network_8B91EC6C,
+						event_network_packet_in);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_network_8B91EC6C, event_network_packet_in,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_skbuff;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_protocol;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_NETWORK))
+
+
+/* Event packet_out structures */
+
+/* Event packet_out logging function */
+static inline void trace_network_packet_out(
+		const void * lttng_param_skbuff,
+		unsigned int lttng_param_protocol)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_NETWORK))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_skbuff;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_protocol;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_network_8B91EC6C,
+						event_network_packet_out);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_network_8B91EC6C, event_network_packet_out,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_skbuff;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_protocol;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_NETWORK))
+
+
+#endif //_LTT_FACILITY_NETWORK_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-process.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-process.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-process.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-process.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,1214 @@
+#ifndef _LTT_FACILITY_PROCESS_H_
+#define _LTT_FACILITY_PROCESS_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-process.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+enum lttng_signal_name {
+	LTTNG_SIGHUP = 0,
+	LTTNG_SIGINT = 1,
+	LTTNG_SIGQUIT = 2,
+	LTTNG_SIGILL = 3,
+	LTTNG_SIGTRAP = 4,
+	LTTNG_SIGABRT = 5,
+	LTTNG_SIGBUS = 6,
+	LTTNG_SIGFPE = 7,
+	LTTNG_SIGKILL = 8,
+	LTTNG_SIGUSR1 = 9,
+	LTTNG_SIGSEGV = 10,
+	LTTNG_SIGUSR2 = 11,
+	LTTNG_SIGPIPE = 12,
+	LTTNG_SIGALRM = 13,
+	LTTNG_SIGTERM = 14,
+	LTTNG_SIGSTKFLT = 15,
+	LTTNG_SIGCHLD = 16,
+	LTTNG_SIGCONT = 17,
+	LTTNG_SIGSTOP = 18,
+	LTTNG_SIGTSTP = 19,
+	LTTNG_SIGTTIN = 20,
+	LTTNG_SIGTTOU = 21,
+	LTTNG_SIGURG = 22,
+	LTTNG_SIGXCPU = 23,
+	LTTNG_SIGXFSZ = 24,
+	LTTNG_SIGVTALRM = 25,
+	LTTNG_SIGPROF = 26,
+	LTTNG_SIGWINCH = 27,
+	LTTNG_SIGIO = 28,
+	LTTNG_SIGPWR = 29,
+	LTTNG_SIGSYS = 30,
+};
+
+/* Event fork structures */
+
+/* Event fork logging function */
+static inline void trace_process_fork(
+		unsigned int lttng_param_parent_pid,
+		unsigned int lttng_param_child_pid)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_parent_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_child_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_fork);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_fork,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_parent_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_child_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event kernel_thread structures */
+
+/* Event kernel_thread logging function */
+static inline void trace_process_kernel_thread(
+		unsigned int lttng_param_pid,
+		const void * lttng_param_function)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_function;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_kernel_thread);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_kernel_thread,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_function;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event exit structures */
+
+/* Event exit logging function */
+static inline void trace_process_exit(
+		unsigned int lttng_param_pid)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_exit);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_exit,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event wait structures */
+
+/* Event wait logging function */
+static inline void trace_process_wait(
+		unsigned int lttng_param_parent_pid,
+		unsigned int lttng_param_child_pid)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_parent_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_child_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_wait);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_wait,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_parent_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_child_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event free structures */
+
+/* Event free logging function */
+static inline void trace_process_free(
+		unsigned int lttng_param_pid)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_free);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_free,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event kill structures */
+
+/* Event kill logging function */
+static inline void trace_process_kill(
+		unsigned int lttng_param_pid,
+		unsigned int lttng_param_target_pid,
+		enum lttng_signal_name lttng_param_signal)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_target_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_signal;
+	align = sizeof(enum lttng_signal_name);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_signal_name);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_kill);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_kill,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_target_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_signal;
+		align = sizeof(enum lttng_signal_name);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_signal_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event signal structures */
+
+/* Event signal logging function */
+static inline void trace_process_signal(
+		unsigned int lttng_param_pid,
+		enum lttng_signal_name lttng_param_signal)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_signal;
+	align = sizeof(enum lttng_signal_name);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_signal_name);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_signal);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_signal,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_signal;
+		align = sizeof(enum lttng_signal_name);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_signal_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event wakeup structures */
+
+/* Event wakeup logging function */
+static inline void trace_process_wakeup(
+		unsigned int lttng_param_pid,
+		int lttng_param_state)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_state;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_wakeup);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_wakeup,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_state;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+/* Event schedchange structures */
+
+/* Event schedchange logging function */
+static inline void trace_process_schedchange(
+		unsigned int lttng_param_out,
+		unsigned int lttng_param_in,
+		int lttng_param_out_state)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_out;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_in;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_out_state;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_process_F7697017,
+						event_process_schedchange);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_process_F7697017, event_process_schedchange,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_out;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_in;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_out_state;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_PROCESS))
+
+
+#endif //_LTT_FACILITY_PROCESS_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-socket.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-socket.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-socket.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,800 @@
+#ifndef _LTT_FACILITY_SOCKET_H_
+#define _LTT_FACILITY_SOCKET_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-socket.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event call structures */
+
+/* Event call logging function */
+static inline void trace_socket_call(
+		int lttng_param_call_number,
+		unsigned long lttng_param_first_argument)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_call_number;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_first_argument;
+	align = sizeof(unsigned long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned long);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_socket_5E76ED18,
+						event_socket_call);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_socket_5E76ED18, event_socket_call,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_call_number;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_first_argument;
+		align = sizeof(unsigned long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+
+
+/* Event create structures */
+
+/* Event create logging function */
+static inline void trace_socket_create(
+		const void * lttng_param_socket,
+		int lttng_param_family,
+		int lttng_param_type,
+		int lttng_param_protocol,
+		int lttng_param_fd)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_socket;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_family;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_type;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_protocol;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_fd;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_socket_5E76ED18,
+						event_socket_create);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_socket_5E76ED18, event_socket_create,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_socket;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_family;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_type;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_protocol;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_fd;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+
+
+/* Event sendmsg structures */
+
+/* Event sendmsg logging function */
+static inline void trace_socket_sendmsg(
+		const void * lttng_param_socket,
+		int lttng_param_family,
+		int lttng_param_type,
+		int lttng_param_protocol,
+		size_t lttng_param_size)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_socket;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_family;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_type;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_protocol;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_size;
+	align = sizeof(size_t);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(size_t);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_socket_5E76ED18,
+						event_socket_sendmsg);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_socket_5E76ED18, event_socket_sendmsg,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_socket;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_family;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_type;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_protocol;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_size;
+		align = sizeof(size_t);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(size_t);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+
+
+/* Event recvmsg structures */
+
+/* Event recvmsg logging function */
+static inline void trace_socket_recvmsg(
+		const void * lttng_param_socket,
+		int lttng_param_family,
+		int lttng_param_type,
+		int lttng_param_protocol,
+		size_t lttng_param_size)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_socket;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_family;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_type;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_protocol;
+	align = sizeof(int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(int);
+
+	*from = &lttng_param_size;
+	align = sizeof(size_t);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(size_t);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_socket_5E76ED18,
+						event_socket_recvmsg);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_socket_5E76ED18, event_socket_recvmsg,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_socket;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_family;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_type;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_protocol;
+		align = sizeof(int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_size;
+		align = sizeof(size_t);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(size_t);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_SOCKET))
+
+
+#endif //_LTT_FACILITY_SOCKET_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-statedump.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-statedump.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-statedump.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-statedump.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,886 @@
+#ifndef _LTT_FACILITY_STATEDUMP_H_
+#define _LTT_FACILITY_STATEDUMP_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-statedump.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+/* Event enumerate_file_descriptors structures */
+static inline void lttng_write_string_statedump_enumerate_file_descriptors_name(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+
+/* Event enumerate_file_descriptors logging function */
+static inline void trace_statedump_enumerate_file_descriptors(
+		const char * lttng_param_name,
+		unsigned int lttng_param_PID,
+		unsigned int lttng_param_fd)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_name;
+	lttng_write_string_statedump_enumerate_file_descriptors_name(buffer, to_base, to, from, len, lttng_param_name);
+
+	*from = &lttng_param_PID;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_fd;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_statedump_31582B7A,
+						event_statedump_enumerate_file_descriptors);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_statedump_31582B7A, event_statedump_enumerate_file_descriptors,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_name;
+		lttng_write_string_statedump_enumerate_file_descriptors_name(buffer, to_base, to, from, len, lttng_param_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_PID;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_fd;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+
+
+/* Event enumerate_vm_maps structures */
+
+/* Event enumerate_vm_maps logging function */
+static inline void trace_statedump_enumerate_vm_maps(
+		const void * lttng_param_start,
+		const void * lttng_param_end,
+		unsigned int lttng_param_flags,
+		long lttng_param_pgoff,
+		long lttng_param_inode)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_start;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_end;
+	align = sizeof(const void *);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(const void *);
+
+	*from = &lttng_param_flags;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_pgoff;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	*from = &lttng_param_inode;
+	align = sizeof(long);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(long);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_statedump_31582B7A,
+						event_statedump_enumerate_vm_maps);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_statedump_31582B7A, event_statedump_enumerate_vm_maps,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_start;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_end;
+		align = sizeof(const void *);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(const void *);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_flags;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_pgoff;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_inode;
+		align = sizeof(long);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(long);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+
+
+/* Event enumerate_modules structures */
+static inline void lttng_write_string_statedump_enumerate_modules_name(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+
+/* Event enumerate_modules logging function */
+static inline void trace_statedump_enumerate_modules(
+		const char * lttng_param_name,
+		unsigned int lttng_param_state,
+		unsigned int lttng_param_ref)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_name;
+	lttng_write_string_statedump_enumerate_modules_name(buffer, to_base, to, from, len, lttng_param_name);
+
+	*from = &lttng_param_state;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_ref;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_statedump_31582B7A,
+						event_statedump_enumerate_modules);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_statedump_31582B7A, event_statedump_enumerate_modules,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_name;
+		lttng_write_string_statedump_enumerate_modules_name(buffer, to_base, to, from, len, lttng_param_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_state;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_ref;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+
+
+/* Event enumerate_interrupts structures */
+static inline void lttng_write_string_statedump_enumerate_interrupts_name(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+static inline void lttng_write_string_statedump_enumerate_interrupts_action(
+		void *buffer,
+		size_t *to_base,
+		size_t *to,
+		const void **from,
+		size_t *len,
+		const char * obj)
+{
+	size_t size;
+	size_t align;
+
+	/* Flush pending memcpy */
+	if(*len != 0) {
+		if(buffer != NULL)
+			memcpy(buffer+*to_base+*to, *from, *len);
+	}
+	*to += *len;
+	*len = 0;
+
+	align = sizeof(char);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	/* Contains variable sized fields : must explode the structure */
+
+	size = strlen(obj) + 1; /* Include final NULL char. */
+	if(buffer != NULL)
+		memcpy(buffer+*to_base+*to, obj, size);
+	*to += size;
+
+	/* Realign the *to_base on arch size, set *to to 0 */
+	*to += ltt_align(*to, sizeof(void *));
+	*to_base = *to_base+*to;
+	*to = 0;
+
+	/* Put source *from just after the C string */
+	*from += size;
+}
+
+
+/* Event enumerate_interrupts logging function */
+static inline void trace_statedump_enumerate_interrupts(
+		const char * lttng_param_name,
+		const char * lttng_param_action,
+		unsigned int lttng_param_num)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = lttng_param_name;
+	lttng_write_string_statedump_enumerate_interrupts_name(buffer, to_base, to, from, len, lttng_param_name);
+
+	*from = lttng_param_action;
+	lttng_write_string_statedump_enumerate_interrupts_action(buffer, to_base, to, from, len, lttng_param_action);
+
+	*from = &lttng_param_num;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_statedump_31582B7A,
+						event_statedump_enumerate_interrupts);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_statedump_31582B7A, event_statedump_enumerate_interrupts,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = lttng_param_name;
+		lttng_write_string_statedump_enumerate_interrupts_name(buffer, to_base, to, from, len, lttng_param_name);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = lttng_param_action;
+		lttng_write_string_statedump_enumerate_interrupts_action(buffer, to_base, to, from, len, lttng_param_action);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_num;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+
+
+/* Event statedump_end structures */
+
+/* Event statedump_end logging function */
+static inline void trace_statedump_statedump_end(
+		void)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_statedump_31582B7A,
+						event_statedump_statedump_end);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_statedump_31582B7A, event_statedump_statedump_end,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_STATEDUMP))
+
+
+#endif //_LTT_FACILITY_STATEDUMP_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt/ltt-facility-timer.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-timer.h
--- linux-2.6.14.5/include/linux/ltt/ltt-facility-timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt/ltt-facility-timer.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,404 @@
+#ifndef _LTT_FACILITY_TIMER_H_
+#define _LTT_FACILITY_TIMER_H_
+
+#include <linux/types.h>
+#include <linux/ltt/ltt-facility-id-timer.h>
+#include <linux/ltt-core.h>
+
+/* Named types */
+
+enum lttng_itimer_kind {
+	LTTNG_ITIMER_REAL = 0,
+	LTTNG_ITIMER_VIRTUAL = 1,
+	LTTNG_ITIMER_PROF = 2,
+};
+
+/* Event expired structures */
+
+/* Event expired logging function */
+static inline void trace_timer_expired(
+		unsigned int lttng_param_pid)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_pid;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_timer_5EACEACA,
+						event_timer_expired);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_timer_5EACEACA, event_timer_expired,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_pid;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+
+
+/* Event softirq structures */
+
+/* Event softirq logging function */
+static inline void trace_timer_softirq(
+		void)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_timer_5EACEACA,
+						event_timer_softirq);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_timer_5EACEACA, event_timer_softirq,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+
+
+/* Event set_itimer structures */
+
+/* Event set_itimer logging function */
+static inline void trace_timer_set_itimer(
+		enum lttng_itimer_kind lttng_param_which,
+		unsigned int lttng_param_interval_seconds,
+		unsigned int lttng_param_interval_microseconds,
+		unsigned int lttng_param_value_seconds,
+		unsigned int lttng_param_value_microseconds)
+#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+{
+}
+#else
+{
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	struct rchan_buf *relayfs_buf;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	size_t align;
+	const void *real_from;
+	const void **from = &real_from;
+	cycles_t tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+
+	if(ltt_traces.num_active_traces == 0) return;
+
+	/* For each field, calculate the field size. */
+	/* size = *to_base + *to + *len */
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	*from = &lttng_param_which;
+	align = sizeof(enum lttng_itimer_kind);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(enum lttng_itimer_kind);
+
+	*from = &lttng_param_interval_seconds;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_interval_microseconds;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_value_seconds;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	*from = &lttng_param_value_microseconds;
+	align = sizeof(unsigned int);
+
+	if(*len == 0) {
+		*to += ltt_align(*to, align); /* align output */
+	} else {
+		*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+	}
+
+	*len += sizeof(unsigned int);
+
+	reserve_size = *to_base + *to + *len;
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	index = ltt_get_index_from_facility(ltt_facility_timer_5EACEACA,
+						event_timer_set_itimer);
+
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if(!trace->active) continue;
+
+		channel = ltt_get_channel_from_index(trace, index);
+		relayfs_buf = channel->rchan->buf[smp_processor_id()];
+
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, relayfs_buf,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if(!buffer) continue; /* buffer full */
+
+		*to_base = *to = *len = 0;
+
+		ltt_write_event_header(trace, channel, buffer,
+			ltt_facility_timer_5EACEACA, event_timer_set_itimer,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+		*from = &lttng_param_which;
+		align = sizeof(enum lttng_itimer_kind);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(enum lttng_itimer_kind);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_interval_seconds;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_interval_microseconds;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_value_seconds;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		*from = &lttng_param_value_microseconds;
+		align = sizeof(unsigned int);
+
+		if(*len == 0) {
+			*to += ltt_align(*to, align); /* align output */
+		} else {
+			*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+		}
+
+		*len += sizeof(unsigned int);
+
+		/* Flush pending memcpy */
+		if(*len != 0) {
+			memcpy(buffer+*to_base+*to, *from, *len);
+			*to += *len;
+			*len = 0;
+		}
+
+		ltt_commit_slot(relayfs_buf, buffer, slot_size);
+
+	}
+
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+}
+#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_TIMER))
+
+
+#endif //_LTT_FACILITY_TIMER_H_
diff -uNrp linux-2.6.14.5/include/linux/ltt-core.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-core.h
--- linux-2.6.14.5/include/linux/ltt-core.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-core.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,905 @@
+/*
+ * linux/include/linux/ltt-core.h
+ *
+ * Copyright (C) 1999-2004 Karim Yaghmour (karim@opersys.com)
+ * Copyright (C) 2005 Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * This contains the core definitions for the Linux Trace Toolkit.
+ */
+
+#ifndef _LTT_CORE_H
+#define _LTT_CORE_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/cache.h>
+#include <linux/kernel.h>
+#include <linux/timex.h>
+//#include <linux/ltt-relayfs.h>
+
+#include <linux/relayfs_fs.h>
+#include <linux/ltt-time.h>
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-core.h>
+#include <linux/ltt/ltt-facility-id-process.h>
+
+#include <asm/semaphore.h>
+
+//#include <asm/timer.h>
+
+#ifdef CONFIG_LTT
+
+//FIXME : WARN if get_cycles() (tsc) is missing on arch.
+
+extern void ltt_init(void);
+
+/* All modifications of ltt_traces must be done by ltt-core.c, while holding the
+ * semaphore. Only reading of this information can be done elsewhere, with the
+ * RCU mechanism : the preemption must be disabled while reading the list. */
+struct ltt_traces {
+	/* Traces list */
+	struct list_head										head;
+	/* Number of active traces */
+	unsigned int 												num_active_traces;
+} ____cacheline_aligned;
+
+extern struct ltt_traces ltt_traces;
+
+/* Keep track of traps nesting inside LTT */
+extern volatile unsigned int ltt_nesting[];
+
+struct ltt_trace_struct;
+
+/* LTTng lockless logging buffer info */
+struct ltt_channel_buf_struct {
+	/* Use the relayfs void *start as buffer start pointer */
+	volatile int offset;		/* Current offset in the buffer */
+	volatile int consumed;	/* Current offset in the buffer */
+	atomic_t *reserve_count;				/* Final per sub-buffer reserve count */
+	atomic_t *commit_count;					/* Commit count per sub-buffer */
+	
+	atomic_t events_lost;
+	atomic_t corrupted_subbuffers;
+	struct timeval	current_subbuffer_start_time;
+} ____cacheline_aligned;
+
+struct ltt_channel_struct {
+	char										channel_name[PATH_MAX];
+	struct rchan						*rchan;
+	struct ltt_trace_struct	*trace;
+	struct ltt_channel_buf_struct buf[NR_CPUS];
+
+	/*
+	 * subbuf_header_len - called on buffer-switch to a new sub-buffer
+	 * @buf: the channel buffer containing the new sub-buffer
+	 *
+	 * returns the client header size at the beginning of the buffer.
+	 */
+	unsigned int (*subbuf_header_len) (struct rchan_buf *buf);
+	
+	/*
+	 * buffer_begin - called on buffer-switch to a new sub-buffer
+	 * @buf: the channel buffer containing the new sub-buffer
+	 */
+	void (*buffer_begin) (struct rchan_buf *buf,
+			cycles_t tsc, unsigned int subbuf_idx);
+
+	/*
+	 * buffer_end - called on buffer-switch to a new sub-buffer
+	 * @buf: the channel buffer containing the previous sub-buffer
+	 */
+	void (*buffer_end) (struct rchan_buf *buf,
+			cycles_t tsc, unsigned int offset, unsigned int subbuf_idx);
+};
+
+
+enum trace_mode { LTT_TRACE_NORMAL, LTT_TRACE_FLIGHT };
+
+/* Per-trace information - each trace/flight recorder represented by one */
+struct ltt_trace_struct {
+	struct list_head	list;
+	int								active;
+	char							trace_name[NAME_MAX];
+	int								paused;
+	enum trace_mode		mode;
+	u32								has_tsc;
+	u64								start_freq;
+	u64								start_tsc;
+	unsigned long long start_monotonic;
+	//struct timespec		start_time;
+	struct timeval		start_time;
+//	int								heartbeat_active;
+	// removed .int								using_tsc;
+	//u32								n_buffers;
+	//u32								buf_size;
+	//u32								buffers_produced[NR_CPUS];
+	struct {
+		struct dentry			*trace_root;
+		struct dentry			*control_root;
+	} dentry;
+
+	struct {
+		struct ltt_channel_struct	*facilities;
+		struct ltt_channel_struct	*interrupts;
+		struct ltt_channel_struct	*processes;
+		struct ltt_channel_struct	*modules;
+		struct ltt_channel_struct	*cpu;
+	} channel;
+
+	struct rchan_callbacks callbacks;
+	struct file_operations fops;
+
+} ____cacheline_aligned;
+
+
+/* Hardcoded event headers */
+
+
+/* event header for a trace with active heartbeat : 32 bits timestamps */
+
+/* headers are 8 bytes aligned : that means members are aligned on memory
+ * boundaries *if* structure starts on a 8 bytes boundary. In order to insure
+ * such alignment, a dynamic per trace alignment value must be set.
+ *
+ * Remeber that the C compiler does align each member on the boundary equivalent
+ * to their own size.
+ *
+ * As relayfs subbuffers are aligned on pages, we are sure that they are 8 bytes
+ * aligned, so the buffer header and trace header are aligned.
+ *
+ * Event headers are aligned depending on the trace alignment option. */
+
+struct ltt_event_header_hb {
+	uint32_t			timestamp;
+	unsigned char	facility_id;
+	unsigned char event_id;
+	uint16_t			event_size;
+} __attribute((packed));
+
+struct ltt_event_header_nohb {
+	uint64_t			timestamp;
+	unsigned char	facility_id;
+	unsigned char event_id;
+	uint16_t			event_size;
+} __attribute((packed));
+
+
+
+struct ltt_trace_header {
+	uint32_t				magic_number;
+	uint32_t				arch_type;
+	uint32_t				arch_variant;
+	uint32_t				float_word_order;	 /* Only useful for user space traces */
+	uint8_t 				arch_size;
+	//uint32_t				system_type;
+	uint8_t					major_version;
+	uint8_t					minor_version;
+	uint8_t					flight_recorder;
+	uint8_t					has_heartbeat;
+	uint8_t					has_alignment;	/* Event header alignment */
+	uint8_t					has_tsc;
+	uint64_t				start_freq;
+	uint64_t				start_tsc;
+	uint64_t				start_monotonic;
+	//struct timespec	start_time;
+	//struct timeval	start_time; // non portable
+  uint64_t        start_time_sec;
+  uint64_t        start_time_usec;
+} __attribute((packed));
+
+
+/* We use asm/timex.h : cpu_khz variable in here : we might have to deal
+ * specifically with CPU frequency scaling someday, so using an interpolation
+ * between the start and end of buffer values is not flexible enough. Using an
+ * immediate frequency value permits to calculate directly the times for parts
+ * of a buffer that would be before a frequency change. */
+
+struct ltt_block_start_header {
+	struct { 
+		//struct timeval					timestamp; // not portable
+		uint64_t								timestamp_sec;
+		uint64_t								timestamp_usec;
+		uint64_t								cycle_count;
+		uint64_t								freq; /* khz */
+	} begin;
+	struct { 
+		//struct timeval					timestamp;	// not portable
+		uint64_t								timestamp_sec;
+		uint64_t								timestamp_usec;
+		uint64_t								cycle_count;
+		uint64_t								freq; /* khz */
+	} end;
+	uint32_t								lost_size;	/* Size unused at the end of the buffer */
+	uint32_t								buf_size;		/* The size of this sub-buffer */
+	struct ltt_trace_header	trace;
+} __attribute((packed));
+
+
+
+/* Get the offset of the channel in the ltt_trace_struct */
+#define GET_CHANNEL_INDEX(chan)	\
+	(unsigned int)&((struct ltt_trace_struct*)NULL)->channel.chan
+
+/* ltt_get_index_from_facility
+ *
+ * Get channel index from facility and event id.
+ * 
+ * @fID : facility ID
+ * @eID : event number
+ *
+ * Get the channel index into which events must be written for the given
+ * facility and event number. We get this structure offset as soon as possible
+ * and remember it so we pass through this logic only once per trace call (not
+ * for every trace).
+ */
+static inline unsigned int ltt_get_index_from_facility(ltt_facility_t fID,
+																												u8 eID)
+{
+
+	if(fID == ltt_facility_core) {
+		switch(eID) {
+			case event_core_facility_load:
+			case event_core_facility_unload:
+			case event_core_state_dump_facility_load:
+				return GET_CHANNEL_INDEX(facilities);
+			default:
+				return GET_CHANNEL_INDEX(cpu);
+		}
+	} else if(fID == ltt_facility_process) {
+		switch(eID) {
+			case event_process_fork:
+			case event_process_kernel_thread:
+			case event_process_exit:
+			case event_process_wait:
+			case event_process_free:
+				return GET_CHANNEL_INDEX(processes);
+			default:
+				return GET_CHANNEL_INDEX(cpu);
+		}
+	}
+	//TODO
+	// add modules events
+	// add interrupts register/unregister events.
+	
+	/* Default channel */
+	return GET_CHANNEL_INDEX(cpu);
+
+}
+
+static inline struct ltt_channel_struct *ltt_get_channel_from_index(
+		struct ltt_trace_struct *trace, unsigned int index)
+{
+	return *(struct ltt_channel_struct **)((void*)trace+index);
+}
+
+#ifdef CONFIG_LTT_ALIGNMENT
+
+/* Calculate the offset needed to align the type */
+static inline unsigned int ltt_align(size_t align_drift,
+																		 size_t size_of_type)
+{
+	size_t alignment = min(sizeof(void*), size_of_type);
+
+	return ((alignment - align_drift) & (alignment-1));
+}
+/* Default arch alignment */
+#define LTT_ALIGN
+
+#else
+static inline unsigned int ltt_align(size_t align_drift,
+																		 size_t size_of_type)
+{
+	return 0;
+}
+
+#define LTT_ALIGN __attribute__((packed))
+
+#endif //CONFIG_LTT_ALIGNMENT
+
+
+/*
+ * ltt_get_header_size
+ *
+ * Calculate alignment offset for arch size void*. This is the
+ * alignment offset of the event header.
+ *
+ * Important note :
+ * The event header must be a size multiple of the void* size. This is necessary
+ * to be able to calculate statically the alignment offset of the variable
+ * length data fields that follows. The total offset calculated here :
+ *
+ *	 Alignment of header struct on arch size
+ * + sizeof(header struct)
+ * + padding added to end of struct to align on arch size.
+ * */
+static inline unsigned char ltt_get_header_size(struct ltt_trace_struct *trace,
+																								void *address,
+																								size_t *before_hdr_pad,
+																								size_t *after_hdr_pad,
+																								size_t *header_size)
+{
+	unsigned int padding;
+	unsigned int header;
+	
+	if(trace->has_tsc) {
+#ifdef CONFIG_LTT_HEARTBEAT
+		header = sizeof(struct ltt_event_header_hb);
+#else
+		header = sizeof(struct ltt_event_header_nohb);
+#endif // CONFIG_LTT_HEARTBEAT
+	} else {
+		header = sizeof(struct ltt_event_header_hb);
+	}
+	/* Padding before the header. Calculated dynamically */
+	*before_hdr_pad = ltt_align((unsigned long)address, header);
+	padding = *before_hdr_pad;
+
+	/* Padding after header, considering header aligned on ltt_align.
+	 * Calculated statically if header size if known. */
+	*after_hdr_pad = ltt_align(header, sizeof(void*));
+	padding += *after_hdr_pad;
+
+	*header_size = header;
+
+	return header+padding;
+}
+
+
+
+#if 0
+static inline unsigned char ltt_get_event_header_data(
+		struct ltt_trace_struct *trace, struct ltt_channel_struct *channel,
+		void *ptr, unsigned char *offset, struct timeval *delta, 
+		u64 *tsc)
+{
+	unsigned char size;
+	
+	if(trace->has_tsc) {
+#ifdef CONFIG_LTT_HEARTBEAT
+		size = sizeof(struct ltt_event_header_hb);
+#else
+		size = sizeof(struct ltt_event_header_nohb);
+#endif // CONFIG_LTT_HEARTBEAT
+		*tsc = (u64)get_cycles();
+	} else {
+		size = sizeof(struct ltt_event_header_hb);
+		calc_time_delta(delta,
+							&channel->buf[smp_processor_id()].current_subbuffer_start_time);
+		*tsc = 0;
+	
+	}
+
+	*offset = 0;
+
+	return size;
+}
+#endif //0
+
+#if 0
+static inline unsigned char ltt_get_event_header_size(
+		struct ltt_trace_struct *trace, struct ltt_channel_struct *channel,
+		void *ptr, unsigned char *offset)
+{
+	unsigned char size; 
+
+	*offset =	(trace->alignment - ((unsigned int)ptr&(trace->alignment-1)))
+									& (trace->alignment-1);
+	
+	if(trace->heartbeat_active) 
+		size = sizeof(struct ltt_event_header_hb);
+	else
+		size = sizeof(struct ltt_event_header_nohb);
+
+	return size;
+}
+#endif //0
+
+/* ltt_write_event_header
+ *
+ * Writes the event header to the pointer.
+ *
+ * @channel : pointer to the channel structure
+ * @ptr : buffer pointer
+ * @fID : facility ID
+ * @eID : event ID
+ * @event_size : size of the event, excluding the event header.
+ * @offset : offset of the beginning of the header, for alignment.
+ * 					 Calculated by ltt_get_event_header_size.
+ * @tsc : time stamp counter.
+ */
+static inline void ltt_write_event_header(
+		struct ltt_trace_struct *trace, struct ltt_channel_struct *channel,
+		void *ptr, ltt_facility_t fID, uint32_t eID, size_t event_size,
+		size_t offset, cycles_t tsc)
+{
+#ifdef CONFIG_LTT_HEARTBEAT
+	struct ltt_event_header_hb *hb;
+#else
+	struct ltt_event_header_nohb *nohb;
+#endif //CONFIG_LTT_HEARTBEAT
+
+	event_size = min(event_size, 0xFFFFU);
+
+	if(trace->has_tsc) {
+#ifdef CONFIG_LTT_HEARTBEAT
+		hb = (struct ltt_event_header_hb *)(ptr+offset);
+		hb->timestamp = (u32)tsc;
+		hb->facility_id = fID;
+		hb->event_id = eID;
+		hb->event_size = (uint16_t)event_size;
+#else
+		nohb = (struct ltt_event_header_nohb *)(ptr+offset);
+		nohb->timestamp = (u64)tsc;
+		nohb->facility_id = fID;
+		nohb->event_id = eID;
+		nohb->event_size = (uint16_t)event_size;
+#endif //CONFIG_LTT_HEARTBEAT
+	} else {
+		/* Only support TSC CPU */
+		WARN_ON(1);
+	}
+}
+
+/* for flight recording. must be called after relay_commit.
+ * This function does not protect from corruption resulting from writing non
+ * sequentially in the buffer (and trying to read this buffer after a crash
+ * which occured at the wrong moment).
+ * That's why sequential writes are good!
+ *
+ * This function does nothing if trace is in normal mode. */
+#if 0
+static inline void ltt_write_commit_counter(struct rchan_buf *buf,
+		void *reserved)
+{
+	struct ltt_channel_struct *channel = 
+		(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_block_start_header *header =
+		(struct ltt_block_start_header*)buf->data;
+	unsigned offset, subbuf_idx;
+	
+	offset = reserved - buf->start;
+	subbuf_idx = offset / buf->chan->subbuf_size;
+
+	if(channel->trace->mode == LTT_TRACE_FLIGHT)
+		header->lost_size = buf->chan->subbuf_size - 
+													buf->commit[subbuf_idx];
+
+}
+#endif //0
+#endif //CONFIG_LTT
+
+
+/* Is kernel tracer enabled */
+#if defined(CONFIG_LTT_TRACER) || defined(CONFIG_LTT_TRACER_MODULE)
+
+//#define MAX_NR_TRACES 256 //FIXME : use dynamic allocation or a CONFIG option ?
+
+//typedef unsigned long ltt_facility_t;
+
+/* 3 control channels :
+ * ltt/control/facilities
+ * ltt/control/interrupts
+ * ltt/control/processes
+ *
+ * 1 cpu channel :
+ * ltt/cpu
+ */
+#define LTT_RELAYFS_ROOT						"ltt"
+#define LTT_CONTROL_ROOT						"control"
+#define LTT_FACILITIES_CHANNEL			"facilities"
+#define LTT_INTERRUPTS_CHANNEL			"interrupts"
+#define LTT_PROCESSES_CHANNEL				"processes"
+#define LTT_MODULES_CHANNEL					"modules"
+#define LTT_CPU_CHANNEL							"cpu"
+
+/* System types */
+#define LTT_SYS_TYPE_VANILLA_LINUX	1
+
+/* Architecture types */
+#define LTT_ARCH_TYPE_I386					1
+#define LTT_ARCH_TYPE_PPC						2
+#define LTT_ARCH_TYPE_SH						3
+#define LTT_ARCH_TYPE_S390					4
+#define LTT_ARCH_TYPE_MIPS					5
+#define LTT_ARCH_TYPE_ARM						6
+
+/* Standard definitions for variants */
+#define LTT_ARCH_VARIANT_NONE				0	 /* Main architecture implementation */
+
+/* Per-CPU channel information */
+//struct ltt_channel_data {
+//	int channel_handle;
+//	struct rchan_reader *reader;
+//	atomic_t waiting_for_cpu_async;
+//	u32 events_lost;
+//};
+
+
+/* Tracer properties */
+#define LTT_DEFAULT_SUBBUF_SIZE 1048576
+#define LTT_DEFAULT_N_SUBBUFS 2
+#if 0
+#define LTT_TRACER_MIN_BUF_SIZE				1000
+#define LTT_TRACER_MAX_BUF_SIZE			500000
+#define LTT_TRACER_MIN_BUFFERS						2
+#define LTT_TRACER_MAX_BUFFERS					256
+#endif //0
+#define LTT_TRACER_MAGIC_NUMBER		 0x00D6B7ED
+#define LTT_TRACER_VERSION_MAJOR		0
+#define LTT_TRACER_VERSION_MINOR		6
+
+
+/* Lockless LTTng */
+
+/* Buffer offset macros */
+
+#define BUFFER_OFFSET(offset, chan) (offset & (chan->alloc_size-1))
+#define SUBBUF_OFFSET(offset, chan) (offset & (chan->subbuf_size-1))
+#define SUBBUF_ALIGN(offset, chan) \
+	(((offset) + chan->subbuf_size) & (~(chan->subbuf_size-1)))
+#define SUBBUF_TRUNC(offset, chan) \
+	((offset) & (~(chan->subbuf_size-1)))
+#define SUBBUF_INDEX(offset, chan) \
+	(BUFFER_OFFSET(offset,chan)/chan->subbuf_size)
+
+
+/* ltt_reserve_slot
+ *
+ * Atomic slot reservation in a LTTng buffer. It will take care of
+ * sub-buffer switching.
+ *
+ * Parameters:
+ *
+ * @trace : the trace structure to log to.
+ * @buf : the buffer to reserve space into.
+ * @data_size : size of the variable length data to log.
+ * @slot_size : pointer to total size of the slot (out)
+ * @tsc : pointer to the tsc at the slot reservation (out)
+ * @before_hdr_pad : dynamic padding before the event header.
+ * @after_hdr_pad : dynamic padding after the event header.
+ *
+ * Return : NULL if not enough space, else returns the pointer
+ * 					to the beginning of the reserved slot. */
+static inline void *ltt_reserve_slot(
+															struct ltt_trace_struct *trace,
+															struct rchan_buf *buf,
+															unsigned int data_size,
+															unsigned int *slot_size,
+															cycles_t *tsc,
+															size_t *before_hdr_pad,
+															size_t *after_hdr_pad,
+															size_t *header_size)
+{
+	struct ltt_channel_struct *ltt_channel = 
+						(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_channel_buf_struct *ltt_buf = &ltt_channel->buf[buf->cpu];
+
+	int offset_begin, offset_end, offset_old;
+	//int has_switch;
+	int begin_switch, end_switch_current, end_switch_old;
+	int reserve_commit_diff = 0;
+	unsigned int size;
+	int consumed_old, consumed_new;
+	int commit_count, reserve_count;
+
+	do {
+		offset_old = ltt_buf->offset;
+		offset_begin = offset_old;
+		//has_switch = 0;
+		begin_switch = 0;
+		end_switch_current = 0;
+		end_switch_old = 0;
+		*tsc = get_cycles();
+
+		if(SUBBUF_OFFSET(offset_begin, buf->chan) == 0) {
+			begin_switch = 1; /* For offset_begin */
+		} else {
+			size = ltt_get_header_size(trace, buf->start + offset_begin,
+																 before_hdr_pad, after_hdr_pad, header_size)
+						 + data_size;
+
+			if((SUBBUF_OFFSET(offset_begin, buf->chan)+size)>buf->chan->subbuf_size) {
+				//has_switch = 1;
+				end_switch_old = 1;	/* For offset_old */
+				begin_switch = 1;	/* For offset_begin */
+			}
+		}
+
+		if(begin_switch) {
+			if(end_switch_old) {
+				offset_begin = SUBBUF_ALIGN(offset_begin, buf->chan);
+			}
+			offset_begin = offset_begin + ltt_channel->subbuf_header_len(buf);
+			/* Test new buffer integrity */
+			reserve_commit_diff =
+				atomic_read(&ltt_buf->reserve_count[SUBBUF_INDEX(offset_begin,
+																												 buf->chan)])
+				- atomic_read(&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin,
+																						 buf->chan)]);
+			if(reserve_commit_diff == 0) {
+				/* Next buffer not corrupted. */
+				if(!buf->chan->overwrite && 
+						(SUBBUF_TRUNC(offset_begin, buf->chan) 
+								- SUBBUF_TRUNC(ltt_buf->consumed, buf->chan))
+									>= ltt_channel->rchan->alloc_size) {
+					/* We do not overwrite non consumed buffers and we are full : event
+						 is lost. */
+					atomic_inc(&ltt_buf->events_lost);
+					if(likely(!atomic_read(&buf->full))) {
+						buf->chan->cb->buf_full(buf,
+																		SUBBUF_INDEX(offset_begin, buf->chan),
+							buf->start +
+								(SUBBUF_INDEX(offset_begin, buf->chan)
+									*buf->chan->subbuf_size));
+						atomic_set(&buf->full, 1);
+					}
+					return NULL;
+				} else {
+					/* next buffer not corrupted, we are either in overwrite mode or
+					 * the buffer is not full. It's safe to write in this new subbuffer.*/
+				}
+			} else {
+				/* Next subbuffer corrupted. Force pushing reader even in normal
+				 * mode. It's safe to write in this new subbuffer. */
+			}
+			size = ltt_get_header_size(trace, buf->start + offset_begin,
+					before_hdr_pad, after_hdr_pad, header_size) + data_size;
+			if((SUBBUF_OFFSET(offset_begin,buf->chan)+size)>buf->chan->subbuf_size) {
+				/* Event too big for subbuffers, report error, don't complete 
+				 * the sub-buffer switch. */
+				atomic_inc(&ltt_buf->events_lost);
+				return NULL;
+			} else {
+				/* We just made a successful buffer switch and the event fits in the
+				 * new subbuffer. Let's write. */
+			}
+		} else {
+			/* Event fits in the current buffer and we are not on a switch boundary.
+			 * It's safe to write */
+		}
+		offset_end = offset_begin + size;
+
+		if((SUBBUF_OFFSET(offset_end, buf->chan))	== 0) {
+			/* The offset_end will fall at the very beginning of the next subbuffer.
+			 */
+			end_switch_current = 1;	/* For offset_begin */
+		}
+
+	} while(cmpxchg(&ltt_buf->offset, offset_old, offset_end) != offset_old);
+
+
+	/* Push the reader if necessary */
+	do {
+		consumed_old = ltt_buf->consumed;
+		/* If buffer is in overwrite mode, push the reader consumed count if
+			 the write position has reached it and we are not at the first
+			 iteration (don't push the reader farther than the writer). 
+			 This operation can be done concurrently by many writers in the
+			 same buffer, the writer being at the fartest write position sub-buffer
+			 index in the buffer being the one which will win this loop. */
+		/* If the buffer is not in overwrite mode, pushing the reader only
+			 happen if a sub-buffer is corrupted */
+		if((SUBBUF_TRUNC(offset_end, buf->chan) 
+					- SUBBUF_TRUNC(consumed_old, buf->chan)) 
+							>= ltt_channel->rchan->alloc_size)
+			consumed_new = SUBBUF_ALIGN(consumed_old, buf->chan);
+		else {
+			consumed_new = consumed_old;
+			break;
+		}
+	} while(cmpxchg(&ltt_buf->consumed, consumed_old, consumed_new)
+						!= consumed_old);
+
+	if(consumed_old != consumed_new) {
+		/* Reader pushed : we are the winner of the push, we can therefore
+			 reequilibrate reserve and commit. Atomic increment of the commit
+			 count permits other writers to play around with this variable
+			 before us. We keep track of corrupted_subbuffers even in overwrite mode :
+			 we never want to write over a non completely committed sub-buffer : 
+			 possible causes : the buffer size is too low compared to the unordered
+			 data input, or there is a writer who died between the reserve and the
+			 commit. */
+		if(reserve_commit_diff) {
+			/* We have to alter the sub-buffer commit count : a sub-buffer is
+				 corrupted. We do not deliver it. */
+			atomic_add(reserve_commit_diff,
+								&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin, buf->chan)]);
+			atomic_inc(&ltt_buf->corrupted_subbuffers);
+		}
+	}
+
+
+	if(end_switch_old) {
+		/* old subbuffer */
+		/* Concurrency safe because we are the last and only thread to alter this
+			 sub-buffer. As long as it is not delivered and read, no other thread can
+			 alter the offset, alter the reserve_count or call the
+			 client_buffer_end_callback on this sub-buffer.
+			 The only remaining threads could be the ones with pending commits. They
+			 will have to do the deliver themself.
+			 Not concurrency safe in overwrite mode. We detect corrupted subbuffers 
+			 with commit and reserve counts. We keep a corrupted sub-buffers count
+			 and push the readers across these sub-buffers.
+			 Not concurrency safe if a writer is stalled in a subbuffer and
+			 another writer switches in, finding out it's corrupted. The result will
+			 be than the old (uncommited) subbuffer will be declared corrupted, and
+			 that the new subbuffer will be declared corrupted too because of the
+			 commit count adjustment.
+			 Note : offset_old should never be 0 here.*/
+		ltt_channel->buffer_end(buf, *tsc, offset_old, 
+														SUBBUF_INDEX((offset_old-1), buf->chan));
+		/* Setting this reserve_count will allow the sub-buffer to be delivered by
+			 the last committer. */
+		reserve_count = 
+						 atomic_add_return((SUBBUF_OFFSET((offset_old-1), buf->chan)+1),
+						 &ltt_buf->reserve_count[SUBBUF_INDEX((offset_old-1), buf->chan)]);
+		if(reserve_count 
+					== atomic_read(&ltt_buf->commit_count[SUBBUF_INDEX((offset_old-1),
+																															buf->chan)])) {
+			buf->chan->cb->deliver(buf, SUBBUF_INDEX((offset_old-1), buf->chan),
+														 NULL);
+		}
+	}
+
+	if(begin_switch) {
+		/* New sub-buffer */
+		/* This code can be executed unordered : writers may already have written
+			 to the sub-buffer before this code gets executed, caution. */
+		/* The commit makes sure that this code is executed before the deliver
+			 of this sub-buffer */
+		ltt_channel->buffer_begin(buf, *tsc, SUBBUF_INDEX(offset_begin, buf->chan));
+		commit_count = atomic_add_return(ltt_channel->subbuf_header_len(buf),
+							 &ltt_buf->commit_count[SUBBUF_INDEX(offset_begin, buf->chan)]);
+		/* Check if the written buffer has to be delivered */
+		if(commit_count
+					== atomic_read(&ltt_buf->reserve_count[SUBBUF_INDEX(offset_begin,
+																															buf->chan)])) {
+			buf->chan->cb->deliver(buf, SUBBUF_INDEX(offset_begin, buf->chan), NULL);
+		}
+	}
+
+	if(end_switch_current) {
+		/* current subbuffer */
+		/* Concurrency safe because we are the last and only thread to alter this
+			 sub-buffer. As long as it is not delivered and read, no other thread can
+			 alter the offset, alter the reserve_count or call the
+			 client_buffer_end_callback on this sub-buffer.
+			 The only remaining threads could be the ones with pending commits. They
+			 will have to do the deliver themself.
+			 Not concurrency safe in overwrite mode. We detect corrupted subbuffers 
+			 with commit and reserve counts. We keep a corrupted sub-buffers count
+			 and push the readers across these sub-buffers.
+			 Not concurrency safe if a writer is stalled in a subbuffer and
+			 another writer switches in, finding out it's corrupted. The result will
+			 be than the old (uncommited) subbuffer will be declared corrupted, and
+			 that the new subbuffer will be declared corrupted too because of the
+			 commit count adjustment. */
+		ltt_channel->buffer_end(buf, *tsc, offset_end,
+														SUBBUF_INDEX((offset_end-1), buf->chan));
+		/* Setting this reserve_count will allow the sub-buffer to be delivered by
+			 the last committer. */
+		reserve_count = 
+      atomic_add_return((SUBBUF_OFFSET((offset_end-1), buf->chan)+1),
+			&ltt_buf->reserve_count[SUBBUF_INDEX((offset_end-1), buf->chan)]);
+		if(reserve_count 
+					== atomic_read(&ltt_buf->commit_count[SUBBUF_INDEX((offset_end-1),
+																															buf->chan)])) {
+			buf->chan->cb->deliver(buf, SUBBUF_INDEX((offset_end-1), buf->chan), NULL);
+		}
+	}
+
+	*slot_size = size;
+
+	//BUG_ON(*slot_size != (data_size + *before_hdr_pad + *after_hdr_pad + *header_size));
+	//BUG_ON(*slot_size != (offset_end - offset_begin));
+	
+	return buf->start + BUFFER_OFFSET(offset_begin, buf->chan);
+}
+	
+	
+/* ltt_commit_slot
+ *
+ * Atomic unordered slot commit. Increments the commit count in the
+ * specified sub-buffer, and delivers it if necessary.
+ *
+ * Parameters:
+ *
+ * @buf : the buffer to commit to.
+ * @reserved : address of the beginnig of the reserved slot.
+ * @slot_size : size of the reserved slot.
+ *
+ */
+static inline void ltt_commit_slot(
+															struct rchan_buf *buf,
+															void *reserved,
+															unsigned int slot_size)
+{
+	struct ltt_channel_struct *ltt_channel = 
+						(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_channel_buf_struct *ltt_buf = &ltt_channel->buf[buf->cpu];
+
+	unsigned int offset_begin = reserved - buf->start;
+	int commit_count;
+
+	commit_count = atomic_add_return(slot_size,
+													&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin,
+																															buf->chan)]);
+	
+	/* Check if all commits have been done */
+	if(commit_count	==
+	atomic_read(&ltt_buf->reserve_count[SUBBUF_INDEX(offset_begin, buf->chan)])) {
+		buf->chan->cb->deliver(buf, SUBBUF_INDEX(offset_begin, buf->chan), NULL);
+	}
+}
+	
+/* Register and unregister function pointers */
+
+enum ltt_module_function {
+	LTT_FUNCTION_RUN_FILTER,
+	LTT_FUNCTION_FILTER_CONTROL,
+	LTT_FUNCTION_HEARTBEAT,
+	LTT_FUNCTION_STATEDUMP };
+
+extern int ltt_module_register(enum ltt_module_function name, void *function,
+		struct module *owner);
+extern void ltt_module_unregister(enum ltt_module_function name);
+
+/* Exported control function */
+
+enum ltt_heartbeat_functor_msg { LTT_HEARTBEAT_START, LTT_HEARTBEAT_STOP };
+
+enum ltt_control_msg {
+	LTT_CONTROL_START,
+	LTT_CONTROL_STOP,
+	LTT_CONTROL_CREATE_TRACE,
+	LTT_CONTROL_DESTROY_TRACE
+};
+
+union ltt_control_args {
+	struct {
+		enum trace_mode mode;
+		unsigned subbuf_size;
+		unsigned n_subbufs;
+	} new_trace;
+};
+
+extern int ltt_control(enum ltt_control_msg msg, char *trace_name,
+		union ltt_control_args args);
+
+enum ltt_filter_control_msg { 
+	LTT_FILTER_DEFAULT_ACCEPT,
+	LTT_FILTER_DEFAULT_REJECT };
+
+extern int ltt_filter_control(enum ltt_filter_control_msg msg,
+															char *trace_name);
+
+
+void ltt_core_register(int (*function)(u8, void*));
+
+void ltt_core_unregister(void);
+
+
+/* Relayfs IOCTL */
+
+/* Get the next sub buffer that can be read. */
+#define RELAYFS_GET_SUBBUF				_IOR(0xF4, 0x00,__u32)
+/* Release the oldest reserved (by "get") sub buffer. */
+#define RELAYFS_PUT_SUBBUF				_IOW(0xF4, 0x01,__u32)
+/* returns the number of sub buffers in the per cpu channel. */
+#define RELAYFS_GET_N_SUBBUFS			_IOR(0xF4, 0x02,__u32)
+/* returns the size of the sub buffers. */
+#define RELAYFS_GET_SUBBUF_SIZE		_IOR(0xF4, 0x03,__u32)
+
+
+
+//#else /* defined(CONFIG_LTT) */
+//extern inline int ltt_log_event(trace_facility_t fID, u8 eID,
+//																int length, char *buf)
+//{
+//	return 0;
+//}
+
+#endif /* defined(CONFIG_LTT_TRACER) || defined(CONFIG_LTT_TRACER_MODULE) */
+#endif /* _LTT_CORE_H */
diff -uNrp linux-2.6.14.5/include/linux/ltt-facilities.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-facilities.h
--- linux-2.6.14.5/include/linux/ltt-facilities.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-facilities.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * linux/include/linux/ltt-facilities.h
+ *
+ * Copyright (C) 2005 Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * This contains the definitions for the Linux Trace Toolkit facilities.
+ *
+ * Each facility must store its facility index number (returned by the register)
+ * in an exported symbol named :
+ *
+ * ltt_facility_name_checksum
+ *
+ * Where name is the name of the facility, and checksum is the text that
+ * corresponds to the checksum of the facility in hexadecimal notation.
+ */
+
+#ifndef _LTT_FACILITIES_H
+#define _LTT_FACILITIES_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+/* Is kernel tracing enabled */
+#if defined(CONFIG_LTT)
+
+
+#define LTT_MAX_NUM_FACILITIES	256
+#define LTT_RESERVED_FACILITIES	1
+
+
+typedef unsigned long ltt_facility_t;
+
+struct ltt_facility {
+	const char 						*name;
+	const unsigned int		num_events;
+	const u32							checksum;
+	const char						*symbol;
+};
+
+struct ltt_trace_struct;
+
+int ltt_facility_builtin_register(struct ltt_facility *facility);
+
+int ltt_facility_dynamic_register(struct ltt_facility *facility);
+int ltt_facility_dynamic_unregister(ltt_facility_t facility_id);
+
+void ltt_facility_free_unused(void);
+
+void ltt_facility_state_dump(struct ltt_trace_struct *trace);
+
+#endif /* defined(CONFIG_LTT) */
+#endif /* _LTT_FACILITIES_H */
diff -uNrp linux-2.6.14.5/include/linux/ltt-time.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-time.h
--- linux-2.6.14.5/include/linux/ltt-time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/ltt-time.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,155 @@
+#ifndef _LINUX_LTT_TIME_H
+#define _LINUX_LTT_TIME_H
+/*
+ * linux/include/linux/ltt-time.h
+ *
+ * Copyright (C) 2005 - Mathiey Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
+ * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
+ *
+ * LTT time functions.
+ */
+
+#include <linux/time.h>
+
+#include <asm/ltt.h>
+
+#ifndef LTT_TSC_READY
+
+/**
+ *	calc_time_delta - utility function for time delta calculation
+ *	@now: current time
+ *	@start: start time
+ *
+ *	Returns the time delta produced by subtracting start time from now.
+ */
+static inline u64
+calc_time_delta(struct timeval *now,
+		struct timeval *start)
+{
+	return (now->tv_sec - start->tv_sec) * USEC_PER_SEC
+		+ (now->tv_usec - start->tv_usec);
+}
+
+
+#ifdef LTT_HAS_TSC
+
+/**
+ *	get_time_delta - utility function for getting time delta
+ *	@now: pointer to a timeval struct that may be given current time
+ *	@start: the previous time
+ *
+ *	Returns either the TSC if TSCs are being used, or the time and the
+ *	time difference between the current time and the buffer start time
+ *	if TSCs are not being used.
+ *
+ *	We use arch independant "get_cycles" from timex.h and cast the result
+ *	in a 32 bits variable, keeping the 32 LSB.
+ */
+static inline u64
+get_time_delta(struct timeval *now, struct timeval *start)
+{
+	u64 time_delta;
+
+	time_delta = (u64)get_cycles();
+
+	return time_delta;
+}
+
+/**
+ *	get_timestamp - utility function for getting a time and TSC pair
+ *	@now: current time
+ *	@tsc: the TSC associated with now
+ *
+ *	Sets the value pointed to by now to the current time and the value
+ *	pointed to by tsc to the tsc associated with that time, if the
+ *	platform supports TSC.
+ */
+static inline void
+get_timestamp(struct timeval *now,
+	      u64 *tsc)
+{
+	do_gettimeofday(now);
+	
+	*tsc = (u64)get_cycles();
+}
+
+/**
+ *	get_time_or_tsc - utility function for getting a time or a TSC
+ *	@now: current time
+ *	@tsc: current TSC
+ *
+ *	Sets the value pointed to by now to the current time or the value
+ *	pointed to by tsc to the current tsc, depending on whether we're
+ *	using TSCs or not.
+ */
+static inline void
+get_time_or_tsc(struct timeval *now,
+		u64 *tsc)
+{
+	*tsc = (u64)get_cycles();
+}
+
+#else //!LTT_HAS_TSC
+
+/**
+ *	get_time_delta - utility function for getting time delta
+ *	@now: pointer to a timeval struct that may be given current time
+ *	@start: the previous time
+ *
+ *	Returns either the TSC if TSCs are being used, or the time and the
+ *	time difference between the current time and the buffer start time
+ *	if TSCs are not being used.
+ *
+ *	We use arch independant "get_cycles" from timex.h and cast the result
+ *	in a 32 bits variable, keeping the 32 LSB.
+ *
+ */
+static inline u64
+get_time_delta(struct timeval *now, struct timeval *start)
+{
+	u64 time_delta;
+
+	do_gettimeofday(now);
+	time_delta = calc_time_delta(now, start);
+	return time_delta;
+}
+
+/**
+ *	get_timestamp - utility function for getting a time and TSC pair
+ *	@now: current time
+ *	@tsc: the TSC associated with now
+ *
+ *	Sets the value pointed to by now to the current time and the value
+ *	pointed to by tsc to the tsc associated with that time, if the
+ *	platform supports TSC.
+ */
+static inline void
+get_timestamp(struct timeval *now,
+	      u64 *tsc)
+{
+	do_gettimeofday(now);
+	*tsc = 0;
+}
+
+/**
+ *	get_time_or_tsc - utility function for getting a time or a TSC
+ *	@now: current time
+ *	@tsc: current TSC
+ *
+ *	Sets the value pointed to by now to the current time or the value
+ *	pointed to by tsc to the current tsc, depending on whether we're
+ *	using TSCs or not.
+ */
+static inline void
+get_time_or_tsc(struct timeval *now,
+		u64 *tsc)
+{
+	do_gettimeofday(now);
+}
+
+#endif //LTT_HAS_TSC
+
+#endif //!LTT_TSC_READY
+
+#endif //_LINUX_LTT_TIME_H
diff -uNrp linux-2.6.14.5/include/linux/netlink.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/netlink.h
--- linux-2.6.14.5/include/linux/netlink.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/netlink.h	2006-01-22 13:01:14.000000000 +0100
@@ -21,6 +21,7 @@
 #define NETLINK_DNRTMSG		14	/* DECnet routing messages */
 #define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
 #define NETLINK_GENERIC		16
+#define NETLINK_LTT				31 /* Linux Trace Toolkit : until we have a handle */
 
 #define MAX_LINKS 32		
 
diff -uNrp linux-2.6.14.5/include/linux/preempt.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/preempt.h
--- linux-2.6.14.5/include/linux/preempt.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/preempt.h	2006-01-22 13:01:14.000000000 +0100
@@ -13,41 +13,58 @@
   extern void fastcall add_preempt_count(int val);
   extern void fastcall sub_preempt_count(int val);
 #else
-# define add_preempt_count(val)	do { preempt_count() += (val); } while (0)
-# define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
+#define add_preempt_count(val)	do { preempt_count() += (val); } while (0)
+#define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
 #endif
 
-#define inc_preempt_count() add_preempt_count(1)
-#define dec_preempt_count() sub_preempt_count(1)
+#define inc_preempt_count()	add_preempt_count(1)
+#define dec_preempt_count()	sub_preempt_count(1)
 
-#define preempt_count()	(current_thread_info()->preempt_count)
+#define preempt_count()		(current_thread_info()->preempt_count)
 
 #ifdef CONFIG_PREEMPT
 
 asmlinkage void preempt_schedule(void);
 
-#define preempt_disable() \
-do { \
-	inc_preempt_count(); \
-	barrier(); \
+#ifdef CONFIG_IPIPE
+
+#include <asm/ipipe.h>
+
+extern struct ipipe_domain *ipipe_percpu_domain[], *ipipe_root_domain;
+
+#define ipipe_preempt_guard()	(ipipe_percpu_domain[ipipe_processor_id()] == ipipe_root_domain)
+#else
+#define ipipe_preempt_guard()	1
+#endif
+
+#define preempt_disable()						\
+do {									\
+	if (ipipe_preempt_guard()) {					\
+		inc_preempt_count();					\
+		barrier();						\
+	}								\
 } while (0)
 
-#define preempt_enable_no_resched() \
-do { \
-	barrier(); \
-	dec_preempt_count(); \
+#define preempt_enable_no_resched()					\
+do {									\
+	if (ipipe_preempt_guard()) {					\
+		barrier();						\
+		dec_preempt_count();					\
+	}								\
 } while (0)
 
-#define preempt_check_resched() \
-do { \
-	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
-		preempt_schedule(); \
+#define preempt_check_resched()						\
+do {									\
+	if (ipipe_preempt_guard()) {					\
+		if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))	\
+			preempt_schedule();				\
+	}								\
 } while (0)
 
-#define preempt_enable() \
-do { \
-	preempt_enable_no_resched(); \
-	preempt_check_resched(); \
+#define preempt_enable()						\
+do {									\
+	preempt_enable_no_resched();					\
+	preempt_check_resched();					\
 } while (0)
 
 #else
diff -uNrp linux-2.6.14.5/include/linux/relayfs_fs.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/relayfs_fs.h
--- linux-2.6.14.5/include/linux/relayfs_fs.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/relayfs_fs.h	2006-01-22 13:01:14.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * linux/include/linux/relayfs_fs.h
  *
+ * Copyright (C) 2005, Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
  * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
  * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com)
  *
@@ -18,6 +19,10 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/kref.h>
+//#include <linux/percpu.h>
+//#include <linux/preempt.h>
+//#include <linux/err.h>
+//#include <asm/system.h> //for cmpxchg
 
 /*
  * Tracks changes to rchan_buf struct
@@ -34,11 +39,13 @@ struct rchan_buf
 	size_t offset;			/* current offset into sub-buffer */
 	size_t subbufs_produced;	/* count of sub-buffers produced */
 	size_t subbufs_consumed;	/* count of sub-buffers consumed */
+	atomic_t full;		/* buffer is in full state */
 	struct rchan *chan;		/* associated channel */
 	wait_queue_head_t read_wait;	/* reader wait queue */
 	struct work_struct wake_readers; /* reader wake-up work struct */
 	struct dentry *dentry;		/* channel file dentry */
 	struct kref kref;		/* channel buffer refcount */
+	atomic_t open_count;			/* file open count */
 	struct page **page_array;	/* array of current buffer pages */
 	unsigned int page_count;	/* number of current buffer pages */
 	unsigned int finalized;		/* buffer has been finalized */
@@ -46,6 +53,10 @@ struct rchan_buf
 	size_t prev_padding;		/* temporary variable */
 	size_t bytes_consumed;		/* bytes consumed in cur read subbuf */
 	unsigned int cpu;		/* this buf's cpu */
+#ifdef CONFIG_IPIPE
+        struct list_head wake_link;
+        unsigned long wake_posted;
+#endif /* CONFIG_IPIPE */
 } ____cacheline_aligned;
 
 /*
@@ -57,10 +68,16 @@ struct rchan
 	size_t subbuf_size;		/* sub-buffer size */
 	size_t n_subbufs;		/* number of sub-buffers per buffer */
 	size_t alloc_size;		/* total buffer size allocated */
+	int overwrite;			/* overwrite buffer when full? */
 	struct rchan_callbacks *cb;	/* client callbacks */
+	struct file_operations fops; /* file operations */
+	void *client_data; /* client data associated with the client callbacks */
+	void (*free_client_data_cb)(void*); /* Callback function to free the client
+																				 data */
 	struct kref kref;		/* channel refcount */
 	void *private_data;		/* for user-defined data */
 	struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
+	struct module *client_module;	/* Client module (for reference count) */
 };
 
 /*
@@ -86,6 +103,7 @@ struct rchan_callbacks
 	 * subbuf_start - called on buffer-switch to a new sub-buffer
 	 * @buf: the channel buffer containing the new sub-buffer
 	 * @subbuf: the start of the new sub-buffer
+	 * @prev_subbuf_idx: the previous sub-buffer's index
 	 * @prev_subbuf: the start of the previous sub-buffer
 	 * @prev_padding: unused space at the end of previous sub-buffer
 	 *
@@ -105,6 +123,18 @@ struct rchan_callbacks
 			     size_t prev_padding);
 
 	/*
+	 * deliver - deliver a guaranteed full sub-buffer to client
+	 * @buf: the channel buffer containing the sub-buffer
+	 * @subbuf_idx: the sub-buffer's index
+	 * @subbuf: the start of the new sub-buffer
+	 *
+	 * Only works if relay_commit is also used
+	 */
+	void (*deliver) (struct rchan_buf *buf,
+			 unsigned subbuf_idx,
+			 void *subbuf);
+
+	/*
 	 * buf_mapped - relayfs buffer mmap notification
 	 * @buf: the channel buffer
 	 * @filp: relayfs file pointer
@@ -123,6 +153,31 @@ struct rchan_callbacks
 	 */
         void (*buf_unmapped)(struct rchan_buf *buf,
 			     struct file *filp);
+
+	/*
+	 * buf_full - relayfs buffer full notification
+	 * @buf: the channel channel buffer
+	 * @subbuf_idx: the current sub-buffer's index
+	 * @subbuf: the start of the current sub-buffer
+	 *
+	 * Called when a relayfs buffer becomes full
+	 */
+	void (*buf_full)(struct rchan_buf *buf,
+			unsigned subbuf_idx,
+			void *subbuf);
+
+	/*
+	 * buf_unfull - relayfs buffer unfull notification
+	 * @buf: the channel channel buffer
+	 * @subbuf_idx: the current sub-buffer's index
+	 * @subbuf: the start of the current sub-buffer
+	 *
+	 * Called when a relayfs buffer passes from full to not full
+	 */
+	void (*buf_unfull)(struct rchan_buf *buf,
+			unsigned subbuf_idx,
+			void *subbuf);
+
 };
 
 /*
@@ -133,7 +188,12 @@ struct rchan *relay_open(const char *bas
 			 struct dentry *parent,
 			 size_t subbuf_size,
 			 size_t n_subbufs,
-			 struct rchan_callbacks *cb);
+			 int overwrite,
+			 struct module *client_module,
+			 struct rchan_callbacks *cb,
+			 struct file_operations *fops,
+			 void *client_data,
+			 void (*free_client_data_cb)(void*));
 extern void relay_close(struct rchan *chan);
 extern void relay_flush(struct rchan *chan);
 extern void relay_subbufs_consumed(struct rchan *chan,
@@ -224,6 +284,7 @@ static inline void *relay_reserve(struct
 		if (!length)
 			return NULL;
 	}
+
 	reserved = buf->data + buf->offset;
 	buf->offset += length;
 
@@ -245,11 +306,5 @@ static inline void subbuf_start_reserve(
 	buf->offset = length;
 }
 
-/*
- * exported relayfs file operations, fs/relayfs/inode.c
- */
-
-extern struct file_operations relayfs_file_operations;
-
 #endif /* _LINUX_RELAYFS_FS_H */
 
diff -uNrp linux-2.6.14.5/include/linux/sched.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/sched.h
--- linux-2.6.14.5/include/linux/sched.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/sched.h	2006-01-22 13:01:14.000000000 +0100
@@ -4,6 +4,7 @@
 #include <asm/param.h>	/* for HZ */
 
 #include <linux/config.h>
+#include <linux/ipipe.h>
 #include <linux/capability.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
@@ -813,6 +814,9 @@ struct task_struct {
 	int cpuset_mems_generation;
 #endif
 	atomic_t fs_excl;	/* holding fs exclusive resources */
+#ifdef CONFIG_IPIPE
+        void *ptd[IPIPE_ROOT_NPTDKEYS];
+#endif
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
diff -uNrp linux-2.6.14.5/include/linux/seqlock.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/seqlock.h
--- linux-2.6.14.5/include/linux/seqlock.h	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/include/linux/seqlock.h	2006-01-22 13:01:14.000000000 +0100
@@ -49,6 +49,9 @@ typedef struct {
  */
 static inline void write_seqlock(seqlock_t *sl)
 {
+#ifdef CONFIG_IPIPE
+        local_irq_disable_hw();
+#endif /* CONFIG_IPIPE */
 	spin_lock(&sl->lock);
 	++sl->sequence;
 	smp_wmb();			
@@ -59,16 +62,30 @@ static inline void write_sequnlock(seqlo
 	smp_wmb();
 	sl->sequence++;
 	spin_unlock(&sl->lock);
+#ifdef CONFIG_IPIPE
+        local_irq_enable_hw();
+#endif /* CONFIG_IPIPE */
 }
 
 static inline int write_tryseqlock(seqlock_t *sl)
 {
-	int ret = spin_trylock(&sl->lock);
+	int ret;
+
+#ifdef CONFIG_IPIPE
+        local_irq_disable_hw();
+#endif /* CONFIG_IPIPE */
+
+	ret = spin_trylock(&sl->lock);
 
 	if (ret) {
 		++sl->sequence;
 		smp_wmb();			
 	}
+#ifdef CONFIG_IPIPE
+	else
+	  local_irq_enable_hw();
+#endif /* CONFIG_IPIPE */
+
 	return ret;
 }
 
@@ -145,6 +162,7 @@ static inline void write_seqcount_end(se
 	s->sequence++;
 }
 
+/* IPIPE TODO: to check */ 
 /*
  * Possible sw/hw IRQ protected versions of the interfaces.
  */
diff -uNrp linux-2.6.14.5/init/Kconfig linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/init/Kconfig
--- linux-2.6.14.5/init/Kconfig	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/init/Kconfig	2006-01-22 13:01:14.000000000 +0100
@@ -69,6 +69,7 @@ menu "General setup"
 
 config LOCALVERSION
 	string "Local version - append to kernel release"
+	default "-ipipe"
 	help
 	  Append an extra string to the end of your kernel version.
 	  This will show up when you type uname, for example.
diff -uNrp linux-2.6.14.5/init/main.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/init/main.c
--- linux-2.6.14.5/init/main.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/init/main.c	2006-01-22 13:01:14.000000000 +0100
@@ -48,6 +48,7 @@
 #include <linux/mempolicy.h>
 #include <linux/key.h>
 #include <net/sock.h>
+#include <linux/ltt-core.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -402,6 +403,7 @@ static void noinline rest_init(void)
 	 */
 	schedule();
 
+ 	ipipe_reset_stats();
 	cpu_idle();
 } 
 
@@ -480,6 +482,9 @@ asmlinkage void __init start_kernel(void
 		   __stop___param - __start___param,
 		   &unknown_bootoption);
 	sort_main_extable();
+#ifdef CONFIG_LTT
+	ltt_init();
+#endif //CONFIG_LTT
 	trap_init();
 	rcu_init();
 	init_IRQ();
@@ -487,6 +492,11 @@ asmlinkage void __init start_kernel(void
 	init_timers();
 	softirq_init();
 	time_init();
+	/*
+	 * We need to wait for the interrupt and time subsystems to be
+	 * initialized before enabling the pipeline.
+	 */
+ 	ipipe_init();
 
 	/*
 	 * HACK ALERT! This is early. We're enabling the console before
@@ -611,6 +621,7 @@ static void __init do_basic_setup(void)
 #ifdef CONFIG_SYSCTL
 	sysctl_init();
 #endif
+	ipipe_init_proc();
 
 	/* Networking initialization needs a process context */ 
 	sock_init();
diff -uNrp linux-2.6.14.5/ipc/msg.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/msg.c
--- linux-2.6.14.5/ipc/msg.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/msg.c	2006-01-22 13:01:14.000000000 +0100
@@ -15,6 +15,7 @@
  * (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
  */
 
+#include <linux/ltt/ltt-facility-ipc.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/msg.h>
@@ -232,6 +233,8 @@ asmlinkage long sys_msgget (key_t key, i
 		msg_unlock(msq);
 	}
 	up(&msg_ids.sem);
+	
+	trace_ipc_msg_create(ret, msgflg);
 	return ret;
 }
 
diff -uNrp linux-2.6.14.5/ipc/sem.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/sem.c
--- linux-2.6.14.5/ipc/sem.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/sem.c	2006-01-22 13:01:14.000000000 +0100
@@ -63,6 +63,7 @@
  * (c) 2003 Manfred Spraul <manfred@colorfullife.com>
  */
 
+#include <linux/ltt/ltt-facility-ipc.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -242,6 +243,7 @@ asmlinkage long sys_semget (key_t key, i
 	}
 
 	up(&sem_ids.sem);
+	trace_ipc_sem_create(err, semflg);
 	return err;
 }
 
diff -uNrp linux-2.6.14.5/ipc/shm.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/shm.c
--- linux-2.6.14.5/ipc/shm.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ipc/shm.c	2006-01-22 13:01:14.000000000 +0100
@@ -15,6 +15,7 @@
  *
  */
 
+#include <linux/ltt/ltt-facility-ipc.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
@@ -281,7 +282,7 @@ asmlinkage long sys_shmget (key_t key, s
 		shm_unlock(shp);
 	}
 	up(&shm_ids.sem);
-
+	trace_ipc_shm_create(err, shmflg);
 	return err;
 }
 
diff -uNrp linux-2.6.14.5/kernel/exit.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/exit.c
--- linux-2.6.14.5/kernel/exit.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/exit.c	2006-01-22 13:01:14.000000000 +0100
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/ltt/ltt-facility-process.h>
 #include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -105,6 +106,7 @@ repeat: 
 	spin_unlock(&p->proc_lock);
 	proc_pid_flush(proc_dentry);
 	release_thread(p);
+  trace_process_free(p->pid);
 	put_task_struct(p);
 
 	p = leader;
@@ -846,8 +848,11 @@ fastcall NORET_TYPE void do_exit(long co
 		exit_itimers(tsk->signal);
 		acct_process(code);
 	}
+ 	ipipe_exit_notify(tsk);
 	exit_mm(tsk);
 
+	trace_process_exit(tsk->pid);
+
 	exit_sem(tsk);
 	__exit_files(tsk);
 	__exit_fs(tsk);
@@ -1356,6 +1361,8 @@ static long do_wait(pid_t pid, int optio
 	struct task_struct *tsk;
 	int flag, retval;
 
+	trace_process_wait(current->pid, pid);
+
 	add_wait_queue(&current->signal->wait_chldexit,&wait);
 repeat:
 	/*
diff -uNrp linux-2.6.14.5/kernel/fork.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/fork.c
--- linux-2.6.14.5/kernel/fork.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/fork.c	2006-01-22 13:01:14.000000000 +0100
@@ -11,6 +11,7 @@
  * management can be a bitch. See 'mm/memory.c': 'copy_page_range()'
  */
 
+#include <linux/ltt/ltt-facility-process.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -1153,6 +1154,14 @@ static task_t *copy_process(unsigned lon
 	total_forks++;
 	write_unlock_irq(&tasklist_lock);
 	retval = 0;
+#ifdef CONFIG_IPIPE
+	{
+	int k;
+
+	for (k = 0; k < IPIPE_ROOT_NPTDKEYS; k++)
+	    p->ptd[k] = NULL;
+	}
+#endif /* CONFIG_IPIPE */
 
 fork_out:
 	if (retval)
@@ -1266,6 +1275,8 @@ long do_fork(unsigned long clone_flags,
 	if (!IS_ERR(p)) {
 		struct completion vfork;
 
+		trace_process_fork(current->pid, p->pid);
+
 		if (clone_flags & CLONE_VFORK) {
 			p->vfork_done = &vfork;
 			init_completion(&vfork);
diff -uNrp linux-2.6.14.5/kernel/ipipe/core.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/core.c
--- linux-2.6.14.5/kernel/ipipe/core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/core.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,679 @@
+/* -*- linux-c -*-
+ * linux/kernel/ipipe/core.c
+ *
+ * Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Architecture-independent I-PIPE core support.
+ */
+
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif	/* CONFIG_PROC_FS */
+
+static struct ipipe_domain ipipe_root =
+	{ .cpudata = {[0 ... IPIPE_NR_CPUS-1] =
+		{ .status = (1<<IPIPE_STALL_FLAG) } } };
+
+struct ipipe_domain *ipipe_root_domain = &ipipe_root;
+
+struct ipipe_domain *ipipe_percpu_domain[IPIPE_NR_CPUS] =
+	{[0 ... IPIPE_NR_CPUS - 1] = &ipipe_root };
+
+ipipe_spinlock_t __ipipe_pipelock = IPIPE_SPIN_LOCK_UNLOCKED;
+
+struct list_head __ipipe_pipeline;
+
+unsigned long __ipipe_virtual_irq_map = 0;
+
+unsigned __ipipe_printk_virq;
+
+int __ipipe_event_monitors[IPIPE_NR_EVENTS];
+
+/*
+ * ipipe_init() -- Initialization routine of the IPIPE layer. Called
+ * by the host kernel early during the boot procedure.
+ */
+void ipipe_init(void)
+{
+	struct ipipe_domain *ipd = &ipipe_root;
+
+	__ipipe_check_platform();	/* Do platform dependent checks first. */
+
+	/*
+	 * A lightweight registration code for the root domain. We are
+	 * running on the boot CPU, hw interrupts are off, and
+	 * secondary CPUs are still lost in space.
+	 */
+
+	INIT_LIST_HEAD(&__ipipe_pipeline);
+
+	ipd->name = "Linux";
+	ipd->domid = IPIPE_ROOT_ID;
+	ipd->priority = IPIPE_ROOT_PRIO;
+
+	__ipipe_init_stage(ipd);
+
+	INIT_LIST_HEAD(&ipd->p_link);
+	list_add_tail(&ipd->p_link, &__ipipe_pipeline);
+
+	__ipipe_init_platform();
+
+	__ipipe_printk_virq = ipipe_alloc_virq();	/* Cannot fail here. */
+	ipd->irqs[__ipipe_printk_virq].handler = &__ipipe_flush_printk;
+	ipd->irqs[__ipipe_printk_virq].acknowledge = NULL;
+	ipd->irqs[__ipipe_printk_virq].control = IPIPE_HANDLE_MASK;
+
+	__ipipe_enable_pipeline();
+
+	printk(KERN_INFO "I-pipe %s: pipeline enabled.\n",
+	       IPIPE_VERSION_STRING);
+}
+
+void __ipipe_init_stage(struct ipipe_domain *ipd)
+{
+	int cpuid, n;
+
+	for (cpuid = 0; cpuid < IPIPE_NR_CPUS; cpuid++) {
+		ipd->cpudata[cpuid].irq_pending_hi = 0;
+
+		for (n = 0; n < IPIPE_IRQ_IWORDS; n++)
+			ipd->cpudata[cpuid].irq_pending_lo[n] = 0;
+
+		for (n = 0; n < IPIPE_NR_IRQS; n++)
+			ipd->cpudata[cpuid].irq_hits[n] = 0;
+	}
+
+	for (n = 0; n < IPIPE_NR_IRQS; n++) {
+		ipd->irqs[n].acknowledge = NULL;
+		ipd->irqs[n].handler = NULL;
+		ipd->irqs[n].control = IPIPE_PASS_MASK;	/* Pass but don't handle */
+	}
+
+	for (n = 0; n < IPIPE_NR_EVENTS; n++)
+		ipd->evhand[n] = NULL;
+
+	ipd->evexcl = 0;
+
+#ifdef CONFIG_SMP
+	ipd->irqs[IPIPE_CRITICAL_IPI].acknowledge = &__ipipe_ack_system_irq;
+	ipd->irqs[IPIPE_CRITICAL_IPI].handler = &__ipipe_do_critical_sync;
+	/* Immediately handle in the current domain but *never* pass */
+	ipd->irqs[IPIPE_CRITICAL_IPI].control =
+		IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK;
+#endif	/* CONFIG_SMP */
+}
+
+void __ipipe_stall_root(void)
+{
+	ipipe_declare_cpuid;
+	unsigned long flags;
+
+	ipipe_get_cpu(flags); /* Care for migration. */
+
+	set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+
+#ifdef CONFIG_SMP
+	if (!__ipipe_pipeline_head_p(ipipe_root_domain))
+		ipipe_put_cpu(flags);
+#else /* CONFIG_SMP */
+	if (__ipipe_pipeline_head_p(ipipe_root_domain))
+		local_irq_disable_hw();
+#endif /* CONFIG_SMP */
+	ipipe_mark_domain_stall(ipipe_root_domain,cpuid);
+}
+
+void __ipipe_cleanup_domain(struct ipipe_domain *ipd)
+{
+	ipipe_unstall_pipeline_from(ipd);
+
+#ifdef CONFIG_SMP
+	{
+		int cpu;
+
+		for_each_online_cpu(cpu) {
+			while (ipd->cpudata[cpu].irq_pending_hi != 0)
+				cpu_relax();
+		}
+	}
+#endif	/* CONFIG_SMP */
+}
+
+void __ipipe_unstall_root(void)
+{
+	ipipe_declare_cpuid;
+
+	local_irq_disable_hw();
+
+	ipipe_load_cpuid();
+
+	__clear_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+
+	ipipe_mark_domain_unstall(ipipe_root_domain, cpuid);
+
+	if (ipipe_root_domain->cpudata[cpuid].irq_pending_hi != 0)
+		__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+
+	local_irq_enable_hw();
+}
+
+unsigned long __ipipe_test_root(void)
+{
+	unsigned long flags, s;
+	ipipe_declare_cpuid;
+
+	ipipe_get_cpu(flags); /* Care for migration. */
+	s = test_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+	ipipe_put_cpu(flags);
+
+	return s;
+}
+
+unsigned long __ipipe_test_and_stall_root(void)
+{
+	unsigned long flags, s;
+	ipipe_declare_cpuid;
+
+	ipipe_get_cpu(flags); /* Care for migration. */
+	s = test_and_set_bit(IPIPE_STALL_FLAG,
+			     &ipipe_root_domain->cpudata[cpuid].status);
+	ipipe_mark_domain_stall(ipipe_root_domain,cpuid);
+	ipipe_put_cpu(flags);
+
+	return s;
+}
+
+void fastcall __ipipe_restore_root(unsigned long flags)
+{
+	if (flags)
+		__ipipe_stall_root();
+	else
+		__ipipe_unstall_root();
+}
+
+/*
+ * ipipe_unstall_pipeline_from() -- Unstall the pipeline and
+ * synchronize pending interrupts for a given domain. See
+ * __ipipe_walk_pipeline() for more information.
+ */
+void fastcall ipipe_unstall_pipeline_from(struct ipipe_domain *ipd)
+{
+	struct ipipe_domain *this_domain;
+	struct list_head *pos;
+	unsigned long flags;
+	ipipe_declare_cpuid;
+
+	ipipe_lock_cpu(flags);
+
+	__clear_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpuid].status);
+
+	ipipe_mark_domain_unstall(ipd, cpuid);
+
+	this_domain = ipipe_percpu_domain[cpuid];
+
+	if (ipd == this_domain) {
+		if (ipd->cpudata[cpuid].irq_pending_hi != 0)
+			__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+
+		goto release_cpu_and_exit;
+	}
+
+	list_for_each(pos, &__ipipe_pipeline) {
+
+		struct ipipe_domain *next_domain =
+			list_entry(pos, struct ipipe_domain, p_link);
+
+		if (test_bit(IPIPE_STALL_FLAG,
+			     &next_domain->cpudata[cpuid].status))
+			break;	/* Stalled stage -- do not go further. */
+
+		if (next_domain->cpudata[cpuid].irq_pending_hi != 0) {
+
+			if (next_domain == this_domain)
+				__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+			else {
+				__ipipe_switch_to(this_domain, next_domain,
+						  cpuid);
+
+				ipipe_load_cpuid();	/* Processor might have changed. */
+
+				if (this_domain->cpudata[cpuid].
+				    irq_pending_hi != 0
+				    && !test_bit(IPIPE_STALL_FLAG,
+						 &this_domain->cpudata[cpuid].
+						 status))
+					__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+			}
+
+			break;
+		} else if (next_domain == this_domain)
+			break;
+	}
+
+release_cpu_and_exit:
+
+	if (__ipipe_pipeline_head_p(ipd))
+		local_irq_enable_hw();
+	else
+		ipipe_unlock_cpu(flags);
+}
+
+/*
+ * ipipe_suspend_domain() -- Suspend the current domain, switching to
+ * the next one which has pending work down the pipeline.
+ */
+void ipipe_suspend_domain(void)
+{
+	struct ipipe_domain *this_domain, *next_domain;
+	struct list_head *ln;
+	unsigned long flags;
+	ipipe_declare_cpuid;
+
+	ipipe_lock_cpu(flags);
+
+	this_domain = next_domain = ipipe_percpu_domain[cpuid];
+
+	__clear_bit(IPIPE_STALL_FLAG, &this_domain->cpudata[cpuid].status);
+
+	ipipe_mark_domain_unstall(this_domain, cpuid);
+
+	if (this_domain->cpudata[cpuid].irq_pending_hi != 0)
+		goto sync_stage;
+
+	for (;;) {
+		ln = next_domain->p_link.next;
+
+		if (ln == &__ipipe_pipeline)
+			break;
+
+		next_domain = list_entry(ln, struct ipipe_domain, p_link);
+
+		if (test_bit(IPIPE_STALL_FLAG,
+			     &next_domain->cpudata[cpuid].status))
+			break;
+
+		if (next_domain->cpudata[cpuid].irq_pending_hi == 0)
+			continue;
+
+		ipipe_percpu_domain[cpuid] = next_domain;
+
+sync_stage:
+
+		__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+
+		ipipe_load_cpuid();	/* Processor might have changed. */
+
+		if (ipipe_percpu_domain[cpuid] != next_domain)
+			/*
+			 * Something has changed the current domain under our
+			 * feet, recycling the register set; take note.
+			 */
+			this_domain = ipipe_percpu_domain[cpuid];
+	}
+
+	ipipe_percpu_domain[cpuid] = this_domain;
+
+	ipipe_unlock_cpu(flags);
+}
+
+/* ipipe_alloc_virq() -- Allocate a pipelined virtual/soft interrupt.
+ * Virtual interrupts are handled in exactly the same way than their
+ * hw-generated counterparts wrt pipelining.
+ */
+unsigned ipipe_alloc_virq(void)
+{
+	unsigned long flags, irq = 0;
+	int ipos;
+
+	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);
+
+	if (__ipipe_virtual_irq_map != ~0) {
+		ipos = ffz(__ipipe_virtual_irq_map);
+		set_bit(ipos, &__ipipe_virtual_irq_map);
+		irq = ipos + IPIPE_VIRQ_BASE;
+	}
+
+	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);
+
+	return irq;
+}
+
+/* __ipipe_dispatch_event() -- Low-level event dispatcher. */
+
+int fastcall __ipipe_dispatch_event (unsigned event, void *data)
+{
+	struct ipipe_domain *start_domain, *this_domain, *next_domain;
+	struct list_head *pos, *npos;
+	unsigned long flags;
+	ipipe_declare_cpuid;
+	int propagate = 1;
+
+	ipipe_lock_cpu(flags);
+
+	start_domain = this_domain = ipipe_percpu_domain[cpuid];
+
+	list_for_each_safe(pos,npos,&__ipipe_pipeline) {
+
+		next_domain = list_entry(pos,struct ipipe_domain,p_link);
+
+		/*
+		 * Note: Domain migration may occur while running
+		 * event or interrupt handlers, in which case the
+		 * current register set is going to be recycled for a
+		 * different domain than the initiating one. We do
+		 * care for that, always tracking the current domain
+		 * descriptor upon return from those handlers.
+		 */
+		if (next_domain->evhand[event] != NULL)	{
+			ipipe_percpu_domain[cpuid] = next_domain;
+			ipipe_unlock_cpu(flags);
+			propagate = !next_domain->evhand[event](event,start_domain,data);
+			ipipe_lock_cpu(flags);
+			if (ipipe_percpu_domain[cpuid] != next_domain)
+				this_domain = ipipe_percpu_domain[cpuid];
+		}
+
+		if (next_domain != ipipe_root_domain &&	/* NEVER sync the root stage here. */
+		    next_domain->cpudata[cpuid].irq_pending_hi != 0 &&
+		    !test_bit(IPIPE_STALL_FLAG,&next_domain->cpudata[cpuid].status)) {
+			ipipe_percpu_domain[cpuid] = next_domain;
+			__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+			ipipe_load_cpuid();
+			if (ipipe_percpu_domain[cpuid] != next_domain)
+				this_domain = ipipe_percpu_domain[cpuid];
+		}
+
+		ipipe_percpu_domain[cpuid] = this_domain;
+
+		if (next_domain == this_domain || !propagate)
+			break;
+	}
+
+	ipipe_unlock_cpu(flags);
+
+	return !propagate;
+}
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/proc_fs.h>
+
+struct proc_dir_entry *ipipe_proc_root;
+
+static int __ipipe_version_info_proc(char *page,
+				     char **start,
+				     off_t off, int count, int *eof, void *data)
+{
+	int len = sprintf(page, "%s\n", IPIPE_VERSION_STRING);
+
+	len -= off;
+
+	if (len <= off + count)
+		*eof = 1;
+
+	*start = page + off;
+
+	if(len > count)
+		len = count;
+
+	if(len < 0)
+		len = 0;
+
+	return len;
+}
+
+static int __ipipe_common_info_proc(char *page,
+				    char **start,
+				    off_t off, int count, int *eof, void *data)
+{
+	struct ipipe_domain *ipd = (struct ipipe_domain *)data;
+	unsigned long ctlbits;
+	unsigned irq, _irq;
+	char *p = page;
+	int len;
+
+	spin_lock(&__ipipe_pipelock);
+
+	p += sprintf(p, "Priority=%d, Id=0x%.8x\n",
+		     ipd->priority, ipd->domid);
+	irq = 0;
+
+	while (irq < IPIPE_NR_IRQS) {
+		ctlbits =
+			(ipd->irqs[irq].
+			 control & (IPIPE_HANDLE_MASK | IPIPE_PASS_MASK |
+				    IPIPE_STICKY_MASK));
+		if (irq >= IPIPE_NR_XIRQS && !ipipe_virtual_irq_p(irq)) {
+			/*
+			 * There might be a hole between the last external
+			 * IRQ and the first virtual one; skip it.
+			 */
+			irq++;
+			continue;
+		}
+
+		if (ipipe_virtual_irq_p(irq)
+		    && !test_bit(irq - IPIPE_VIRQ_BASE,
+				 &__ipipe_virtual_irq_map)) {
+			/* Non-allocated virtual IRQ; skip it. */
+			irq++;
+			continue;
+		}
+
+		/*
+		 * Attempt to group consecutive IRQ numbers having the
+		 * same virtualization settings in a single line.
+		 */
+
+		_irq = irq;
+
+		while (++_irq < IPIPE_NR_IRQS) {
+			if (ipipe_virtual_irq_p(_irq) !=
+			    ipipe_virtual_irq_p(irq)
+			    || (ipipe_virtual_irq_p(_irq)
+				&& !test_bit(_irq - IPIPE_VIRQ_BASE,
+					     &__ipipe_virtual_irq_map))
+			    || ctlbits != (ipd->irqs[_irq].
+			     control & (IPIPE_HANDLE_MASK |
+					IPIPE_PASS_MASK |
+					IPIPE_STICKY_MASK)))
+				break;
+		}
+
+		if (_irq == irq + 1)
+			p += sprintf(p, "irq%u: ", irq);
+		else
+			p += sprintf(p, "irq%u-%u: ", irq, _irq - 1);
+
+		/*
+		 * Statuses are as follows:
+		 * o "accepted" means handled _and_ passed down the pipeline.
+		 * o "grabbed" means handled, but the interrupt might be
+		 * terminated _or_ passed down the pipeline depending on
+		 * what the domain handler asks for to the I-pipe.
+		 * o "passed" means unhandled by the domain but passed
+		 * down the pipeline.
+		 * o "discarded" means unhandled and _not_ passed down the
+		 * pipeline. The interrupt merely disappears from the
+		 * current domain down to the end of the pipeline.
+		 */
+		if (ctlbits & IPIPE_HANDLE_MASK) {
+			if (ctlbits & IPIPE_PASS_MASK)
+				p += sprintf(p, "accepted");
+			else
+				p += sprintf(p, "grabbed");
+		} else if (ctlbits & IPIPE_PASS_MASK)
+			p += sprintf(p, "passed");
+		else
+			p += sprintf(p, "discarded");
+
+		if (ctlbits & IPIPE_STICKY_MASK)
+			p += sprintf(p, ", sticky");
+
+		if (ipipe_virtual_irq_p(irq))
+			p += sprintf(p, ", virtual");
+
+		p += sprintf(p, "\n");
+
+		irq = _irq;
+	}
+
+	spin_unlock(&__ipipe_pipelock);
+
+	len = p - page;
+
+	if (len <= off + count)
+		*eof = 1;
+
+	*start = page + off;
+
+	len -= off;
+
+	if (len > count)
+		len = count;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+#ifdef CONFIG_IPIPE_STATS
+
+static int __ipipe_stat_info_proc(char *page,
+				  char **start,
+				  off_t off, int count, int *eof, void *data)
+{
+	struct ipipe_domain *ipd = (struct ipipe_domain *)data;
+	int len = 0, cpu, irq;
+	char *p = page;
+
+	p += sprintf(p,"> STALL TIME:\n");
+
+	for_each_online_cpu(cpu) {
+		unsigned long eip = ipd->stats[cpu].max_stall_eip;
+		char namebuf[KSYM_NAME_LEN+1];
+		unsigned long offset, size, t;
+		const char *name;
+		char *modname;
+
+		name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);
+		t = ipipe_tsc2ns(ipd->stats[cpu].max_stall_time);
+
+		if (name) {
+			if (modname)
+				p += sprintf(p,"CPU%d  %12lu  (%s+%#lx [%s])\n",
+					     cpu,t,name,offset,modname);
+			else
+				p += sprintf(p,"CPU%d  %12lu  (%s+%#lx)\n",
+					     cpu,t,name,offset);
+		}
+		else
+			p += sprintf(p,"CPU%d  %12lu  (%lx)\n",
+				     cpu,t,eip);
+	}
+
+	p += sprintf(p,"> PROPAGATION TIME:\nIRQ");
+
+	for_each_online_cpu(cpu) {
+		p += sprintf(p,"         CPU%d",cpu);
+	}
+
+	for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {
+
+		unsigned long long t = 0;
+
+		for_each_online_cpu(cpu) {
+			t += ipd->stats[cpu].irq_stats[irq].max_delivery_time;
+		}
+
+		if (!t)
+			continue;
+
+		p += sprintf(p,"\n%3d:",irq);
+
+		for_each_online_cpu(cpu) {
+			p += sprintf(p,"%13lu",
+				     ipipe_tsc2ns(ipd->stats[cpu].irq_stats[irq].max_delivery_time));
+		}
+	}
+
+	p += sprintf(p,"\n");
+
+	len = p - page - off;
+	if (len <= off + count) *eof = 1;
+	*start = page + off;
+	if (len > count) len = count;
+	if (len < 0) len = 0;
+
+	return len;
+}
+
+#endif /* CONFIG_IPIPE_STATS */
+
+void __ipipe_add_domain_proc(struct ipipe_domain *ipd)
+{
+
+	create_proc_read_entry(ipd->name,0444,ipipe_proc_root,&__ipipe_common_info_proc,ipd);
+#ifdef CONFIG_IPIPE_STATS
+	{
+		char name[64];
+		snprintf(name,sizeof(name),"%s_stats",ipd->name);
+		create_proc_read_entry(name,0444,ipipe_proc_root,&__ipipe_stat_info_proc,ipd);
+	}
+#endif /* CONFIG_IPIPE_STATS */
+}
+
+void __ipipe_remove_domain_proc(struct ipipe_domain *ipd)
+{
+	remove_proc_entry(ipd->name,ipipe_proc_root);
+#ifdef CONFIG_IPIPE_STATS
+	{
+		char name[64];
+		snprintf(name,sizeof(name),"%s_stats",ipd->name);
+		remove_proc_entry(name,ipipe_proc_root);
+	}
+#endif /* CONFIG_IPIPE_STATS */
+}
+
+void ipipe_init_proc(void)
+{
+	ipipe_proc_root = create_proc_entry("ipipe",S_IFDIR, 0);
+	create_proc_read_entry("version",0444,ipipe_proc_root,&__ipipe_version_info_proc,NULL);
+	__ipipe_init_trace_proc();
+	__ipipe_add_domain_proc(ipipe_root_domain);
+}
+
+#endif	/* CONFIG_PROC_FS */
+
+EXPORT_SYMBOL(ipipe_suspend_domain);
+EXPORT_SYMBOL(ipipe_alloc_virq);
+EXPORT_SYMBOL(ipipe_unstall_pipeline_from);
+EXPORT_SYMBOL(ipipe_percpu_domain);
+EXPORT_SYMBOL(ipipe_root_domain);
+EXPORT_SYMBOL(__ipipe_unstall_root);
+EXPORT_SYMBOL(__ipipe_stall_root);
+EXPORT_SYMBOL(__ipipe_restore_root);
+EXPORT_SYMBOL(__ipipe_test_and_stall_root);
+EXPORT_SYMBOL(__ipipe_test_root);
+EXPORT_SYMBOL(__ipipe_dispatch_event);
+EXPORT_SYMBOL(__ipipe_pipeline);
+EXPORT_SYMBOL(__ipipe_pipelock);
+EXPORT_SYMBOL(__ipipe_virtual_irq_map);
diff -uNrp linux-2.6.14.5/kernel/ipipe/generic.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/generic.c
--- linux-2.6.14.5/kernel/ipipe/generic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/generic.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,390 @@
+/* -*- linux-c -*-
+ * linux/kernel/ipipe/generic.c
+ *
+ * Copyright (C) 2002-2005 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Architecture-independent I-PIPE services.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif	/* CONFIG_PROC_FS */
+
+MODULE_DESCRIPTION("I-pipe");
+MODULE_LICENSE("GPL");
+
+static int __ipipe_ptd_key_count;
+
+static unsigned long __ipipe_ptd_key_map;
+
+/* ipipe_register_domain() -- Link a new domain to the pipeline. */
+
+int ipipe_register_domain(struct ipipe_domain *ipd,
+			  struct ipipe_domain_attr *attr)
+{
+	struct list_head *pos;
+	unsigned long flags;
+
+	if (ipipe_current_domain != ipipe_root_domain) {
+		printk(KERN_WARNING
+		       "I-pipe: Only the root domain may register a new domain.\n");
+		return -EPERM;
+	}
+
+	flags = ipipe_critical_enter(NULL);
+
+	list_for_each(pos, &__ipipe_pipeline) {
+		struct ipipe_domain *_ipd =
+			list_entry(pos, struct ipipe_domain, p_link);
+		if (_ipd->domid == attr->domid)
+			break;
+	}
+
+	ipipe_critical_exit(flags);
+
+	if (pos != &__ipipe_pipeline)
+		/* A domain with the given id already exists -- fail. */
+		return -EBUSY;
+
+	ipd->name = attr->name;
+	ipd->priority = attr->priority;
+	ipd->domid = attr->domid;
+	ipd->pdd = attr->pdd;
+	ipd->flags = 0;
+
+#ifdef CONFIG_IPIPE_STATS
+	{
+		int cpu, irq;
+		for_each_online_cpu(cpu) {
+			ipd->stats[cpu].last_stall_date = 0LL;
+			for (irq = 0; irq < IPIPE_NR_IRQS; irq++)
+				ipd->stats[cpu].irq_stats[irq].last_receipt_date = 0LL;
+		}
+	}
+#endif /* CONFIG_IPIPE_STATS */
+
+	__ipipe_init_stage(ipd);
+
+	INIT_LIST_HEAD(&ipd->p_link);
+
+#ifdef CONFIG_PROC_FS
+	__ipipe_add_domain_proc(ipd);
+#endif /* CONFIG_PROC_FS */
+
+	flags = ipipe_critical_enter(NULL);
+
+	list_for_each(pos, &__ipipe_pipeline) {
+		struct ipipe_domain *_ipd =
+			list_entry(pos, struct ipipe_domain, p_link);
+		if (ipd->priority > _ipd->priority)
+			break;
+	}
+
+	list_add_tail(&ipd->p_link, pos);
+
+	ipipe_critical_exit(flags);
+
+	printk(KERN_WARNING "I-pipe: Domain %s registered.\n", ipd->name);
+
+	/*
+	 * Finally, allow the new domain to perform its initialization
+	 * chores.
+	 */
+
+	if (attr->entry != NULL) {
+		ipipe_declare_cpuid;
+
+		ipipe_lock_cpu(flags);
+
+		ipipe_percpu_domain[cpuid] = ipd;
+		attr->entry();
+		ipipe_percpu_domain[cpuid] = ipipe_root_domain;
+
+		ipipe_load_cpuid();	/* Processor might have changed. */
+
+		if (ipipe_root_domain->cpudata[cpuid].irq_pending_hi != 0 &&
+		    !test_bit(IPIPE_STALL_FLAG,
+			      &ipipe_root_domain->cpudata[cpuid].status))
+			__ipipe_sync_stage(IPIPE_IRQMASK_ANY);
+
+		ipipe_unlock_cpu(flags);
+	}
+
+	return 0;
+}
+
+/* ipipe_unregister_domain() -- Remove a domain from the pipeline. */
+
+int ipipe_unregister_domain(struct ipipe_domain *ipd)
+{
+	unsigned long flags;
+
+	if (ipipe_current_domain != ipipe_root_domain) {
+		printk(KERN_WARNING
+		       "I-pipe: Only the root domain may unregister a domain.\n");
+		return -EPERM;
+	}
+
+	if (ipd == ipipe_root_domain) {
+		printk(KERN_WARNING
+		       "I-pipe: Cannot unregister the root domain.\n");
+		return -EPERM;
+	}
+#ifdef CONFIG_SMP
+	{
+		int nr_cpus = num_online_cpus(), _cpuid;
+		unsigned irq;
+
+		/*
+		 * In the SMP case, wait for the logged events to drain on
+		 * other processors before eventually removing the domain
+		 * from the pipeline.
+		 */
+
+		ipipe_unstall_pipeline_from(ipd);
+
+		flags = ipipe_critical_enter(NULL);
+
+		for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {
+			clear_bit(IPIPE_HANDLE_FLAG, &ipd->irqs[irq].control);
+			clear_bit(IPIPE_STICKY_FLAG, &ipd->irqs[irq].control);
+			set_bit(IPIPE_PASS_FLAG, &ipd->irqs[irq].control);
+		}
+
+		ipipe_critical_exit(flags);
+
+		for (_cpuid = 0; _cpuid < nr_cpus; _cpuid++)
+			for (irq = 0; irq < IPIPE_NR_IRQS; irq++)
+				while (ipd->cpudata[_cpuid].irq_hits[irq] > 0)
+					cpu_relax();
+	}
+#endif	/* CONFIG_SMP */
+
+#ifdef CONFIG_PROC_FS
+	__ipipe_remove_domain_proc(ipd);
+#endif /* CONFIG_PROC_FS */
+
+	/*
+	 * Simply remove the domain from the pipeline and we are almost done.
+	 */
+
+	flags = ipipe_critical_enter(NULL);
+	list_del_init(&ipd->p_link);
+	ipipe_critical_exit(flags);
+
+	__ipipe_cleanup_domain(ipd);
+
+	printk(KERN_WARNING "I-pipe: Domain %s unregistered.\n", ipd->name);
+
+	return 0;
+}
+
+/*
+ * ipipe_propagate_irq() -- Force a given IRQ propagation on behalf of
+ * a running interrupt handler to the next domain down the pipeline.
+ * ipipe_schedule_irq() -- Does almost the same as above, but attempts
+ * to pend the interrupt for the current domain first.
+ */
+int fastcall __ipipe_schedule_irq(unsigned irq, struct list_head *head)
+{
+	struct list_head *ln;
+	unsigned long flags;
+	ipipe_declare_cpuid;
+
+	if (irq >= IPIPE_NR_IRQS ||
+	    (ipipe_virtual_irq_p(irq)
+	     && !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
+		return -EINVAL;
+
+	ipipe_lock_cpu(flags);
+
+	ln = head;
+
+	while (ln != &__ipipe_pipeline) {
+		struct ipipe_domain *ipd =
+			list_entry(ln, struct ipipe_domain, p_link);
+
+		if (test_bit(IPIPE_HANDLE_FLAG, &ipd->irqs[irq].control)) {
+			ipd->cpudata[cpuid].irq_hits[irq]++;
+			__ipipe_set_irq_bit(ipd, cpuid, irq);
+			ipipe_mark_irq_receipt(ipd, irq, cpuid);
+			ipipe_unlock_cpu(flags);
+			return 1;
+		}
+
+		ln = ipd->p_link.next;
+	}
+
+	ipipe_unlock_cpu(flags);
+
+	return 0;
+}
+
+/* ipipe_free_virq() -- Release a virtual/soft interrupt. */
+
+int ipipe_free_virq(unsigned virq)
+{
+	if (!ipipe_virtual_irq_p(virq))
+		return -EINVAL;
+
+	clear_bit(virq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map);
+
+	return 0;
+}
+
+void ipipe_init_attr(struct ipipe_domain_attr *attr)
+{
+	attr->name = "anon";
+	attr->domid = 1;
+	attr->entry = NULL;
+	attr->priority = IPIPE_ROOT_PRIO;
+	attr->pdd = NULL;
+}
+
+/*
+ * ipipe_catch_event() -- Interpose or remove an event handler for a
+ * given domain.
+ */
+int ipipe_catch_event(struct ipipe_domain *ipd,
+		      unsigned event,
+		      int (*handler)(unsigned event, struct ipipe_domain *ipd, void *data))
+{
+	if (event >= IPIPE_NR_EVENTS)
+		return -EINVAL;
+
+	if (!xchg(&ipd->evhand[event],handler))	{
+		if (handler)
+			__ipipe_event_monitors[event]++;
+	}
+	else if (!handler)
+		__ipipe_event_monitors[event]--;
+
+	return 0;
+}
+
+cpumask_t ipipe_set_irq_affinity (unsigned irq, cpumask_t cpumask)
+{
+#ifdef CONFIG_SMP
+	if (irq >= IPIPE_NR_XIRQS)
+		/* Allow changing affinity of external IRQs only. */
+		return CPU_MASK_NONE;
+
+	if (num_online_cpus() > 1)
+		/* Allow changing affinity of external IRQs only. */
+		return __ipipe_set_irq_affinity(irq,cpumask);
+#endif /* CONFIG_SMP */
+
+	return CPU_MASK_NONE;
+}
+
+int fastcall ipipe_send_ipi (unsigned ipi, cpumask_t cpumask)
+
+{
+#ifdef CONFIG_SMP
+	switch (ipi) {
+
+	case IPIPE_SERVICE_IPI0:
+	case IPIPE_SERVICE_IPI1:
+	case IPIPE_SERVICE_IPI2:
+	case IPIPE_SERVICE_IPI3:
+
+		break;
+
+	default:
+
+		return -EINVAL;
+	}
+
+	return __ipipe_send_ipi(ipi,cpumask);
+#endif /* CONFIG_SMP */
+
+	return -EINVAL;
+}
+
+int ipipe_alloc_ptdkey (void)
+{
+	unsigned long flags;
+	int key = -1;
+
+	spin_lock_irqsave_hw(&__ipipe_pipelock,flags);
+
+	if (__ipipe_ptd_key_count < IPIPE_ROOT_NPTDKEYS) {
+		key = ffz(__ipipe_ptd_key_map);
+		set_bit(key,&__ipipe_ptd_key_map);
+		__ipipe_ptd_key_count++;
+	}
+
+	spin_unlock_irqrestore_hw(&__ipipe_pipelock,flags);
+
+	return key;
+}
+
+int ipipe_free_ptdkey (int key)
+{
+	unsigned long flags;
+
+	if (key < 0 || key >= IPIPE_ROOT_NPTDKEYS)
+		return -EINVAL;
+
+	spin_lock_irqsave_hw(&__ipipe_pipelock,flags);
+
+	if (test_and_clear_bit(key,&__ipipe_ptd_key_map))
+		__ipipe_ptd_key_count--;
+
+	spin_unlock_irqrestore_hw(&__ipipe_pipelock,flags);
+
+	return 0;
+}
+
+int fastcall ipipe_set_ptd (int key, void *value)
+
+{
+	if (key < 0 || key >= IPIPE_ROOT_NPTDKEYS)
+		return -EINVAL;
+
+	current->ptd[key] = value;
+
+	return 0;
+}
+
+void fastcall *ipipe_get_ptd (int key)
+
+{
+	if (key < 0 || key >= IPIPE_ROOT_NPTDKEYS)
+		return NULL;
+
+	return current->ptd[key];
+}
+
+EXPORT_SYMBOL(ipipe_register_domain);
+EXPORT_SYMBOL(ipipe_unregister_domain);
+EXPORT_SYMBOL(ipipe_free_virq);
+EXPORT_SYMBOL(ipipe_init_attr);
+EXPORT_SYMBOL(ipipe_catch_event);
+EXPORT_SYMBOL(ipipe_alloc_ptdkey);
+EXPORT_SYMBOL(ipipe_free_ptdkey);
+EXPORT_SYMBOL(ipipe_set_ptd);
+EXPORT_SYMBOL(ipipe_get_ptd);
+EXPORT_SYMBOL(ipipe_set_irq_affinity);
+EXPORT_SYMBOL(ipipe_send_ipi);
+EXPORT_SYMBOL(__ipipe_schedule_irq);
diff -uNrp linux-2.6.14.5/kernel/ipipe/Kconfig linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/Kconfig
--- linux-2.6.14.5/kernel/ipipe/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/Kconfig	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,15 @@
+config IPIPE
+	bool "Interrupt pipeline"
+	default y
+	---help---
+	  Activate this option if you want the interrupt pipeline to be
+	  compiled in.
+
+config IPIPE_STATS
+	bool "Collect statistics"
+	depends on IPIPE
+	default n
+	---help---
+	  Activate this option if you want runtime statistics to be collected
+	  while the I-pipe is operating. This option adds a small overhead, but
+	  is useful to detect unexpected latency spots.
diff -uNrp linux-2.6.14.5/kernel/ipipe/Makefile linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/Makefile
--- linux-2.6.14.5/kernel/ipipe/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ipipe/Makefile	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_IPIPE)	+= core.o generic.o
+obj-$(CONFIG_IPIPE_TRACE) += tracer.o
diff -uNrp linux-2.6.14.5/kernel/irq/handle.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/irq/handle.c
--- linux-2.6.14.5/kernel/irq/handle.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/irq/handle.c	2006-01-22 13:01:14.000000000 +0100
@@ -6,6 +6,7 @@
  * This file contains the core interrupt handling code.
  */
 
+#include <linux/ltt/ltt-facility-kernel.h>
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/random.h>
@@ -81,6 +82,19 @@ fastcall int handle_IRQ_event(unsigned i
 {
 	int ret, retval = 0, status = 0;
 
+#ifdef CONFIG_IPIPE
+	/*
+	 * If processing a timer tick, pass the original regs as
+	 * collected during preemption and not our phony - always
+	 * kernel-originated - frame, so that we don't wreck the
+	 * profiling code.
+	 */
+	if (__ipipe_tick_irq == irq)
+		regs = __ipipe_tick_regs + smp_processor_id();
+#endif /* CONFIG_IPIPE */
+
+	trace_kernel_irq_entry(irq, !(user_mode(regs)));
+
 	if (!(action->flags & SA_INTERRUPT))
 		local_irq_enable();
 
@@ -96,6 +110,8 @@ fastcall int handle_IRQ_event(unsigned i
 		add_interrupt_randomness(irq);
 	local_irq_disable();
 
+	trace_kernel_irq_exit();
+
 	return retval;
 }
 
@@ -117,14 +133,18 @@ fastcall unsigned int __do_IRQ(unsigned 
 		/*
 		 * No locking required for CPU-local interrupts:
 		 */
+#ifndef CONFIG_IPIPE
 		desc->handler->ack(irq);
+#endif /* CONFIG_IPIPE */
 		action_ret = handle_IRQ_event(irq, regs, desc->action);
 		desc->handler->end(irq);
 		return 1;
 	}
 
 	spin_lock(&desc->lock);
+#ifndef CONFIG_IPIPE
 	desc->handler->ack(irq);
+#endif /* CONFIG_IPIPE */
 	/*
 	 * REPLAY is when Linux resends an IRQ that was dropped earlier
 	 * WAITING is used by probe to mark irqs that are being tested
diff -uNrp linux-2.6.14.5/kernel/itimer.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/itimer.c
--- linux-2.6.14.5/kernel/itimer.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/itimer.c	2006-01-22 13:01:14.000000000 +0100
@@ -6,6 +6,7 @@
 
 /* These are all the functions necessary to implement itimers */
 
+#include <linux/ltt/ltt-facility-timer.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
@@ -118,6 +119,8 @@ void it_real_fn(unsigned long __data)
 	struct task_struct * p = (struct task_struct *) __data;
 	unsigned long inc = p->signal->it_real_incr;
 
+	trace_timer_expired(p->pid);
+
 	send_group_sig_info(SIGALRM, SEND_SIG_PRIV, p);
 
 	/*
@@ -143,6 +146,12 @@ int do_setitimer(int which, struct itime
  	unsigned long val, interval, expires;
 	cputime_t cval, cinterval, nval, ninterval;
 
+	trace_timer_set_itimer(which,
+			value->it_interval.tv_sec,
+			value->it_interval.tv_usec,
+			value->it_value.tv_sec,
+			value->it_value.tv_usec);
+
 	switch (which) {
 	case ITIMER_REAL:
 again:
diff -uNrp linux-2.6.14.5/kernel/ltt-base.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-base.c
--- linux-2.6.14.5/kernel/ltt-base.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-base.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * ltt-base.c
+ *
+ * (C) Copyright  2005 -
+ * 							Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the kernel core code for Linux Trace Toolkit.
+ *
+ * This base ltt file is used when LTT is configured as a module. Otherwise,
+ * ltt-core defines the ltt_log_event directly. The cost of this modularisation
+ * is a pointer to dereference in the LTT tracing critical path.
+ *
+ * Author:
+ *	Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ */
+
+#include <linux/ltt-core.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+
+/* Traces structures */
+struct ltt_traces ltt_traces = {
+	.head = LIST_HEAD_INIT(ltt_traces.head),
+	.num_active_traces = 0
+};
+
+EXPORT_SYMBOL(ltt_traces);
+
+volatile unsigned int ltt_nesting[NR_CPUS];
+
+EXPORT_SYMBOL(ltt_nesting);
+
+void __init ltt_init(void)
+{
+	unsigned int i;
+	printk(KERN_INFO "LTT : ltt-base init\n");
+
+	for(i=0;i<NR_CPUS;i++) {
+		ltt_nesting[i] = 0;
+	}
+	
+}
+
diff -uNrp linux-2.6.14.5/kernel/ltt-core.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-core.c
--- linux-2.6.14.5/kernel/ltt-core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-core.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,1421 @@
+/*
+ * ltt-core.c
+ *
+ * (C) Copyright	2005 -
+ * 							Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * (C) Copyright	1999, 2000, 2001, 2002, 2003, 2004 -
+ *							Karim Yaghmour (karim@opersys.com)
+ *
+ * Contains the kernel code for the Linux Trace Toolkit.
+ *
+ * Author:
+ *	Karim Yaghmour (karim@opersys.com)
+ *	Tom Zanussi (zanussi@us.ibm.com)
+ *	Bob Wisniewski (bob@watson.ibm.com)
+ *	Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Changelog:
+ *  19/10/05, Complete lockless mechanism. (Mathieu Desnoyers)
+ *	27/05/05, Modular redesign and rewrite. (Mathieu Desnoyers)
+ *	14/12/04, Renamed trace macros and variables to avoid namespace
+ *		pollution (i.e. TRACE_XXX is now ltt_ev_xxx, etc.)
+ *	24/01/04, Revamped tracer to rely entirely on relayfs, no sys_trace.
+ *		Renamed all relevant files and functions from trace* to ltt*.
+ *	14/03/03, Modified to use relayfs (zanussi@us.ibm.com)
+ *	15/10/02, Changed tracer from device to kernel subsystem and added
+ *		custom trace system call (sys_trace).
+ *	01/10/02, Coding style change to fit with kernel coding style.
+ *	16/02/02, Added Tom Zanussi's implementation of K42's lockless logging.
+ *		K42 tracing guru Robert Wisniewski participated in the
+ *		discussions surrounding this implementation. A big thanks to
+ *		the IBM folks.
+ *	03/12/01, Added user event support.
+ *	05/01/01, Modified PPC bit manipulation functions for x86
+ *		compatibility (andy_lowe@mvista.com).
+ *	15/11/00, Finally fixed memory allocation and remapping method. Now
+ *		using BTTV-driver-inspired code.
+ *	13/03/00, Modified tracer so that the daemon mmaps the tracer's buffers
+ *		in it's address space rather than use "read".
+ *	26/01/00, Added support for standardized buffer sizes and extensibility
+ *		of events.
+ *	01/10/99, Modified tracer in order to used double-buffering.
+ *	28/09/99, Adding tracer configuration support.
+ *	09/09/99, Changing the format of an event record in order to reduce the
+ *		size of the traces.
+ *	04/03/99, Initial typing.
+ *
+ * Comments :
+ * num_active_traces protects the functors. Changing the pointer is an atomic
+ * operation, but the functions can only be called when in tracing. It is then
+ * safe to unload a module in which sits a functor when no tracing is active.
+ *
+ * filter_control functor is protected by incrementing its module refcount.
+ *
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/time.h>
+#include <linux/ltt-core.h>
+#include <linux/relayfs_fs.h>
+#include <linux/ltt-time.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ltt-facilities.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <asm/timer.h>
+
+static struct dentry *ltt_root_dentry;
+
+#ifdef CONFIG_IPIPE
+extern struct list_head relay_wakeup_queue;
+extern unsigned relay_wakeup_virq;
+extern spinlock_t relay_wakeup_spinlock;
+#endif /* CONFIG_IPIPE */
+
+/* How a force_switch must be done ? 
+ *
+ * Is it done during tracing or as a final flush after tracing (so it won't
+ * write in the new sub-buffer).
+ */
+enum force_switch_mode { FORCE_ACTIVE, FORCE_FLUSH };
+
+/* Traces list writer locking */
+DECLARE_MUTEX(ltt_traces_sem);
+
+/* Default callbacks for modules */
+int ltt_run_filter_default(void)
+{
+	return 1;
+}
+
+int ltt_filter_control_default
+	(enum ltt_filter_control_msg msg, struct ltt_trace_struct *trace)
+{
+	return 0;
+}
+
+int ltt_heartbeat_default(enum ltt_heartbeat_functor_msg msg)
+{
+	return 0;
+}
+
+int ltt_statedump_default(struct ltt_trace_struct *trace)
+{
+	return 0;
+}
+
+
+
+/* Callbacks for registered modules */
+
+int (*ltt_filter_control_functor)
+	(enum ltt_filter_control_msg msg, struct ltt_trace_struct *trace) =
+					ltt_filter_control_default;
+struct module *ltt_filter_control_owner = NULL;
+
+/* These function pointers are protected by trace activation check */
+					
+int (*ltt_run_filter_functor)(void) = ltt_run_filter_default;
+struct module *ltt_run_filter_owner = NULL;
+
+// FIXME : integrate the filter in the logging chain.
+int (*ltt_heartbeat_functor)(enum ltt_heartbeat_functor_msg msg) =
+					ltt_heartbeat_default;
+struct module *ltt_heartbeat_owner = NULL;
+
+int (*ltt_statedump_functor)(struct ltt_trace_struct *trace) = 
+					ltt_statedump_default;
+struct module *ltt_statedump_owner = NULL;
+					
+/* Module registration methods */
+
+int ltt_module_register(enum ltt_module_function name, void *function,
+		struct module *owner)
+{
+	int ret = 0;
+	
+	/* Protect these operations by disallowing them when tracing is active */
+	if(ltt_traces.num_active_traces) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	switch(name) {
+		case LTT_FUNCTION_RUN_FILTER:
+			if(ltt_run_filter_owner != NULL) {
+				ret = -EEXIST;
+				goto end;
+			}
+			ltt_run_filter_functor = (int (*)(void))function;
+			ltt_run_filter_owner = owner;
+			break;
+		case LTT_FUNCTION_FILTER_CONTROL:
+			if(ltt_filter_control_owner != NULL) {
+				ret = -EEXIST;
+				goto end;
+			}
+			ltt_filter_control_functor = 
+		(int (*)(enum ltt_filter_control_msg, struct ltt_trace_struct *))function;
+			break;
+		case LTT_FUNCTION_HEARTBEAT:
+			if(ltt_heartbeat_owner != NULL) {
+				ret = -EEXIST;
+				goto end;
+			}
+			ltt_heartbeat_functor = 
+				(int (*)(enum ltt_heartbeat_functor_msg))function;
+			ltt_heartbeat_owner = owner;
+			break;
+		case LTT_FUNCTION_STATEDUMP:
+			if(ltt_statedump_owner != NULL) {
+				ret = -EEXIST;
+				goto end;
+			}
+			ltt_statedump_functor = (int (*)(struct ltt_trace_struct *))function;
+			ltt_statedump_owner = owner;
+			break;
+	}
+
+end:
+
+	return ret;
+}
+
+
+void ltt_module_unregister(enum ltt_module_function name)
+{
+	/* It should NEVER happen : modules has their reference count incremented when
+	 * tracing is active. */
+	BUG_ON(ltt_traces.num_active_traces);
+
+	switch(name) {
+		case LTT_FUNCTION_RUN_FILTER:
+			ltt_run_filter_functor = ltt_run_filter_default;
+			ltt_run_filter_owner = NULL;
+			break;
+		case LTT_FUNCTION_FILTER_CONTROL:
+			ltt_filter_control_functor = ltt_filter_control_default;
+			break;
+		case LTT_FUNCTION_HEARTBEAT:
+			ltt_heartbeat_functor = ltt_heartbeat_default;
+			ltt_heartbeat_owner = NULL;
+			break;
+		case LTT_FUNCTION_STATEDUMP:
+			ltt_statedump_functor = ltt_statedump_default;
+			ltt_statedump_owner = NULL;
+			break;
+	}
+
+}
+
+EXPORT_SYMBOL_GPL(ltt_module_register);
+EXPORT_SYMBOL_GPL(ltt_module_unregister);
+
+static void ltt_write_trace_header(struct ltt_trace_struct *trace,
+		struct ltt_trace_header *header)
+{
+	header->magic_number = LTT_TRACER_MAGIC_NUMBER;
+	header->major_version = LTT_TRACER_VERSION_MAJOR;
+	header->minor_version = LTT_TRACER_VERSION_MINOR;
+	header->float_word_order = 0;	 /* Kernel : no floating point */
+	header->arch_type = LTT_ARCH_TYPE;
+	header->arch_size = sizeof(void*);
+	header->arch_variant = LTT_ARCH_VARIANT;
+	header->flight_recorder = (trace->mode == LTT_TRACE_FLIGHT);
+#ifdef CONFIG_LTT_HEARTBEAT
+	header->has_heartbeat = 1;
+#else
+	header->has_heartbeat = 0;
+#endif //CONFIG_LTT_HEARTBEAT
+
+#ifdef CONFIG_LTT_ALIGNMENT
+	header->has_alignment = sizeof(void*);
+#else
+	header->has_alignment = 0;
+#endif
+	
+	header->has_tsc = trace->has_tsc;
+	header->start_freq = trace->start_freq;
+	header->start_tsc = trace->start_tsc;
+	header->start_monotonic = trace->start_monotonic;
+	header->start_time_sec = trace->start_time.tv_sec;
+	header->start_time_usec = trace->start_time.tv_usec;
+}
+
+
+/* Trace callbacks */
+
+
+static unsigned int ltt_subbuf_header_len_callback(struct rchan_buf *buf)
+{
+	return sizeof(struct ltt_block_start_header);
+}
+
+
+static void ltt_buffer_begin_callback(struct rchan_buf *buf,
+		      cycles_t tsc, unsigned int subbuf_idx)
+{
+	struct ltt_channel_struct *channel = 
+				(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_block_start_header *header = 
+					(struct ltt_block_start_header*)
+						(buf->start + (subbuf_idx*buf->chan->subbuf_size));
+	
+	header->begin.cycle_count = (u64)tsc;
+	header->begin.freq = (u64)cpu_khz;
+
+	header->lost_size = 0xFFFFFFFF; // for debugging...
+	
+	header->buf_size = buf->chan->subbuf_size;
+	
+	ltt_write_trace_header(channel->trace, &header->trace);
+
+}
+#if 0
+	if(!channel->trace->has_tsc) {
+		do_gettimeofday(&channel->current_subbuffer_start_time[buf->cpu]);
+		header->begin.timestamp_sec = channel->current_subbuffer_start_time[buf->cpu].tv_sec;
+		header->begin.timestamp_usec = channel->current_subbuffer_start_time[buf->cpu].tv_usec;
+	} else {
+		header->begin.timestamp_sec = 0;
+		header->begin.timestamp_usec = 0;
+	}
+#endif //0
+
+
+static void ltt_buffer_end_callback(struct rchan_buf *buf,
+		      cycles_t tsc, unsigned int offset, unsigned int subbuf_idx)
+{
+	struct ltt_block_start_header *header = 
+						(struct ltt_block_start_header*)
+								(buf->start + (subbuf_idx*buf->chan->subbuf_size));
+  /* offset is assumed to never be 0 here : never deliver a completely
+   * empty subbuffer. */
+  /* The lost size is between 0 and subbuf_size-1 */
+	header->lost_size = SUBBUF_OFFSET((buf->chan->subbuf_size - offset),
+																		buf->chan);
+	header->end.cycle_count = (u64)tsc;
+	header->end.freq = (u64)cpu_khz;
+}
+
+#if 0
+	if(!channel->trace->has_tsc) {
+		do_gettimeofday(&timestamp);
+		header->end.timestamp_sec = timestamp.tv_sec;
+		header->end.timestamp_usec = timestamp.tv_usec;
+	} else {
+		header->end.timestamp_sec = 0;
+		header->end.timestamp_usec = 0;
+	}
+#endif //0
+
+static void wakeup_readers(void *private)
+{
+	struct rchan_buf *buf = private;
+	wake_up_interruptible(&buf->read_wait);
+}
+
+static void ltt_deliver_callback(struct rchan_buf *buf,
+		unsigned subbuf_idx,
+		void *subbuf)
+{
+  if (waitqueue_active(&buf->read_wait)) {
+#ifdef CONFIG_IPIPE
+    if (ipipe_current_domain != ipipe_root_domain) {
+      if (!test_and_set_bit(0,&buf->wake_posted)) {
+	unsigned long flags;
+	spin_lock_irqsave_hw(&relay_wakeup_spinlock,flags);
+	list_add_tail(&buf->wake_link,&relay_wakeup_queue);
+	spin_unlock_irqrestore_hw(&relay_wakeup_spinlock,flags);
+	ipipe_propagate_irq(relay_wakeup_virq);
+      }
+      return;
+    }
+#endif /* CONFIG_IPIPE */
+    PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf);
+    schedule_delayed_work(&buf->wake_readers, 1);
+  }
+}
+
+static void ltt_buf_mapped_callback(struct rchan_buf *buf,
+		struct file *filp)
+{
+	//printk(KERN_ALERT "ltt_buf_mapped_callback, buf %p, filp %p\n", buf, filp);
+}
+
+static void ltt_buf_unmapped_callback(struct rchan_buf *buf,
+		struct file *filp)
+{
+	//printk(KERN_ALERT "ltt_buf_unmapped_callback, buf %p, filp %p\n",
+	//									buf, filp);
+}
+
+static void ltt_buf_full_callback(struct rchan_buf *buf,
+		unsigned subbuf_idx,
+		void *subbuf)
+{
+	//printk(KERN_ALERT "ltt_buf_full_callback, buf %p, subbuf_idx %u, subbuf %p\n",
+	//									buf, subbuf_idx, subbuf);
+}
+
+static void ltt_buf_unfull_callback(struct rchan_buf *buf,
+		unsigned subbuf_idx,
+		void *subbuf)
+{
+	//printk(KERN_ALERT
+	//		"ltt_buf_unfull_callback, buf %p, subbuf_idx %u, subbuf %p\n",
+	//		buf, subbuf_idx, subbuf);
+}
+
+/* _ltt_trace_find :
+ * find a trace by given name.
+ *
+ * Returns a pointer to the trace structure, NULL if not found. */
+static struct ltt_trace_struct *_ltt_trace_find(char *trace_name)
+{
+	int compare;
+	struct ltt_trace_struct *trace, *found=NULL;
+	
+	list_for_each_entry(trace, &ltt_traces.head, list) {
+		compare = strncmp(trace->trace_name, trace_name, NAME_MAX);
+
+		if(compare == 0) {
+			found = trace;
+			break;
+		}
+	}
+	
+	return found;
+}
+
+/* This function must be called with traces semaphore held. */
+static int _ltt_trace_create(char *trace_name,	enum trace_mode mode,
+														unsigned subbuf_size, unsigned n_subbufs,
+														struct ltt_trace_struct *new_trace)
+{
+	int err = EPERM;
+
+	if(_ltt_trace_find(trace_name) != NULL) {
+		printk(KERN_ERR "LTT : Trace %s already exists\n",
+										trace_name);
+		err = EEXIST;
+		goto traces_error;
+	}
+
+	list_add_rcu(&new_trace->list, &ltt_traces.head);
+	synchronize_rcu();
+	
+	/* Everything went fine, finish creation */
+
+	return 0;
+
+
+	/* Error handling */
+traces_error:
+
+	return err;
+}
+
+
+
+/**
+ *	ltt_poll - poll file op for ltt files
+ *	@filp: the file
+ *	@wait: poll table
+ *
+ *	Poll implemention.
+ */
+unsigned int ltt_poll(struct file *filp, poll_table *wait)
+{
+	unsigned int mask = 0;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+	struct ltt_channel_struct *ltt_channel =
+		(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_channel_buf_struct *ltt_buf = &ltt_channel->buf[buf->cpu];
+
+	printk(KERN_DEBUG "DEBUG : in LTT poll %p\n", filp);
+	if (filp->f_mode & FMODE_READ) {
+		poll_wait(filp, &buf->read_wait, wait);
+
+		if(SUBBUF_TRUNC(ltt_buf->offset, buf->chan) 
+				- SUBBUF_TRUNC(ltt_buf->consumed, buf->chan) == 0) {
+			if(buf->finalized)
+				return POLLHUP;
+			else
+				return 0;
+		} else {
+			if(SUBBUF_TRUNC(ltt_buf->offset, buf->chan)
+					- SUBBUF_TRUNC(ltt_buf->consumed, buf->chan)
+							>= ltt_channel->rchan->alloc_size)
+				return POLLPRI | POLLRDBAND;
+			else
+				return POLLIN | POLLRDNORM;
+		}
+	}
+
+	return mask;
+}
+
+
+/**
+ *	ltt_ioctl - ioctl control on the relayfs file
+ *
+ *	@inode: the inode
+ *	@filp: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements three commands necessary for a minimal
+ *	producer/consumer implementation :
+ *	RELAYFS_GET_SUBBUF
+ *		Get the next sub buffer that can be read. It never blocks.
+ *	RELAYFS_PUT_SUBBUF
+ *		Release the currently read sub-buffer. Parameter is the last
+ *		put subbuffer (returned by GET_SUBBUF).
+ *	RELAYFS_GET_N_BUBBUFS
+ *		returns the number of sub buffers in the per cpu channel.
+ *	RELAYFS_GET_SUBBUF_SIZE
+ *		returns the size of the sub buffers.
+ *
+ */
+int ltt_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+  struct ltt_channel_struct *ltt_channel =
+            (struct ltt_channel_struct*)buf->chan->client_data;
+  struct ltt_channel_buf_struct *ltt_buf = &ltt_channel->buf[buf->cpu];
+
+	u32 __user    *argp = (u32 __user *)arg;
+
+	switch(cmd) {
+		case RELAYFS_GET_SUBBUF:
+			{
+				unsigned int consumed_old = ltt_buf->consumed;
+				unsigned int consumed_idx =
+					SUBBUF_INDEX(consumed_old, buf->chan);
+				if(atomic_read(&ltt_buf->commit_count[consumed_idx])
+							!= atomic_read(&ltt_buf->reserve_count[consumed_idx]))
+					return -EAGAIN;
+				if((SUBBUF_TRUNC(ltt_buf->offset, buf->chan)
+							- SUBBUF_TRUNC(consumed_old, buf->chan))
+									== 0)
+					return -EAGAIN;
+				printk(KERN_DEBUG "LTT ioctl get subbuf %d\n", consumed_old);
+				return put_user((u32)consumed_old, argp);
+			}
+			break;
+		case RELAYFS_PUT_SUBBUF:
+			{
+				u32 consumed_old;
+				int ret;
+				unsigned int consumed_new;
+
+				ret = get_user(consumed_old, argp);
+				if(ret) return ret; /* will return -EFAULT */
+
+				printk(KERN_DEBUG "LTT ioctl put subbuf %d\n", consumed_old);
+				consumed_new = SUBBUF_ALIGN(consumed_old, buf->chan);
+				if(cmpxchg(&ltt_buf->consumed, consumed_old, consumed_new)
+										!= consumed_old) {
+					/* We have been pushed by the writer : the last buffer read _is_
+					 * corrupted!
+					 * It can also happen if this is a buffer we never got. */
+					return -EIO;
+				} else {
+					if(unlikely(atomic_read(&buf->full))) {
+						/* tell the client that buffer is now unfull */
+						int index;
+						void *data;
+						index = SUBBUF_INDEX(consumed_old, buf->chan);
+						data = buf->start + BUFFER_OFFSET(consumed_old, buf->chan);
+						
+						buf->chan->cb->buf_unfull(buf, index, data);
+						atomic_set(&buf->full, 0);
+					}
+				}
+			}
+			break;
+		case RELAYFS_GET_N_SUBBUFS:
+				printk(KERN_DEBUG "LTT ioctl get n subbufs\n");
+			return put_user((u32)buf->chan->n_subbufs, argp);
+			break;
+		case RELAYFS_GET_SUBBUF_SIZE:
+				printk(KERN_DEBUG "LTT ioctl get subbuf size\n");
+			return put_user((u32)buf->chan->subbuf_size, argp);
+			break;
+		default:
+			return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void print_channel_errors(struct ltt_channel_struct *ltt_chan)
+{
+	unsigned int i;
+	int cons_off, cons_idx;
+
+	for(i=0;i<NR_CPUS;i++) {
+		if(atomic_read(&ltt_chan->buf[i].events_lost))
+			printk(KERN_ALERT 
+				"LTT : %s : %d events lost in %s channel (cpu %u).\n",
+				ltt_chan->channel_name,
+				atomic_read(&ltt_chan->buf[i].events_lost),
+				ltt_chan->channel_name, i);
+		if(atomic_read(&ltt_chan->buf[i].corrupted_subbuffers))
+			printk(KERN_ALERT 
+				"LTT : %s : %d corrupted subbuffers in %s channel (cpu %u).\n",
+				ltt_chan->channel_name,
+				atomic_read(&ltt_chan->buf[i].corrupted_subbuffers),
+				ltt_chan->channel_name, i);
+		for(cons_off = ltt_chan->buf[i].consumed;
+				(SUBBUF_TRUNC(ltt_chan->buf[i].offset, ltt_chan->rchan) - cons_off) > 0;
+				cons_off = SUBBUF_ALIGN(cons_off, ltt_chan->rchan)) {
+			printk(KERN_WARNING "LTT : unread channel %s offset is %d and cons_off : %d (cpu %u)\n",
+					ltt_chan->channel_name, 
+					ltt_chan->buf[i].offset, cons_off, i);
+			/* Check each sub-buffer for unequal reserve and commit count */
+			cons_idx = SUBBUF_INDEX(cons_off, ltt_chan->rchan);
+			if(atomic_read(&ltt_chan->buf[i].reserve_count[cons_idx])
+					!= atomic_read(&ltt_chan->buf[i].commit_count[cons_idx]))
+				printk(KERN_ALERT
+			"LTT : %s : subbuffer %u has unequal reserve and commit counts.\n",
+			ltt_chan->channel_name, cons_idx);
+			printk("LTT : %s : reserve count : %u, commit count : %u\n",
+					ltt_chan->channel_name,
+					atomic_read(&ltt_chan->buf[i].reserve_count[cons_idx]),
+					atomic_read(&ltt_chan->buf[i].commit_count[cons_idx]));
+		}
+	}
+}
+
+
+static void ltt_channel_destroy(void *object)
+{
+	struct ltt_channel_struct *ltt_chan = (struct ltt_channel_struct *)object;
+	unsigned int i;
+
+	/* Note : we check that every channel has equal reserve/commit count. It's
+	 * ok if reserve and commit are surrounded by disable_preempt (see
+	 * synchronize_rcu()), but it won't be the case for user space tracing... be
+	 * warned. FIXME */
+	print_channel_errors(ltt_chan);
+
+	for(i=0;i<NR_CPUS;i++) {
+		kfree(ltt_chan->buf[i].reserve_count);
+		kfree(ltt_chan->buf[i].commit_count);
+	}
+	kfree(ltt_chan);
+}
+
+
+
+/* Create channel.
+ *
+ */
+static int ltt_channel_create(char *trace_name,
+		struct ltt_trace_struct *trace,
+		struct dentry *dir,
+		char *channel_name,
+		struct ltt_channel_struct **ltt_chan,
+		unsigned int subbuf_size, unsigned int n_subbufs,
+		int overwrite)
+{
+	unsigned int i, j;
+
+	/* This channel info will be freed by relayfs if the relay_open succeed. */
+	*ltt_chan = kmalloc(sizeof(struct ltt_channel_struct), GFP_KERNEL);
+
+	(*ltt_chan)->trace = trace;
+	(*ltt_chan)->rchan = relay_open(channel_name,
+			dir,
+			subbuf_size,
+			n_subbufs,
+			overwrite,
+			THIS_MODULE,
+			&trace->callbacks,
+			&trace->fops,
+			*ltt_chan,
+			ltt_channel_destroy);
+
+	if((*ltt_chan)->rchan == NULL) {
+		printk(KERN_ERR "LTT : Can't open %s channel for trace %s\n",
+											channel_name, trace_name);
+		goto error;
+	}
+	
+	(*ltt_chan)->subbuf_header_len =
+					ltt_subbuf_header_len_callback;
+	(*ltt_chan)->buffer_begin = ltt_buffer_begin_callback;
+	(*ltt_chan)->buffer_end = ltt_buffer_end_callback;
+	
+	strncpy((*ltt_chan)->channel_name, channel_name, PATH_MAX);
+	
+	for(i=0;i<NR_CPUS;i++) {
+		(*ltt_chan)->buf[i].offset =
+			ltt_subbuf_header_len_callback(
+					(*ltt_chan)->rchan->buf[i]);
+		(*ltt_chan)->buf[i].consumed = 0;
+		(*ltt_chan)->buf[i].reserve_count = 
+			kmalloc(sizeof(atomic_t) * n_subbufs, GFP_KERNEL);
+		for(j=0; j<n_subbufs; j++)
+			atomic_set(&(*ltt_chan)->buf[i].reserve_count[j], 0);
+		(*ltt_chan)->buf[i].commit_count = 
+			kmalloc(sizeof(atomic_t) * n_subbufs, GFP_KERNEL);
+		for(j=0; j<n_subbufs; j++)
+			atomic_set(&(*ltt_chan)->buf[i].commit_count[j], 0);
+		/* Tracing not started yet : we don't deal with concurrency (no delivery) */
+		if(!(*ltt_chan)->rchan->buf[i])
+			continue;
+
+		ltt_buffer_begin_callback((*ltt_chan)->rchan->buf[i], trace->start_tsc, 0);
+		atomic_add((*ltt_chan)->subbuf_header_len((*ltt_chan)->rchan->buf[i]),
+				 &(*ltt_chan)->buf[i].commit_count[0]);
+	}
+
+	return 0;
+error:
+	ltt_channel_destroy(*ltt_chan);
+
+	return EPERM;
+}
+			
+
+static void init_error_count(struct ltt_channel_struct *ltt_chan)
+{	
+	unsigned int i;
+	for(i=0;i<NR_CPUS;i++) {
+		atomic_set(&ltt_chan->buf[i].events_lost, 0);
+		atomic_set(&ltt_chan->buf[i].corrupted_subbuffers, 0);
+	}
+}
+
+static int ltt_trace_create(char *trace_name,enum trace_mode mode,
+			    unsigned subbuf_size, unsigned n_subbufs)
+{
+	int overwrite;
+	int err = 0;
+	struct ltt_trace_struct *new_trace;
+	unsigned long flags;
+	unsigned int subbuf_size_align;
+	struct timeval now;
+	u64 tsc = 0;
+	
+	if(subbuf_size == 0) subbuf_size = LTT_DEFAULT_SUBBUF_SIZE;
+	if(n_subbufs == 0) n_subbufs = LTT_DEFAULT_N_SUBBUFS;
+
+	subbuf_size_align = (subbuf_size + PAGE_SIZE-1)&PAGE_MASK;
+
+	/* Subbuf size and number must both be power of two */
+	if(hweight32(subbuf_size_align) != 1) return EINVAL;
+	if(hweight32(n_subbufs) != 1) return EINVAL;
+	
+	/* We must do a dynamic test because of buggy i386 */
+	get_time_or_tsc(&now, &tsc);
+	if(!tsc) {
+		printk(KERN_WARNING "Your computer does not seem to have TSC : LTTng "
+												"only accepts TSC capable machines.\n");
+		return EINVAL; /* We only accept TSC capable machines. */
+	}
+
+	new_trace = kcalloc(1, sizeof(struct ltt_trace_struct), GFP_KERNEL);
+	if(!new_trace) {
+		printk(KERN_ERR "LTT : Unable to allocate memory for trace %s\n",
+										trace_name);
+		err = ENOMEM;
+		goto traces_error;
+	}
+
+	new_trace->dentry.trace_root = relayfs_create_dir(trace_name,
+			ltt_root_dentry);
+	if(new_trace->dentry.trace_root == NULL) {
+		printk(KERN_ERR "LTT : Trace directory name %s already taken\n",
+										trace_name);
+		err = EEXIST;
+		goto trace_error;
+	}
+
+	new_trace->dentry.control_root = relayfs_create_dir(LTT_CONTROL_ROOT,
+			new_trace->dentry.trace_root);
+	if(new_trace->dentry.control_root == NULL) {
+		printk(KERN_ERR "LTT : Trace control subdirectory name "\
+										"%s/%s already taken\n",
+										trace_name, LTT_CONTROL_ROOT);
+		err = EEXIST;
+		goto control_error;
+	}
+
+	new_trace->active = 0;
+	strncpy(new_trace->trace_name, trace_name, NAME_MAX);
+	new_trace->paused = 0;
+	new_trace->mode = mode;
+	if(tsc) new_trace->has_tsc = 1;
+	else new_trace->has_tsc = 0;
+
+	/* Allocate the relayfs channels */
+
+	switch(mode) {
+		case LTT_TRACE_NORMAL:
+			overwrite = 0;
+			break;
+		case LTT_TRACE_FLIGHT:
+			overwrite = 1;
+			break;
+		default:
+			overwrite = 0;
+	}
+	
+	local_irq_save_hw(flags);
+	new_trace->start_freq = cpu_khz;
+	new_trace->start_tsc = get_cycles();
+	//new_trace->start_monotonic = cur_timer->monotonic_clock();
+	//getnstimeofday(&new_trace->start_time);
+	do_gettimeofday(&new_trace->start_time);
+	local_irq_restore_hw(flags);
+	
+	//new_trace->callbacks.subbuf_start = ltt_subbuf_start_callback;
+	new_trace->callbacks.deliver = ltt_deliver_callback;
+	new_trace->callbacks.buf_mapped = ltt_buf_mapped_callback;
+	new_trace->callbacks.buf_unmapped = ltt_buf_unmapped_callback;
+	new_trace->callbacks.buf_full = ltt_buf_full_callback;
+	new_trace->callbacks.buf_unfull = ltt_buf_unfull_callback;
+	
+	new_trace->fops.poll = ltt_poll;
+	new_trace->fops.ioctl = ltt_ioctl;
+	
+	/* Always put the facilities channel in non-overwrite mode :
+	 * This is a very low traffic channel and it can't afford to have its data
+	 * overwritten : this data (facilities info) is necessary to be able to read
+	 * the trace.
+	 *
+	 * WARNING : The heartbeat time _shouldn't_ write events in the facilities
+	 * channel as it would make the traffic too high. On the other hand, if
+	 * LTTng is configured in heartbeat mode, a heartbeat event should be
+	 * written just before every facility event.
+	 */
+	
+	err = ltt_channel_create(trace_name, new_trace,
+			new_trace->dentry.control_root, LTT_FACILITIES_CHANNEL,
+			&new_trace->channel.facilities, subbuf_size_align, n_subbufs,
+			0);
+	if(err != 0) {
+		goto facilities_error;
+	}
+	err = ltt_channel_create(trace_name, new_trace,
+			new_trace->dentry.control_root, LTT_INTERRUPTS_CHANNEL,
+			&new_trace->channel.interrupts, subbuf_size_align, n_subbufs,
+			overwrite);
+	if(err != 0) {
+		goto interrupts_error;
+	}
+	err = ltt_channel_create(trace_name, new_trace,
+			new_trace->dentry.control_root, LTT_PROCESSES_CHANNEL,
+			&new_trace->channel.processes, subbuf_size_align, n_subbufs,
+			overwrite);
+	if(err != 0) {
+		goto processes_error;
+	}
+	err = ltt_channel_create(trace_name, new_trace,
+			new_trace->dentry.control_root, LTT_MODULES_CHANNEL,
+			&new_trace->channel.modules, subbuf_size_align, n_subbufs,
+			overwrite);
+	if(err != 0) {
+		goto modules_error;
+	}
+	err = ltt_channel_create(trace_name, new_trace,
+			new_trace->dentry.trace_root, LTT_CPU_CHANNEL,
+			&new_trace->channel.cpu, subbuf_size_align, n_subbufs,
+			overwrite);
+	if(err != 0) {
+		goto cpu_error;
+	}
+	
+	init_error_count(new_trace->channel.facilities);
+	init_error_count(new_trace->channel.interrupts);
+	init_error_count(new_trace->channel.processes);
+	init_error_count(new_trace->channel.modules);
+	init_error_count(new_trace->channel.cpu);
+
+	down(&ltt_traces_sem);
+
+	err = _ltt_trace_create(trace_name, mode, subbuf_size_align, n_subbufs,
+														new_trace);
+
+	up(&ltt_traces_sem);
+	
+	if(err != 0)
+		goto lock_create_error;
+ 
+	return err;
+
+lock_create_error:
+	relay_close(new_trace->channel.cpu->rchan);
+cpu_error:
+	relay_close(new_trace->channel.modules->rchan);
+modules_error:
+	relay_close(new_trace->channel.processes->rchan);
+processes_error:
+	relay_close(new_trace->channel.interrupts->rchan);
+interrupts_error:
+	relay_close(new_trace->channel.facilities->rchan);
+facilities_error:
+	relayfs_remove_dir(new_trace->dentry.control_root);
+control_error:
+	relayfs_remove_dir(new_trace->dentry.trace_root);
+trace_error:
+	kfree(new_trace);
+traces_error:
+
+	return err;
+}
+
+
+/* Must be called while sure that trace is in the list. */
+static int _ltt_trace_destroy(struct ltt_trace_struct	*trace)
+{
+	int err = EPERM;
+	
+	if(trace == NULL) {
+		err = ENOENT;
+		goto traces_error;
+	}
+	
+	if(trace->active) {
+			printk(KERN_ERR "LTT : Can't destroy trace %s : tracer is active\n",
+					trace->trace_name);
+		err = EBUSY;
+		goto active_error;
+	}
+
+	/* Everything went fine */
+	list_del_rcu(&trace->list);
+	synchronize_rcu();
+
+	/* If no more trace in the list, we can free the unused facilities */
+	if(list_empty(&ltt_traces.head))
+		ltt_facility_free_unused();
+
+	return 0;
+
+	/* error handling */
+active_error:
+traces_error:
+
+	return err;
+}
+
+/* Force a sub-buffer switch for a per-cpu buffer. This operation is
+ * completely reentrant : can be called while tracing is active with
+ * absolutely no lock held.
+ */
+static void ltt_force_switch(struct rchan_buf *buf, enum force_switch_mode mode)
+{
+	struct ltt_channel_struct *ltt_channel = 
+						(struct ltt_channel_struct*)buf->chan->client_data;
+	struct ltt_channel_buf_struct *ltt_buf = &ltt_channel->buf[buf->cpu];
+
+	cycles_t tsc;
+	int offset_begin, offset_end, offset_old;
+	int reserve_commit_diff;
+	int consumed_old, consumed_new;
+	int commit_count, reserve_count;
+	int end_switch_old;
+
+	do {
+		offset_old = ltt_buf->offset;
+		offset_begin = offset_old;
+		tsc = get_cycles();
+		end_switch_old = 0;
+
+		if(SUBBUF_OFFSET(offset_begin, buf->chan) != 0) {
+			offset_begin = SUBBUF_ALIGN(offset_begin, buf->chan);
+			end_switch_old = 1;
+		} else {
+      /* we do not have to switch : buffer is empty */
+      return;
+    }
+		if(mode == FORCE_ACTIVE)
+			offset_begin += ltt_channel->subbuf_header_len(buf);
+		/* Always begin_switch in FORCE_ACTIVE mode */
+
+		/* Test new buffer integrity */
+		reserve_commit_diff = 
+			atomic_read(
+				&ltt_buf->reserve_count[SUBBUF_INDEX(offset_begin, buf->chan)])
+			- atomic_read(
+					&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin, buf->chan)]);
+		if(reserve_commit_diff == 0) {
+      /* Next buffer not corrupted. */ 
+      if(mode == FORCE_ACTIVE && !buf->chan->overwrite 
+				&& (offset_begin-ltt_buf->consumed) >= ltt_channel->rchan->alloc_size) {
+      	/* We do not overwrite non consumed buffers and we are full : ignore
+        	 switch while tracing is active. */ 
+        return;
+      }   
+    } else { 
+      /* Next subbuffer corrupted. Force pushing reader even in normal mode */
+    }
+			
+		offset_end = offset_begin;
+	} while(cmpxchg(&ltt_buf->offset, offset_old, offset_end) != offset_old);
+
+
+	if(mode == FORCE_ACTIVE) {
+		/* Push the reader if necessary */
+		do {
+			consumed_old = ltt_buf->consumed;
+			/* If buffer is in overwrite mode, push the reader consumed count if
+				 the write position has reached it and we are not at the first
+				 iteration (don't push the reader farther than the writer). 
+				 This operation can be done concurrently by many writers in the
+				 same buffer, the writer being at the fartest write position sub-buffer
+				 index in the buffer being the one which will win this loop. */
+			/* If the buffer is not in overwrite mode, pushing the reader only
+				 happen if a sub-buffer is corrupted */
+			if((SUBBUF_TRUNC(offset_end, buf->chan) 
+					- SUBBUF_TRUNC(consumed_old, buf->chan)) 
+							>= ltt_channel->rchan->alloc_size)
+				consumed_new = SUBBUF_ALIGN(consumed_old, buf->chan);
+			else {
+				consumed_new = consumed_old;
+				break;
+			}
+		} while(cmpxchg(&ltt_buf->consumed, consumed_old, consumed_new)
+				!= consumed_old);
+
+		if(consumed_old != consumed_new) {
+			/* Reader pushed : we are the winner of the push, we can therefore
+				 reequilibrate reserve and commit. Atomic increment of the commit
+				 count permits other writers to play around with this variable
+				 before us. We keep track of corrupted_subbuffers even in overwrite
+				 mode :
+				 we never want to write over a non completely committed sub-buffer : 
+				 possible causes : the buffer size is too low compared to the unordered
+				 data input, or there is a writer who died between the reserve and the
+				 commit. */
+			if(reserve_commit_diff) {
+				/* We have to alter the sub-buffer commit count : a sub-buffer is
+					 corrupted */
+				atomic_add(reserve_commit_diff,
+								&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin, buf->chan)]);
+				atomic_inc(&ltt_buf->corrupted_subbuffers);
+			}
+		}
+	}
+
+	/* Always switch */
+
+	if(end_switch_old) {
+		/* old subbuffer */
+		/* Concurrency safe because we are the last and only thread to alter this
+			 sub-buffer. As long as it is not delivered and read, no other thread can
+			 alter the offset, alter the reserve_count or call the
+			 client_buffer_end_callback on this sub-buffer.
+			 The only remaining threads could be the ones with pending commits. They
+			 will have to do the deliver themself.
+			 Not concurrency safe in overwrite mode. We detect corrupted subbuffers with
+			 commit and reserve counts. We keep a corrupted sub-buffers count and push
+			 the readers across these sub-buffers.
+			 Not concurrency safe if a writer is stalled in a subbuffer and
+			 another writer switches in, finding out it's corrupted. The result will be
+			 than the old (uncommited) subbuffer will be declared corrupted, and that
+			 the new subbuffer will be declared corrupted too because of the commit
+			 count adjustment.
+			 Offset old should never be 0. */
+		ltt_channel->buffer_end(buf, tsc, offset_old,
+				SUBBUF_INDEX((offset_old), buf->chan));
+		/* Setting this reserve_count will allow the sub-buffer to be delivered by
+			 the last committer. */
+		reserve_count = atomic_add_return((SUBBUF_OFFSET((offset_old-1),
+                                                      buf->chan) + 1),
+										&ltt_buf->reserve_count[SUBBUF_INDEX((offset_old),
+                                                          buf->chan)]);
+		if(reserve_count == atomic_read(
+				&ltt_buf->commit_count[SUBBUF_INDEX((offset_old), buf->chan)])) {
+			buf->chan->cb->deliver(buf, SUBBUF_INDEX((offset_old), buf->chan), NULL);
+		}
+	}
+	
+	if(mode == FORCE_ACTIVE) {
+		/* New sub-buffer */
+		/* This code can be executed unordered : writers may already have written
+			 to the sub-buffer before this code gets executed, caution. */
+		/* The commit makes sure that this code is executed before the deliver
+			 of this sub-buffer */
+		ltt_channel->buffer_begin(buf, tsc, SUBBUF_INDEX(offset_begin, buf->chan));
+		commit_count = atomic_add_return(ltt_channel->subbuf_header_len(buf),
+								 &ltt_buf->commit_count[SUBBUF_INDEX(offset_begin, buf->chan)]);
+		/* Check if the written buffer has to be delivered */
+		if(commit_count	== atomic_read(
+					&ltt_buf->reserve_count[SUBBUF_INDEX(offset_begin, buf->chan)])) {
+			buf->chan->cb->deliver(buf, SUBBUF_INDEX(offset_begin, buf->chan), NULL);
+		}
+	}
+}
+
+
+/* LTTng channel flush function.
+ *
+ * Must be called when no tracing is active in the channel, because of
+ * accesses across CPUs. */
+static void ltt_buffer_flush(struct rchan *chan)
+{
+	unsigned int i;
+
+	for(i=0;i<NR_CPUS;i++) {
+		if(!chan->buf[i])
+			continue;
+		ltt_force_switch(chan->buf[i], FORCE_FLUSH);
+	}
+
+}
+
+
+/* Sleepable part of the destroy */
+static void __ltt_trace_destroy(struct ltt_trace_struct	*trace)
+{
+	int err;
+#if 0
+	relay_flush(trace->channel.facilities.rchan);
+	relay_flush(trace->channel.interrupts.rchan);
+	relay_flush(trace->channel.processes.rchan);
+	relay_flush(trace->channel.modules.rchan);
+	relay_flush(trace->channel.cpu.rchan);
+#endif //0
+	ltt_buffer_flush(trace->channel.facilities->rchan);
+	ltt_buffer_flush(trace->channel.interrupts->rchan);
+	ltt_buffer_flush(trace->channel.processes->rchan);
+	ltt_buffer_flush(trace->channel.modules->rchan);
+	ltt_buffer_flush(trace->channel.cpu->rchan);
+
+
+	relay_close(trace->channel.facilities->rchan);
+	relay_close(trace->channel.interrupts->rchan);
+	relay_close(trace->channel.processes->rchan);
+	relay_close(trace->channel.modules->rchan);
+	relay_close(trace->channel.cpu->rchan);
+#if 0
+	ltt_channel_destroy(trace->channel.facilities);
+	ltt_channel_destroy(trace->channel.interrupts);
+	ltt_channel_destroy(trace->channel.processes);
+	ltt_channel_destroy(trace->channel.modules);
+	ltt_channel_destroy(trace->channel.cpu);
+#endif //0
+	err = relayfs_remove_dir(trace->dentry.control_root);
+	WARN_ON(err);
+	relayfs_remove_dir(trace->dentry.trace_root);
+	WARN_ON(err);
+	
+	kfree(trace);
+}
+
+static int ltt_trace_destroy(char *trace_name)
+{
+	int err = 0;
+	struct ltt_trace_struct* trace;
+
+	down(&ltt_traces_sem);
+
+	trace = _ltt_trace_find(trace_name);
+	err = _ltt_trace_destroy(trace);
+	if(err) goto error;
+
+	up(&ltt_traces_sem);
+	
+	__ltt_trace_destroy(trace);
+	
+	return err;
+
+	/* Error handling */
+error:
+	up(&ltt_traces_sem);
+	
+	return err;
+}
+
+/* must be called from within a traces lock. */
+static int _ltt_trace_start(struct ltt_trace_struct* trace)
+{
+	int err = 0;
+
+	if(trace == NULL) {
+		err = ENOENT;
+		goto traces_error;
+	}
+
+	if(trace->active)
+		printk(KERN_INFO "LTT : Tracing already active for trace %s\n",
+				trace->trace_name);
+
+	if(ltt_traces.num_active_traces == 0) {
+
+		if(!try_module_get(ltt_run_filter_owner)) {
+			err = ENODEV;
+			printk(KERN_ERR "LTT : Can't lock filter module.\n");
+			goto get_ltt_run_filter_error;
+		}
+
+		if(!try_module_get(ltt_heartbeat_owner)) {
+			err = ENODEV;
+			printk(KERN_ERR "LTT : Can't lock heartbeat module.\n");
+			goto get_ltt_heartbeat_error;
+		}
+
+		if(!try_module_get(ltt_statedump_owner)) {
+			err = ENODEV;
+			printk(KERN_ERR "LTT : Can't lock state dump module.\n");
+			goto get_ltt_statedump_error;
+		}
+
+#ifdef CONFIG_LTT_HEARTBEAT
+		if(!ltt_heartbeat_functor(LTT_HEARTBEAT_START)) {
+			err = ENODEV;
+			printk(KERN_ERR "LTT : Heartbeat timer module no present.\n");
+			goto ltt_heartbeat_error;
+		}
+#endif //CONFIG_LTT_HEARTBEAT
+
+	}
+	
+	trace->active = 1;
+
+	ltt_traces.num_active_traces++; /* Read by trace points without protection :
+																		 be careful */
+	
+	return err;
+#ifdef CONFIG_LTT_HEARTBEAT
+ltt_heartbeat_error:
+	module_put(ltt_heartbeat_owner);
+#endif //CONFIG_LTT_HEARTBEAT
+get_ltt_statedump_error:
+	module_put(ltt_heartbeat_owner);
+get_ltt_heartbeat_error:
+	module_put(ltt_run_filter_owner);
+get_ltt_run_filter_error:
+traces_error:
+
+	return err;
+
+}
+
+static int ltt_trace_start(char *trace_name)
+{
+	int err = 0;
+	struct ltt_trace_struct* trace;
+
+	down(&ltt_traces_sem);
+
+	trace = _ltt_trace_find(trace_name);
+	if(trace == NULL) goto no_trace;
+	err = _ltt_trace_start(trace);
+
+	up(&ltt_traces_sem);
+	
+	/* Call the kernel state dump */
+	/* Events will be mixed with real kernel events, it's ok */
+	/* Notice that there is no protection on the trace : that's exactly why we
+	 * iterate on the list and check for trace equality instead of directly using
+	 * this trace handle inside the logging function. */
+	
+	/* State dump begin...
+	 * (must have send a tracing stop event if is the case...) */ //FIXME
+	ltt_facility_state_dump(trace);
+	ltt_statedump_functor(trace);
+
+	/* State dump finalize... tells state is coherent */ //FIXME
+
+	return err;
+
+	/* Error handling */
+no_trace:
+	up(&ltt_traces_sem);
+	
+	return err;
+}
+
+
+/* must be called from within traces lock */
+static int _ltt_trace_stop(struct ltt_trace_struct* trace)
+{
+	int err = EPERM;
+
+	if(trace == NULL) {
+		err = ENOENT;
+		goto traces_error;
+	}
+	
+	if(!trace->active)
+		printk(KERN_INFO "LTT : Tracing not active for trace %s\n",
+				trace->trace_name);
+	
+	if(trace->active) {
+		trace->active = 0;
+		ltt_traces.num_active_traces--;
+		synchronize_rcu();	/* Wait for each tracing to be finished */
+	}
+	
+#ifdef CONFIG_LTT_HEARTBEAT
+	/* stop the heartbeat if we are the last active trace */
+	if(ltt_traces.num_active_traces == 0)
+		ltt_heartbeat_functor(LTT_HEARTBEAT_STOP);
+#endif //CONFIG_LTT_HEARTBEAT
+
+	/* Release the modules if we are the last active trace */
+	if(ltt_traces.num_active_traces == 0) {
+		module_put(ltt_run_filter_owner);
+		module_put(ltt_heartbeat_owner);
+		module_put(ltt_statedump_owner);
+	}
+
+	/* Everything went fine */
+	return 0;
+
+	/* Error handling */
+traces_error:
+
+	return err;
+
+}
+
+static int ltt_trace_stop(char *trace_name)
+{
+	int err = 0;
+	struct ltt_trace_struct* trace;
+
+	down(&ltt_traces_sem);
+
+	trace = _ltt_trace_find(trace_name);
+	err = _ltt_trace_stop(trace);
+
+	up(&ltt_traces_sem);
+	
+	return err;
+}
+
+
+/* Exported functions */
+
+int ltt_control(enum ltt_control_msg msg, char *trace_name,
+		union ltt_control_args args)
+{
+	int err = EPERM;
+	
+	printk(KERN_ALERT "ltt_control : trace %s\n", trace_name);
+
+	switch(msg) {
+		case LTT_CONTROL_START:
+			printk(KERN_ALERT "Start tracing %s\n", trace_name);
+			err = ltt_trace_start(trace_name);
+			break;
+		case LTT_CONTROL_STOP:
+			printk(KERN_ALERT "Stop tracing %s\n", trace_name);
+			err = ltt_trace_stop(trace_name);
+			break;
+		case LTT_CONTROL_CREATE_TRACE:
+			printk(KERN_ALERT "Creating trace %s\n", trace_name);
+			err = ltt_trace_create(trace_name,	args.new_trace.mode,
+									args.new_trace.subbuf_size, args.new_trace.n_subbufs);
+			break;
+		case LTT_CONTROL_DESTROY_TRACE:
+			printk(KERN_ALERT "Destroying trace %s\n", trace_name);
+			err = ltt_trace_destroy(trace_name);
+			break;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(ltt_control);
+
+
+int ltt_filter_control(enum ltt_filter_control_msg msg, char *trace_name)
+{
+	int err;
+	struct ltt_trace_struct *trace;
+	printk(KERN_ALERT "ltt_filter_control : trace %s\n", trace_name);
+
+	down(&ltt_traces_sem);
+
+	trace = _ltt_trace_find(trace_name);
+	if(trace == NULL) {
+		printk(KERN_ALERT "Trace does not exist. Cannot proxy control request\n");
+		err = ENOENT;
+		goto trace_error;
+	}
+	
+	if(!try_module_get(ltt_filter_control_owner)) {
+		err = ENODEV;
+		goto get_module_error;
+	}
+
+	switch(msg) {
+		case LTT_FILTER_DEFAULT_ACCEPT:
+			printk(KERN_ALERT "Proxy filter default accept %s\n", trace_name);
+			err = (*ltt_filter_control_functor)(msg, trace);
+			break;
+		case LTT_FILTER_DEFAULT_REJECT:
+			printk(KERN_ALERT "Proxy filter default reject %s\n", trace_name);
+			err = (*ltt_filter_control_functor)(msg, trace);
+			break;
+		default:
+			err = EPERM;
+	}
+
+	module_put(ltt_filter_control_owner);
+	
+get_module_error:
+trace_error:
+	up(&ltt_traces_sem);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(ltt_filter_control);
+
+
+static int __init ltt_core_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-core init as module\n");
+	ltt_root_dentry = relayfs_create_dir(LTT_RELAYFS_ROOT, NULL);
+	if(ltt_root_dentry == NULL) return -EEXIST;
+
+	return 0;
+}
+
+static void __exit ltt_exit(void)
+{
+	int err;
+	struct ltt_trace_struct *trace;
+	
+	printk(KERN_INFO "LTT : ltt-core exit\n");
+
+	down(&ltt_traces_sem);
+
+	/* Stop each trace and destroy them */
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		_ltt_trace_stop(trace);
+		_ltt_trace_destroy(trace);	/* it's doing a synchronize_rcu() */
+		__ltt_trace_destroy(trace);
+	}
+
+	up(&ltt_traces_sem);
+
+	err = relayfs_remove_dir(ltt_root_dentry);
+	if(err != 0)
+		printk(KERN_INFO "LTT : stale ltt root relayfs entry\n");
+
+}
+
+module_init(ltt_core_init)
+module_exit(ltt_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Tracer");
+
+
diff -uNrp linux-2.6.14.5/kernel/ltt-facilities.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-facilities.c
--- linux-2.6.14.5/kernel/ltt-facilities.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/ltt-facilities.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,227 @@
+/*
+ * ltt-facilities.c
+ *
+ * (C) Copyright	2005 -
+ * 							Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the kernel core code for Linux Trace Toolkit facilities.
+ *
+ * Facilities are a group of events that can be recorded by instrumentation
+ * points to a trace. We keep track of the active facilities to know which type
+ * of information can be present in a trace.
+ *
+ * We never reuse a facility id.
+ * 
+ * Author:
+ *	Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ */
+
+#include <linux/ltt/ltt-facility-core.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ltt-facilities.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+enum ltt_facility_type 	{ LTT_FACILITY_BUILTIN,
+													LTT_FACILITY_DYNAMIC_REGISTERED,
+													LTT_FACILITY_DYNAMIC_UNREGISTERED };
+
+struct ltt_facility_info {
+  int exist;  /* Is the facility field used ? */
+	struct ltt_facility *facility;
+	enum ltt_facility_type type;
+  size_t alignment;
+};
+
+static struct ltt_facility_info facilities[LTT_MAX_NUM_FACILITIES];
+static spinlock_t	facilities_lock;
+
+static inline int ltt_facility_register(enum ltt_facility_type type,
+																				struct ltt_facility *facility,
+																				size_t int_size,
+																				size_t long_size,
+																				size_t pointer_size,
+																				size_t size_t_size)
+{
+	int fac_id;
+	size_t alignment;
+  
+	spin_lock(&facilities_lock);
+
+#ifdef CONFIG_LTT_ALIGNMENT
+	alignment = sizeof(void*);
+#else
+	alignment = 0;
+#endif
+
+	if(strcmp(facility->name, "core") == 0) {
+		fac_id = 0;
+		facilities[fac_id].facility = facility;
+		facilities[fac_id].type = type;
+    facilities[fac_id].exist = 1;
+    facilities[fac_id].alignment = alignment;
+  } else {
+    for(fac_id=LTT_RESERVED_FACILITIES;fac_id<LTT_MAX_NUM_FACILITIES;fac_id++)
+      if(facilities[fac_id].exist == 0)
+        break;
+    if(fac_id == LTT_MAX_NUM_FACILITIES) {
+      fac_id = -EPERM;
+      goto unlock;
+    }
+		facilities[fac_id].facility = facility;
+		facilities[fac_id].type = type;
+    facilities[fac_id].exist = 1;
+    facilities[fac_id].alignment = alignment;
+	}
+
+	trace_core_facility_load(
+			facility->name,
+			facility->checksum,
+			fac_id,
+			(u32)int_size,
+			(u32)long_size,
+			(u32)pointer_size,
+			(u32)size_t_size,
+			alignment);
+
+unlock:
+	
+	spin_unlock(&facilities_lock);
+	return fac_id;
+}
+
+
+int ltt_facility_builtin_register(struct ltt_facility *facility)
+{
+	return ltt_facility_register(LTT_FACILITY_BUILTIN, facility,
+			sizeof(int), sizeof(long), sizeof(void*), sizeof(size_t));
+}
+
+int ltt_facility_dynamic_register(struct ltt_facility *facility)
+{
+	return ltt_facility_register(LTT_FACILITY_DYNAMIC_REGISTERED, facility,
+			sizeof(int), sizeof(long), sizeof(void*), sizeof(size_t));
+}
+
+int ltt_facility_dynamic_unregister(ltt_facility_t facility_id)
+{
+	int ret;
+
+	spin_lock(&facilities_lock);
+  
+	if(facilities[facility_id].exist == 0) {
+		ret = -EPERM;
+		goto unlock;
+	}
+	
+	if(facilities[facility_id].type != LTT_FACILITY_DYNAMIC_REGISTERED) {
+		ret = -EPERM;
+		goto unlock;
+	}
+	
+	facilities[facility_id].facility = NULL;
+	facilities[facility_id].type = LTT_FACILITY_DYNAMIC_UNREGISTERED;
+
+	/* Disable preemption because we read the traces list, and want it to be
+	 * RCU coherent. */
+	preempt_disable();
+	ltt_nesting[smp_processor_id()]++;
+	barrier();
+
+	/* If no more trace in the list, we can free the unused facility,
+	 * otherwise it will be freed laster when the last trace is destroyed (by
+	 * ltt_facility_free_unused()). */
+  if(list_empty(&ltt_traces.head))
+	  facilities[facility_id].exist = 0;
+
+	barrier();
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable();
+
+	trace_core_facility_unload(facility_id);
+
+	ret = 0;
+
+unlock:
+	
+	spin_unlock(&facilities_lock);
+	return ret;
+}
+
+/* Cleanup all the unregistered facilities. This must be done when all the
+ * traces are destroyed.
+ */
+void ltt_facility_free_unused(void)
+{
+  int fac_id;
+  
+  for(fac_id=LTT_RESERVED_FACILITIES;fac_id<LTT_MAX_NUM_FACILITIES;fac_id++)
+		if(facilities[fac_id].type == LTT_FACILITY_DYNAMIC_UNREGISTERED)
+			facilities[fac_id].exist = 0;
+}
+
+
+void ltt_facility_state_dump(struct ltt_trace_struct *trace)
+{
+	int fac_id;
+	struct ltt_facility *facility;
+	u32 int_size, long_size, pointer_size, size_t_size;
+
+  int_size = sizeof(int);
+  long_size = sizeof(long);
+  pointer_size = sizeof(void*);
+  size_t_size = sizeof(size_t);
+
+	spin_lock(&facilities_lock);
+
+	for(fac_id=0;fac_id<LTT_MAX_NUM_FACILITIES;fac_id++) {
+    if(facilities[fac_id].exist) {
+      facility = facilities[fac_id].facility;
+      printk(KERN_INFO "Dumping facility %s\n",
+          facility->name);
+      switch(facilities[fac_id].type) {
+        case LTT_FACILITY_DYNAMIC_REGISTERED:
+        case LTT_FACILITY_BUILTIN:
+          trace_core_state_dump_facility_load(trace,
+              facility->name,
+              facility->checksum,
+              fac_id,
+              (u32)int_size,
+              (u32)long_size,
+              (u32)pointer_size,
+              (u32)size_t_size,
+              facilities[fac_id].alignment);
+          break;
+        case LTT_FACILITY_DYNAMIC_UNREGISTERED:
+          break;
+      }
+    }
+	}
+	spin_unlock(&facilities_lock);
+}
+
+
+EXPORT_SYMBOL(ltt_facility_builtin_register);
+
+EXPORT_SYMBOL(ltt_facility_dynamic_register);
+EXPORT_SYMBOL(ltt_facility_dynamic_unregister);
+
+EXPORT_SYMBOL(ltt_facility_free_unused);
+
+EXPORT_SYMBOL(ltt_facility_state_dump);
+
+static int __init ltt_facilities_init(void)
+{
+  int i;
+	printk(KERN_INFO "LTT : ltt-facilities init\n");
+
+	spin_lock_init(&facilities_lock);
+  for(i=0; i<LTT_MAX_NUM_FACILITIES; i++)
+    facilities[i].exist = 0;
+  
+	return 0;
+}
+__initcall(ltt_facilities_init);
+
diff -uNrp linux-2.6.14.5/kernel/Makefile linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/Makefile
--- linux-2.6.14.5/kernel/Makefile	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/Makefile	2006-01-22 13:01:14.000000000 +0100
@@ -9,6 +9,10 @@ obj-y     = sched.o fork.o exec_domain.o
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
 
+ifeq ($(CONFIG_LTT),y)
+	obj-y += ltt-base.o
+endif
+
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
@@ -19,6 +23,8 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_KEXEC) += kexec.o
+obj-$(CONFIG_LTT) += ltt-facilities.o
+obj-$(CONFIG_LTT_TRACER) += ltt-core.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_IKCONFIG) += configs.o
@@ -32,6 +38,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softl
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
+obj-$(CONFIG_IPIPE) += ipipe/
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -55,3 +62,4 @@ quiet_cmd_ikconfiggz = IKCFG   $@
 targets += config_data.h
 $(obj)/config_data.h: $(obj)/config_data.gz FORCE
 	$(call if_changed,ikconfiggz)
+
diff -uNrp linux-2.6.14.5/kernel/printk.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/printk.c
--- linux-2.6.14.5/kernel/printk.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/printk.c	2006-01-22 13:01:14.000000000 +0100
@@ -507,6 +507,78 @@ __attribute__((weak)) unsigned long long
  * is inspected when the actual printing occurs.
  */
 
+#ifdef CONFIG_IPIPE
+
+static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED;
+
+static int __ipipe_printk_fill;
+
+static char __ipipe_printk_buf[__LOG_BUF_LEN];
+
+void __ipipe_flush_printk (unsigned virq)
+{
+	char *p = __ipipe_printk_buf;
+	int len, lmax, out = 0;
+	unsigned long flags;
+
+	goto start;
+
+	do {
+		spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags);
+ start:
+		lmax = __ipipe_printk_fill;
+		while (out < lmax) {
+			len = strlen(p) + 1;
+			printk("%s",p);
+			p += len;
+			out += len;
+		}
+		spin_lock_irqsave_hw(&__ipipe_printk_lock,flags);
+	}
+	while (__ipipe_printk_fill != lmax);
+
+	__ipipe_printk_fill = 0;
+
+	spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags);
+}
+
+asmlinkage int printk(const char *fmt, ...)
+{
+	int r, fbytes, oldcount;
+    	unsigned long flags;
+	va_list args;
+
+	va_start(args, fmt);
+
+	if (ipipe_current_domain == ipipe_root_domain ||
+	    test_bit(IPIPE_SPRINTK_FLAG,&ipipe_current_domain->flags) ||
+	    oops_in_progress) {
+		r = vprintk(fmt, args);
+		goto out;
+	}
+
+	spin_lock_irqsave_hw(&__ipipe_printk_lock,flags);
+
+	oldcount = __ipipe_printk_fill;
+	fbytes = __LOG_BUF_LEN - oldcount;
+
+	if (fbytes > 1)	{
+		r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill,
+			       fbytes, fmt, args) + 1; /* account for the null byte */
+		__ipipe_printk_fill += r;
+	} else
+		r = 0;
+
+	spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags);
+
+	if (oldcount == 0)
+		ipipe_trigger_irq(__ipipe_printk_virq);
+out: 
+	va_end(args);
+
+	return r;
+}
+#else /* !CONFIG_IPIPE */
 asmlinkage int printk(const char *fmt, ...)
 {
 	va_list args;
@@ -518,6 +590,7 @@ asmlinkage int printk(const char *fmt, .
 
 	return r;
 }
+#endif /* CONFIG_IPIPE */
 
 /* cpu currently holding logbuf_lock */
 static volatile unsigned int printk_cpu = UINT_MAX;
diff -uNrp linux-2.6.14.5/kernel/sched.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/sched.c
--- linux-2.6.14.5/kernel/sched.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/sched.c	2006-01-22 13:01:14.000000000 +0100
@@ -18,6 +18,7 @@
  *  2004-04-02	Scheduler domains code by Nick Piggin
  */
 
+#include <linux/ltt/ltt-facility-process.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/nmi.h>
@@ -355,6 +356,8 @@ static inline runqueue_t *task_rq_lock(t
 {
 	struct runqueue *rq;
 
+	trace_process_wakeup(p->pid, p->state);
+
 repeat_lock_task:
 	local_irq_save(*flags);
 	rq = task_rq(p);
@@ -2855,6 +2858,11 @@ asmlinkage void __sched schedule(void)
 	unsigned long run_time;
 	int cpu, idx, new_prio;
 
+#ifdef CONFIG_IPIPE
+	if (unlikely(ipipe_current_domain != ipipe_root_domain)) {
+		goto need_resched;
+	}
+#endif /* CONFIG_IPIPE */
 	/*
 	 * Test if we are atomic.  Since do_exit() needs to call into
 	 * schedule() atomically, we ignore that path for now.
@@ -2872,6 +2880,12 @@ asmlinkage void __sched schedule(void)
 
 need_resched:
 	preempt_disable();
+#ifdef CONFIG_IPIPE
+	if (unlikely(ipipe_current_domain != ipipe_root_domain)) {
+		preempt_enable();
+		return;
+	}
+#endif /* CONFIG_IPIPE */
 	prev = current;
 	release_kernel_lock(prev);
 need_resched_nonpreemptible:
@@ -3008,8 +3022,11 @@ switch_tasks:
 		++*switch_count;
 
 		prepare_task_switch(rq, next);
+		trace_process_schedchange(prev->pid, next->pid, prev->state);
 		prev = context_switch(rq, prev, next);
 		barrier();
+ 		if (task_hijacked(prev))
+ 		    return;
 		/*
 		 * this_rq must be evaluated again because prev may have moved
 		 * CPUs since it called schedule(), thus the 'rq' on its stack
@@ -3042,6 +3059,11 @@ asmlinkage void __sched preempt_schedule
 	struct task_struct *task = current;
 	int saved_lock_depth;
 #endif
+#ifdef CONFIG_IPIPE
+	/* Do not reschedule over non-Linux domains. */
+	if (ipipe_current_domain != ipipe_root_domain)
+		return;
+#endif /* CONFIG_IPIPE */
 	/*
 	 * If there is a non-zero preempt_count or interrupts are disabled,
 	 * we do not want to preempt the current task.  Just return..
@@ -3670,6 +3692,7 @@ recheck:
 		deactivate_task(p, rq);
 	oldprio = p->prio;
 	__setscheduler(p, policy, param->sched_priority);
+	ipipe_setsched_notify(p);
 	if (array) {
 		__activate_task(p, rq);
 		/*
@@ -5647,3 +5670,53 @@ void set_curr_task(int cpu, task_t *p)
 }
 
 #endif
+
+#ifdef CONFIG_IPIPE
+
+int ipipe_setscheduler_root (struct task_struct *p, int policy, int prio)
+{
+	prio_array_t *array;
+	unsigned long flags;
+	runqueue_t *rq;
+	int oldprio;
+
+	if (prio < 1 || prio > MAX_RT_PRIO-1)
+		return -EINVAL;
+
+	rq = task_rq_lock(p, &flags);
+	array = p->array;
+	if (array)
+		deactivate_task(p, rq);
+	oldprio = p->prio;
+	__setscheduler(p, policy, prio);
+	if (array) {
+		__activate_task(p, rq);
+		if (task_running(rq, p)) {
+			if (p->prio > oldprio)
+				resched_task(rq->curr);
+		} else if (TASK_PREEMPTS_CURR(p, rq))
+			resched_task(rq->curr);
+	}
+	task_rq_unlock(rq, &flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ipipe_setscheduler_root);
+
+int ipipe_reenter_root (struct task_struct *prev, int policy, int prio)
+{
+	finish_task_switch(this_rq(), prev);
+	if (reacquire_kernel_lock(current) < 0)
+		;
+	preempt_enable_no_resched();
+
+	if (current->policy != policy || current->rt_priority != prio)
+		return ipipe_setscheduler_root(current,policy,prio);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ipipe_reenter_root);
+
+#endif /* CONFIG_IPIPE */
diff -uNrp linux-2.6.14.5/kernel/signal.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/signal.c
--- linux-2.6.14.5/kernel/signal.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/signal.c	2006-01-22 13:01:14.000000000 +0100
@@ -10,6 +10,7 @@
  *		to allow signals to be sent reliably.
  */
 
+#include <linux/ltt/ltt-facility-process.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -603,6 +604,7 @@ void signal_wake_up(struct task_struct *
 	unsigned int mask;
 
 	set_tsk_thread_flag(t, TIF_SIGPENDING);
+	ipipe_sigwake_notify(t); /* TIF_SIGPENDING must be set first. */
 
 	/*
 	 * For SIGKILL, we want to wake it up in the stopped/traced case.
@@ -869,6 +871,8 @@ specific_send_sig_info(int sig, struct s
 	if (sig_ignored(t, sig))
 		goto out;
 
+	trace_process_signal(t->pid, sig);
+
 	/* Support queueing exactly one non-rt signal, so that we
 	   can get more detailed information about the cause of
 	   the signal. */
diff -uNrp linux-2.6.14.5/kernel/softirq.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/softirq.c
--- linux-2.6.14.5/kernel/softirq.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/softirq.c	2006-01-22 13:01:14.000000000 +0100
@@ -6,6 +6,7 @@
  * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
  */
 
+#include <linux/ltt/ltt-facility-kernel.h>
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
@@ -92,7 +93,9 @@ restart:
 
 	do {
 		if (pending & 1) {
+			trace_kernel_soft_irq_entry((void*)(h - softirq_vec));
 			h->action(h);
+			trace_kernel_soft_irq_exit((void*)(h - softirq_vec));
 			rcu_bh_qsctr_inc(cpu);
 		}
 		h++;
@@ -262,9 +265,17 @@ static void tasklet_action(struct softir
 
 		if (tasklet_trylock(t)) {
 			if (!atomic_read(&t->count)) {
-				if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+				if (!test_and_clear_bit(TASKLET_STATE_SCHED,
+						&t->state))
 					BUG();
+
+				trace_kernel_tasklet_entry(LTTNG_LOW, t->func, t->data);
+
 				t->func(t->data);
+
+				trace_kernel_tasklet_exit(LTTNG_LOW, t->func, t->data);
+
+
 				tasklet_unlock(t);
 				continue;
 			}
@@ -295,9 +306,15 @@ static void tasklet_hi_action(struct sof
 
 		if (tasklet_trylock(t)) {
 			if (!atomic_read(&t->count)) {
-				if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+				if (!test_and_clear_bit(TASKLET_STATE_SCHED,
+						&t->state))
 					BUG();
+
+				trace_kernel_tasklet_entry(LTTNG_HIGH, t->func, t->data);
+
 				t->func(t->data);
+
+				trace_kernel_tasklet_exit(LTTNG_HIGH, t->func, t->data);
 				tasklet_unlock(t);
 				continue;
 			}
diff -uNrp linux-2.6.14.5/kernel/timer.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/timer.c
--- linux-2.6.14.5/kernel/timer.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/kernel/timer.c	2006-01-22 13:01:14.000000000 +0100
@@ -19,6 +19,7 @@
  *              Designed by David S. Miller, Alexey Kuznetsov and Ingo Molnar
  */
 
+#include <linux/ltt/ltt-facility-timer.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -912,6 +913,8 @@ static void run_timer_softirq(struct sof
 {
 	tvec_base_t *base = &__get_cpu_var(tvec_bases);
 
+	trace_timer_softirq();
+
 	if (time_after_eq(jiffies, base->timer_jiffies))
 		__run_timers(base);
 }
@@ -1071,6 +1074,7 @@ asmlinkage long sys_getegid(void)
 
 static void process_timeout(unsigned long __data)
 {
+	trace_timer_expired(((task_t *)__data)->pid);
 	wake_up_process((task_t *)__data);
 }
 
diff -uNrp linux-2.6.14.5/lib/smp_processor_id.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/lib/smp_processor_id.c
--- linux-2.6.14.5/lib/smp_processor_id.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/lib/smp_processor_id.c	2006-01-22 13:01:14.000000000 +0100
@@ -12,6 +12,11 @@ unsigned int debug_smp_processor_id(void
 	int this_cpu = raw_smp_processor_id();
 	cpumask_t this_mask;
 
+#ifdef CONFIG_IPIPE
+ 	if (ipipe_current_domain != ipipe_root_domain)
+	    return this_cpu;
+#endif /* CONFIG_IPIPE */
+
 	if (likely(preempt_count))
 		goto out;
 
diff -uNrp linux-2.6.14.5/lib/spinlock_debug.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/lib/spinlock_debug.c
--- linux-2.6.14.5/lib/spinlock_debug.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/lib/spinlock_debug.c	2006-01-22 13:01:14.000000000 +0100
@@ -10,6 +10,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 static void spin_bug(spinlock_t *lock, const char *msg)
 {
@@ -93,6 +94,8 @@ void _raw_spin_lock(spinlock_t *lock)
 	debug_spin_lock_after(lock);
 }
 
+EXPORT_SYMBOL(_raw_spin_lock);
+
 int _raw_spin_trylock(spinlock_t *lock)
 {
 	int ret = __raw_spin_trylock(&lock->raw_lock);
@@ -108,12 +111,16 @@ int _raw_spin_trylock(spinlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_spin_trylock);
+
 void _raw_spin_unlock(spinlock_t *lock)
 {
 	debug_spin_unlock(lock);
 	__raw_spin_unlock(&lock->raw_lock);
 }
 
+EXPORT_SYMBOL(_raw_spin_unlock);
+
 static void rwlock_bug(rwlock_t *lock, const char *msg)
 {
 	static long print_once = 1;
@@ -162,6 +169,8 @@ void _raw_read_lock(rwlock_t *lock)
 		__read_lock_debug(lock);
 }
 
+EXPORT_SYMBOL(_raw_read_lock);
+
 int _raw_read_trylock(rwlock_t *lock)
 {
 	int ret = __raw_read_trylock(&lock->raw_lock);
@@ -175,12 +184,16 @@ int _raw_read_trylock(rwlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_read_trylock);
+
 void _raw_read_unlock(rwlock_t *lock)
 {
 	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
 	__raw_read_unlock(&lock->raw_lock);
 }
 
+EXPORT_SYMBOL(_raw_read_unlock);
+
 static inline void debug_write_lock_before(rwlock_t *lock)
 {
 	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
@@ -235,6 +248,8 @@ void _raw_write_lock(rwlock_t *lock)
 	debug_write_lock_after(lock);
 }
 
+EXPORT_SYMBOL(_raw_write_lock);
+
 int _raw_write_trylock(rwlock_t *lock)
 {
 	int ret = __raw_write_trylock(&lock->raw_lock);
@@ -250,8 +265,12 @@ int _raw_write_trylock(rwlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_write_trylock);
+
 void _raw_write_unlock(rwlock_t *lock)
 {
 	debug_write_unlock(lock);
 	__raw_write_unlock(&lock->raw_lock);
 }
+
+EXPORT_SYMBOL(_raw_write_unlock);
diff -uNrp linux-2.6.14.5/ltt/Kconfig linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/Kconfig
--- linux-2.6.14.5/ltt/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/Kconfig	2006-01-22 13:02:25.000000000 +0100
@@ -0,0 +1,160 @@
+menu "Instrumentation Support"
+
+config LTT
+	bool "Linux Trace Toolkit Instrumentation Support"
+	select RELAYFS_FS
+	select LTT_FACILITY_CORE
+	depends on !X86_64 && EXPERIMENTAL
+	default n
+	help
+	  It is possible for the kernel to log important events to a trace
+	  facility. Doing so, enables the use of the generated traces in order
+	  to reconstruct the dynamic behavior of the kernel, and hence the
+	  whole system.
+
+	  The tracing process contains 4 parts :
+	      1) The logging of events by key parts of the kernel.
+	      2) The tracer that keeps the events in a data buffer (uses
+	         relayfs).
+	      3) A trace daemon that interacts with the tracer and is
+	         notified every time there is a certain quantity of data to
+	         read from the tracer.
+	      4) A trace event data decoder that reads the accumulated data
+	         and formats it in a human-readable format.
+
+	  If you say Y, the first component will be built into the kernel.
+
+	  For more information on kernel tracing, the trace daemon or the event
+	  decoder, please check the following address :
+	       http://www.opersys.com/ltt
+	  See also the experimental page of the project :
+	       http://ltt.polymtl.ca
+
+config LTT_TRACER
+	tristate "Linux Trace Toolkit Tracer"
+	select RELAYFS_FS
+	depends on LTT
+	default y
+	help
+	  If you enable this option, the Linux Trace Toolkit Tracer will be
+	  either built in the kernel of as module.
+
+	  Critical parts of the kernel will call upon the kernel tracing
+	  function. The data is then recorded by the tracer if a trace daemon
+	  is running in user-space and has issued a "start" command.
+
+	  For more information on kernel tracing, the trace daemon or the event
+	  decoder, please check the following address :
+	       http://www.opersys.com/ltt
+	  See also the experimental page of the project :
+	       http://ltt.polymtl.ca
+
+config LTT_ALIGNMENT
+	bool "Align Linux Trace Toolkit Traces"
+	depends on LTT
+	default y
+	help
+		This option enables dynamic alignment of data in buffers. The alignment
+		is made on the smallest size between architecture size and the size of
+		the value to be written.
+
+		Dynamically calculating the offset of the data has a performance cost,
+		but it is more efficient on some architectures (especially 64 bits) to
+		align data than to write it unaligned.
+
+config LTT_HEARTBEAT
+	bool "Activate Linux Trace Toolkit Heartbeat Timer"
+	depends on LTT
+	default n
+	help
+		The Linux Trace Toolkit Heartbeat Timer fires at an interval small
+		enough to guarantee that the 32 bits truncated TSC won't overflow
+		between two consecutive events in a trace. It simply write an event
+		in each tracefiles at an interval that is one tenth of the time it
+		takes to overflow 32 bits at your CPU frequency.
+
+		If there is no Heartbeat Timer activated, 64 bits fields must be
+		used in each event header to save the full TSC : it can make traces
+		about 1/10 bigger.
+
+		It is suggested that you enable this option to make more compact
+		traces.
+
+config LTT_FACILITY_CORE
+	bool "Linux Trace Toolkit Core Facility"
+	depends on LTT
+	default y
+	help
+		LTT core facility. Contains event definition for facility load/unload and
+		heartbeat.
+
+config LTT_FACILITY_FS
+	bool "Linux Trace Toolkit File System Facility"
+	depends on LTT
+	default y
+	help
+		LTT file system facility. Contains event definition for filesystem related
+		events.
+
+config LTT_FACILITY_IPC
+	bool "Linux Trace Toolkit Inter-Process Communication Facility"
+	depends on LTT
+	default y
+	help
+		LTT IPC facility. Contains event definition for inter-process communication
+		events.
+
+config LTT_FACILITY_KERNEL
+	bool "Linux Trace Toolkit Kernel Facility"
+	depends on LTT
+	default y
+	help
+		LTT Kernel facility. Contains event definition for tasklet, irq, system
+		calls, traps, soft irq events.
+
+config LTT_FACILITY_MEMORY
+	bool "Linux Trace Toolkit Memory Facility"
+	depends on LTT
+	default y
+	help
+		LTT Memory facility. Contains event definition for memory management related
+		events.
+
+config LTT_FACILITY_NETWORK
+	bool "Linux Trace Toolkit Network Facility"
+	depends on LTT
+	default y
+	help
+		LTT Network facility. Contains event definition for network subsystem.
+
+config LTT_FACILITY_PROCESS
+	bool "Linux Trace Toolkit Process Facility"
+	depends on LTT
+	default y
+	help
+		LTT Process facility. Contains event definition for process management and
+		scheduling.
+
+config LTT_FACILITY_SOCKET
+	bool "Linux Trace Toolkit Socket Facility"
+	depends on LTT
+	default y
+	help
+		LTT Socket facility. Contains event definition for sockets.
+
+config LTT_FACILITY_STATEDUMP
+	bool "Linux Trace Toolkit Kernel State Dump Facility"
+	depends on LTT
+	default y
+	help
+		LTT Kernel State Dump facility. Contains events for dumping kernel state at
+		the beginning of a trace.
+
+config LTT_FACILITY_TIMER
+	bool "Linux Trace Toolkit Timer Facility"
+	depends on LTT
+	default y
+	help
+		LTT Timer facility. Contains events for timers.
+
+endmenu
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-core.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-core.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-core.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-core.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-core.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-core init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-core init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-core.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-core.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-core.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-core.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_CORE_H_
+#define _LTT_FACILITY_LOADER_CORE_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-core.h>
+
+ltt_facility_t	ltt_facility_core;
+ltt_facility_t	ltt_facility_core_F1C514F;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_core
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_core_F1C514F
+#define LTT_FACILITY_CHECKSUM						0xF1C514F
+#define LTT_FACILITY_NAME								"core"
+#define LTT_FACILITY_NUM_EVENTS					facility_core_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_CORE_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-fs.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-fs.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-fs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-fs.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-fs.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-fs.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-fs init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-fs init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-fs.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-fs.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-fs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-fs.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_FS_H_
+#define _LTT_FACILITY_LOADER_FS_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-fs.h>
+
+ltt_facility_t	ltt_facility_fs;
+ltt_facility_t	ltt_facility_fs_40A645EC;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_fs
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_fs_40A645EC
+#define LTT_FACILITY_CHECKSUM						0x40A645EC
+#define LTT_FACILITY_NAME								"fs"
+#define LTT_FACILITY_NUM_EVENTS					facility_fs_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_FS_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-ipc.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-ipc.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-ipc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-ipc.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-ipc.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-ipc.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-ipc init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-ipc init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-ipc.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-ipc.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-ipc.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_IPC_H_
+#define _LTT_FACILITY_LOADER_IPC_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-ipc.h>
+
+ltt_facility_t	ltt_facility_ipc;
+ltt_facility_t	ltt_facility_ipc_14120A9A;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_ipc
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_ipc_14120A9A
+#define LTT_FACILITY_CHECKSUM						0x14120A9A
+#define LTT_FACILITY_NAME								"ipc"
+#define LTT_FACILITY_NUM_EVENTS					facility_ipc_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_IPC_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-kernel.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-kernel.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-kernel.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-kernel.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-kernel.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-kernel.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-kernel init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-kernel init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-kernel.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-kernel.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-kernel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-kernel.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_KERNEL_H_
+#define _LTT_FACILITY_LOADER_KERNEL_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-kernel.h>
+
+ltt_facility_t	ltt_facility_kernel;
+ltt_facility_t	ltt_facility_kernel_E78275BF;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_kernel
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_kernel_E78275BF
+#define LTT_FACILITY_CHECKSUM						0xE78275BF
+#define LTT_FACILITY_NAME								"kernel"
+#define LTT_FACILITY_NUM_EVENTS					facility_kernel_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_KERNEL_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-memory.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-memory.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-memory.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-memory.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-memory.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-memory init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-memory init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-memory.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-memory.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-memory.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_MEMORY_H_
+#define _LTT_FACILITY_LOADER_MEMORY_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-memory.h>
+
+ltt_facility_t	ltt_facility_memory;
+ltt_facility_t	ltt_facility_memory_D63D41C7;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_memory
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_memory_D63D41C7
+#define LTT_FACILITY_CHECKSUM						0xD63D41C7
+#define LTT_FACILITY_NAME								"memory"
+#define LTT_FACILITY_NUM_EVENTS					facility_memory_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_MEMORY_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-network.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-network.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-network.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-network.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-network.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-network.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-network init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-network init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-network.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-network.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-network.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-network.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_NETWORK_H_
+#define _LTT_FACILITY_LOADER_NETWORK_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-network.h>
+
+ltt_facility_t	ltt_facility_network;
+ltt_facility_t	ltt_facility_network_8B91EC6C;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_network
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_network_8B91EC6C
+#define LTT_FACILITY_CHECKSUM						0x8B91EC6C
+#define LTT_FACILITY_NAME								"network"
+#define LTT_FACILITY_NUM_EVENTS					facility_network_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_NETWORK_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-process.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-process.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-process.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-process.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-process.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-process init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-process init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-process.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-process.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-process.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-process.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_PROCESS_H_
+#define _LTT_FACILITY_LOADER_PROCESS_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-process.h>
+
+ltt_facility_t	ltt_facility_process;
+ltt_facility_t	ltt_facility_process_F7697017;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_process
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_process_F7697017
+#define LTT_FACILITY_CHECKSUM						0xF7697017
+#define LTT_FACILITY_NAME								"process"
+#define LTT_FACILITY_NUM_EVENTS					facility_process_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_PROCESS_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-socket.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-socket.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-socket.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-socket.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-socket.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-socket.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-socket init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-socket init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-socket.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-socket.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-socket.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_SOCKET_H_
+#define _LTT_FACILITY_LOADER_SOCKET_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-socket.h>
+
+ltt_facility_t	ltt_facility_socket;
+ltt_facility_t	ltt_facility_socket_5E76ED18;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_socket
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_socket_5E76ED18
+#define LTT_FACILITY_CHECKSUM						0x5E76ED18
+#define LTT_FACILITY_NAME								"socket"
+#define LTT_FACILITY_NUM_EVENTS					facility_socket_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_SOCKET_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-statedump.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-statedump.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-statedump.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-statedump.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-statedump.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-statedump.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-statedump init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-statedump init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-statedump.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-statedump.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-statedump.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-statedump.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_STATEDUMP_H_
+#define _LTT_FACILITY_LOADER_STATEDUMP_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-statedump.h>
+
+ltt_facility_t	ltt_facility_statedump;
+ltt_facility_t	ltt_facility_statedump_31582B7A;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_statedump
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_statedump_31582B7A
+#define LTT_FACILITY_CHECKSUM						0x31582B7A
+#define LTT_FACILITY_NAME								"statedump"
+#define LTT_FACILITY_NUM_EVENTS					facility_statedump_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_STATEDUMP_H_
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-timer.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-timer.c
--- linux-2.6.14.5/ltt/ltt-facility-loader-timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-timer.c	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * ltt-facility-loader-timer.c
+ *
+ * (C) Copyright  2005 - 
+ *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT facility loader.
+ *
+ */
+
+
+#include <linux/ltt-facilities.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include "ltt-facility-loader-timer.h"
+
+
+#ifdef CONFIG_LTT
+
+EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);
+EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);
+
+static const char ltt_facility_name[] = LTT_FACILITY_NAME;
+
+#define SYMBOL_STRING(sym) #sym
+
+static struct ltt_facility facility = {
+	.name = ltt_facility_name,
+	.num_events = LTT_FACILITY_NUM_EVENTS,
+	.checksum = LTT_FACILITY_CHECKSUM,
+	.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),
+};
+
+#ifndef MODULE
+
+/* Built-in facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-timer init in kernel\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+	
+	return LTT_FACILITY_SYMBOL;
+}
+__initcall(facility_init);
+
+
+
+#else 
+
+/* Dynamic facility. */
+
+static int __init facility_init(void)
+{
+	printk(KERN_INFO "LTT : ltt-facility-timer init dynamic\n");
+
+	LTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);
+	LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+	return LTT_FACILITY_SYMBOL;
+}
+
+static void __exit facility_exit(void)
+{
+	int err;
+
+	err = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);
+	if(err != 0)
+		printk(KERN_ERR "LTT : Error in unregistering facility.\n");
+
+}
+
+module_init(facility_init)
+module_exit(facility_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Facility");
+
+#endif //MODULE
+
+#endif //CONFIG_LTT
diff -uNrp linux-2.6.14.5/ltt/ltt-facility-loader-timer.h linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-timer.h
--- linux-2.6.14.5/ltt/ltt-facility-loader-timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/ltt-facility-loader-timer.h	2006-01-22 13:01:14.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _LTT_FACILITY_LOADER_TIMER_H_
+#define _LTT_FACILITY_LOADER_TIMER_H_
+
+#ifdef CONFIG_LTT
+
+#include <linux/ltt-facilities.h>
+#include <linux/ltt/ltt-facility-id-timer.h>
+
+ltt_facility_t	ltt_facility_timer;
+ltt_facility_t	ltt_facility_timer_5EACEACA;
+
+#define LTT_FACILITY_SYMBOL							ltt_facility_timer
+#define LTT_FACILITY_CHECKSUM_SYMBOL		ltt_facility_timer_5EACEACA
+#define LTT_FACILITY_CHECKSUM						0x5EACEACA
+#define LTT_FACILITY_NAME								"timer"
+#define LTT_FACILITY_NUM_EVENTS					facility_timer_num_events
+
+#endif //CONFIG_LTT
+
+#endif //_LTT_FACILITY_LOADER_TIMER_H_
diff -uNrp linux-2.6.14.5/ltt/Makefile linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/Makefile
--- linux-2.6.14.5/ltt/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/ltt/Makefile	2006-01-22 13:01:54.000000000 +0100
@@ -0,0 +1,15 @@
+#
+# Makefile for the linux kernel.
+#
+#
+obj-$(CONFIG_LTT) += ltt-facility-loader-core.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-fs.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-ipc.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-kernel.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-memory.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-network.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-process.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-socket.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-timer.o
+obj-$(CONFIG_LTT) += ltt-facility-loader-statedump.o
+
diff -uNrp linux-2.6.14.5/MAINTAINERS linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/MAINTAINERS
--- linux-2.6.14.5/MAINTAINERS	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/MAINTAINERS	2006-01-22 13:01:14.000000000 +0100
@@ -1538,6 +1538,16 @@ L:	linux-security-module@wirex.com
 W:	http://lsm.immunix.org
 S:	Supported
 
+LINUX TRACE TOOLKIT
+P:	Karim Yaghmour
+M:	karim@opersys.com
+P:	Mathieu Desnoyers
+M:	mathieu.desnoyers@polymtl.ca
+W:	http://www.opersys.com/LTT
+W:	http://ltt.polymtl.ca
+L:	ltt-dev@listserv.shafik.org
+S:	Maintained
+
 LM83 HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
diff -uNrp linux-2.6.14.5/Makefile linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/Makefile
--- linux-2.6.14.5/Makefile	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/Makefile	2006-01-22 13:01:14.000000000 +0100
@@ -582,7 +582,7 @@ export MODLIB
 
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
+core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ ltt/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
diff -uNrp linux-2.6.14.5/mm/filemap.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/filemap.c
--- linux-2.6.14.5/mm/filemap.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/filemap.c	2006-01-22 13:01:14.000000000 +0100
@@ -9,6 +9,7 @@
  * most "normal" filesystems (but you don't /have/ to use this:
  * the NFS filesystem used to do this differently, for example)
  */
+#include <linux/ltt/ltt-facility-memory.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -435,9 +436,13 @@ void fastcall wait_on_page_bit(struct pa
 {
 	DEFINE_WAIT_BIT(wait, &page->flags, bit_nr);
 
+	trace_memory_page_wait_start(page_address(page));
+
 	if (test_bit(bit_nr, &page->flags))
 		__wait_on_bit(page_waitqueue(page), &wait, sync_page,
 							TASK_UNINTERRUPTIBLE);
+
+	trace_memory_page_wait_end(page_address(page));
 }
 EXPORT_SYMBOL(wait_on_page_bit);
 
diff -uNrp linux-2.6.14.5/mm/memory.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/memory.c
--- linux-2.6.14.5/mm/memory.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/memory.c	2006-01-22 13:01:14.000000000 +0100
@@ -38,6 +38,7 @@
  * Aug/Sep 2004 Changed to four level page tables (Andi Kleen)
  */
 
+#include <linux/ltt/ltt-facility-memory.h>
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
@@ -49,6 +50,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
+#include <linux/module.h>
+
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
@@ -1670,6 +1673,7 @@ static int do_swap_page(struct mm_struct
 	spin_unlock(&mm->page_table_lock);
 	page = lookup_swap_cache(entry);
 	if (!page) {
+		trace_memory_swap_in((void*)address);
  		swapin_readahead(entry, address, vma);
  		page = read_swap_cache_async(entry, vma, address);
 		if (!page) {
diff -uNrp linux-2.6.14.5/mm/page_alloc.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/page_alloc.c
--- linux-2.6.14.5/mm/page_alloc.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/page_alloc.c	2006-01-22 13:01:14.000000000 +0100
@@ -14,6 +14,7 @@
  *          (lots of bits borrowed from Ingo Molnar & Andrew Morton)
  */
 
+#include <linux/ltt/ltt-facility-memory.h>
 #include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/mm.h>
@@ -371,6 +372,8 @@ void __free_pages_ok(struct page *page, 
 	LIST_HEAD(list);
 	int i;
 
+	trace_memory_page_free(order, page_address(page));
+
 	arch_free_page(page, order);
 
 	mod_page_state(pgfree, 1 << order);
@@ -983,6 +986,7 @@ fastcall unsigned long __get_free_pages(
 	page = alloc_pages(gfp_mask, order);
 	if (!page)
 		return 0;
+	trace_memory_page_alloc(order, page_address(page));
 	return (unsigned long) page_address(page);
 }
 
diff -uNrp linux-2.6.14.5/mm/page_io.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/page_io.c
--- linux-2.6.14.5/mm/page_io.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/page_io.c	2006-01-22 13:01:14.000000000 +0100
@@ -10,6 +10,7 @@
  *  Always use brw_page, life becomes simpler. 12 May 1998 Eric Biederman
  */
 
+#include <linux/ltt/ltt-facility-memory.h>
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/pagemap.h>
@@ -102,6 +103,7 @@ int swap_writepage(struct page *page, st
 		rw |= (1 << BIO_RW_SYNC);
 	inc_page_state(pswpout);
 	set_page_writeback(page);
+	trace_memory_swap_out(page_address(page));
 	unlock_page(page);
 	submit_bio(rw, bio);
 out:
diff -uNrp linux-2.6.14.5/mm/vmalloc.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/vmalloc.c
--- linux-2.6.14.5/mm/vmalloc.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/mm/vmalloc.c	2006-01-22 13:01:14.000000000 +0100
@@ -18,6 +18,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
 
 
 DEFINE_RWLOCK(vmlist_lock);
@@ -148,10 +149,14 @@ int map_vm_area(struct vm_struct *area, 
 	pgd = pgd_offset_k(addr);
 	spin_lock(&init_mm.page_table_lock);
 	do {
+		pgd_t oldpgd;
+		memcpy(&oldpgd,pgd,sizeof(pgd_t));
 		next = pgd_addr_end(addr, end);
 		err = vmap_pud_range(pgd, addr, next, prot, pages);
 		if (err)
 			break;
+		if (pgd_val(oldpgd) != pgd_val(*pgd))
+			set_pgdir(addr, *pgd);
 	} while (pgd++, addr = next, addr != end);
 	spin_unlock(&init_mm.page_table_lock);
 	flush_cache_vmap((unsigned long) area->addr, end);
diff -uNrp linux-2.6.14.5/net/core/dev.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/net/core/dev.c
--- linux-2.6.14.5/net/core/dev.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/net/core/dev.c	2006-01-22 13:01:14.000000000 +0100
@@ -72,6 +72,7 @@
  *				        - netif_rx() feedback
  */
 
+#include <linux/ltt/ltt-facility-network.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <linux/bitops.h>
@@ -1259,6 +1260,8 @@ int dev_queue_xmit(struct sk_buff *skb)
 	      	if (skb_checksum_help(skb, 0))
 	      		goto out_kfree_skb;
 
+	trace_network_packet_out(skb, skb->protocol);
+
 	spin_lock_prefetch(&dev->queue_lock);
 
 	/* Disable soft irqs for various locks below. Also 
@@ -1584,6 +1587,8 @@ int netif_receive_skb(struct sk_buff *sk
 
 	__get_cpu_var(netdev_rx_stat).total++;
 
+	trace_network_packet_in(skb, skb->protocol);
+
 	skb->h.raw = skb->nh.raw = skb->data;
 	skb->mac_len = skb->nh.raw - skb->mac.raw;
 
diff -uNrp linux-2.6.14.5/net/socket.c linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/net/socket.c
--- linux-2.6.14.5/net/socket.c	2005-12-27 01:26:33.000000000 +0100
+++ linux-2.6.14.5-ipipe-1.1-lttng-0.5-v3/net/socket.c	2006-01-22 13:01:14.000000000 +0100
@@ -58,6 +58,7 @@
  *	Based upon Swansea University Computer Society NET3.039
  */
 
+#include <linux/ltt/ltt-facility-socket.h>
 #include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
@@ -556,6 +557,11 @@ int sock_sendmsg(struct socket *sock, st
 	struct sock_iocb siocb;
 	int ret;
 
+	trace_socket_sendmsg(sock, sock->sk->sk_family,
+												sock->sk->sk_type,
+												sock->sk->sk_protocol,
+												size);
+
 	init_sync_kiocb(&iocb, NULL);
 	iocb.private = &siocb;
 	ret = __sock_sendmsg(&iocb, sock, msg, size);
@@ -608,6 +614,11 @@ int sock_recvmsg(struct socket *sock, st
 	struct sock_iocb siocb;
 	int ret;
 
+	trace_socket_recvmsg(sock, sock->sk->sk_family,
+												sock->sk->sk_type,
+												sock->sk->sk_protocol,
+												size);
+
         init_sync_kiocb(&iocb, NULL);
 	iocb.private = &siocb;
 	ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
@@ -1199,6 +1210,11 @@ asmlinkage long sys_socket(int family, i
 	if (retval < 0)
 		goto out_release;
 
+	trace_socket_create(sock, family,
+											type,
+											protocol,
+											retval);
+
 out:
 	/* It may be already another descriptor 8) Not kernel problem. */
 	return retval;
@@ -1926,6 +1942,8 @@ asmlinkage long sys_socketcall(int call,
 
 	a0=a[0];
 	a1=a[1];
+
+	trace_socket_call(call, a0);
 	
 	switch(call) 
 	{
