linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch-early-RFC 00/10] LTTng architecture dependent instrumentation
@ 2007-12-06  2:56 Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 01/10] LTTng - ARM instrumentation Mathieu Desnoyers
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel

Hi,

Here is the architecture dependent instrumentation for LTTng. Not all
architectures are supported, and some of them have missing instrumentation
points.

The most complete should be :
x86_32, x86_64, powerpc, mips and arm.

It depends on the kernel trace thread flag patchset.

It instruments :
- traps/faults
- system calls
- kernel thread creation
- IPC calls

Mathieu

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 01/10] LTTng - ARM instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 02/10] LTTng - x86_32 instrumentation Mathieu Desnoyers
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-arm.patch --]
[-- Type: text/plain, Size: 4407 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/arm/kernel/entry-common.S |    8 ++++----
 arch/arm/kernel/process.c      |    6 +++++-
 arch/arm/kernel/ptrace.c       |    6 ++++++
 arch/arm/kernel/sys_arm.c      |    2 ++
 arch/arm/kernel/traps.c        |    7 +++++++
 5 files changed, 24 insertions(+), 5 deletions(-)

Index: linux-2.6-lttng/arch/arm/kernel/entry-common.S
===================================================================
--- linux-2.6-lttng.orig/arch/arm/kernel/entry-common.S	2007-10-11 11:44:13.000000000 -0400
+++ linux-2.6-lttng/arch/arm/kernel/entry-common.S	2007-10-11 11:44:57.000000000 -0400
@@ -85,8 +85,8 @@ ENTRY(ret_from_fork)
 	get_thread_info tsk
 	ldr	r1, [tsk, #TI_FLAGS]		@ check for syscall tracing
 	mov	why, #1
-	tst	r1, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
-	beq	ret_slow_syscall
+	tst	r1, #_TIF_SYSCALL_TRACE | _TIF_KERNEL_TRACE
+	beq	ret_slow_syscall		@ are we tracing syscalls?
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	syscall_trace
@@ -205,8 +205,8 @@ ENTRY(vector_swi)
 #endif
 
 	stmdb	sp!, {r4, r5}			@ push fifth and sixth args
-	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
-	bne	__sys_trace
+	tst	ip, #_TIF_SYSCALL_TRACE | _TIF_KERNEL_TRACE
+	bne	__sys_trace			@ are we tracing syscalls?
 
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
 	adr	lr, ret_fast_syscall		@ return address
Index: linux-2.6-lttng/arch/arm/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/arm/kernel/process.c	2007-10-11 11:44:13.000000000 -0400
+++ linux-2.6-lttng/arch/arm/kernel/process.c	2007-10-11 14:46:50.000000000 -0400
@@ -418,6 +418,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));
 
@@ -427,7 +428,10 @@ 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);
+
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
 }
 EXPORT_SYMBOL(kernel_thread);
 
Index: linux-2.6-lttng/arch/arm/kernel/ptrace.c
===================================================================
--- linux-2.6-lttng.orig/arch/arm/kernel/ptrace.c	2007-10-11 11:44:13.000000000 -0400
+++ linux-2.6-lttng/arch/arm/kernel/ptrace.c	2007-10-11 14:48:21.000000000 -0400
@@ -789,6 +789,12 @@ asmlinkage int syscall_trace(int why, st
 {
 	unsigned long ip;
 
+	if (!why)
+		trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+			scno, instruction_pointer(regs));
+	else
+		trace_mark(kernel_arch_syscall_exit, MARK_NOARGS);
+
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return scno;
 	if (!(current->ptrace & PT_PTRACED))
Index: linux-2.6-lttng/arch/arm/kernel/sys_arm.c
===================================================================
--- linux-2.6-lttng.orig/arch/arm/kernel/sys_arm.c	2007-10-11 11:44:13.000000000 -0400
+++ linux-2.6-lttng/arch/arm/kernel/sys_arm.c	2007-10-11 14:47:23.000000000 -0400
@@ -161,6 +161,8 @@ asmlinkage int sys_ipc(uint call, int fi
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	switch (call) {
 	case SEMOP:
 		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
Index: linux-2.6-lttng/arch/arm/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/arm/kernel/traps.c	2007-10-11 11:44:13.000000000 -0400
+++ linux-2.6-lttng/arch/arm/kernel/traps.c	2007-10-11 14:48:11.000000000 -0400
@@ -269,7 +269,14 @@ void arm_notify_die(const char *str, str
 		current->thread.error_code = err;
 		current->thread.trap_no = trap;
 
+		trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld",
+			current->thread.trap_no,
+			instruction_pointer(regs));
+
 		force_sig_info(info->si_signo, info, current);
+
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
+
 	} else {
 		die(str, regs, err);
 	}

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 02/10] LTTng - x86_32 instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 01/10] LTTng - ARM instrumentation Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 03/10] LTTng - MIPS instrumentation Mathieu Desnoyers
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel
  Cc: Mathieu Desnoyers, Thomas Gleixner, Ingo Molnar, H. Peter Anvin

[-- Attachment #1: lttng-instrumentation-i386.patch --]
[-- Type: text/plain, Size: 14456 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
CC: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/apic_32.c       |   21 +++++++++++++++++++++
 arch/x86/kernel/cpu/mcheck/p4.c |    7 +++++++
 arch/x86/kernel/entry_32.S      |    6 +++---
 arch/x86/kernel/process_32.c    |    6 +++++-
 arch/x86/kernel/ptrace_32.c     |    6 ++++++
 arch/x86/kernel/smp_32.c        |   18 ++++++++++++++++++
 arch/x86/kernel/sys_i386_32.c   |    2 ++
 arch/x86/kernel/traps_32.c      |   38 +++++++++++++++++++++++++++++++-------
 arch/x86/mm/fault_32.c          |    7 +++++++
 9 files changed, 100 insertions(+), 11 deletions(-)

Index: linux-2.6-lttng/arch/x86/kernel/process_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/process_32.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/process_32.c	2007-12-05 21:48:05.000000000 -0500
@@ -374,6 +374,7 @@ extern void kernel_thread_helper(void);
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	struct pt_regs regs;
+	long pid;
 
 	memset(&regs, 0, sizeof(regs));
 
@@ -389,7 +390,10 @@ 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);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
 }
 EXPORT_SYMBOL(kernel_thread);
 
Index: linux-2.6-lttng/arch/x86/kernel/ptrace_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/ptrace_32.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/ptrace_32.c	2007-12-05 21:48:05.000000000 -0500
@@ -650,6 +650,12 @@ int do_syscall_trace(struct pt_regs *reg
 	int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
 	int ret = 0;
 
+	if (!entryexit)
+		trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+			(int)regs->orig_eax, instruction_pointer(regs));
+	else
+		trace_mark(kernel_arch_syscall_exit, "ret %ld", regs->eax);
+
 	/* do the secure computing check first */
 	if (!entryexit)
 		secure_computing(regs->orig_eax);
Index: linux-2.6-lttng/arch/x86/kernel/sys_i386_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/sys_i386_32.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/sys_i386_32.c	2007-12-05 21:48:05.000000000 -0500
@@ -128,6 +128,8 @@ asmlinkage int sys_ipc (uint call, int f
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	switch (call) {
 	case SEMOP:
 		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
Index: linux-2.6-lttng/arch/x86/kernel/traps_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/traps_32.c	2007-12-05 21:48:04.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/traps_32.c	2007-12-05 21:48:05.000000000 -0500
@@ -455,6 +455,9 @@ static void __kprobes do_trap(int trapnr
 {
 	struct task_struct *tsk = current;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", trapnr,
+		instruction_pointer(regs));
+
 	if (regs->eflags & VM_MASK) {
 		if (vm86)
 			goto vm86_trap;
@@ -481,7 +484,7 @@ static void __kprobes do_trap(int trapnr
 			force_sig_info(signr, info, tsk);
 		else
 			force_sig(signr, tsk);
-		return;
+		goto end;
 	}
 
 	kernel_trap: {
@@ -490,14 +493,16 @@ static void __kprobes do_trap(int trapnr
 			tsk->thread.trap_no = trapnr;
 			die(str, regs, error_code);
 		}
-		return;
+		goto end;
 	}
 
 	vm86_trap: {
 		int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
 		if (ret) goto trap_signal;
-		return;
+		goto end;
 	}
+end:
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #define DO_ERROR(trapnr, signr, str, name) \
@@ -611,7 +616,10 @@ fastcall void __kprobes do_general_prote
 		    current->comm, task_pid_nr(current),
 		    regs->eip, regs->esp, error_code);
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", 13,
+			instruction_pointer(regs));
 	force_sig(SIGSEGV, current);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	return;
 
 gp_in_vm86:
@@ -731,25 +739,28 @@ static __kprobes void default_do_nmi(str
 	if (!smp_processor_id())
 		reason = get_nmi_reason();
  
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", 2,
+		instruction_pointer(regs));
+
 	if (!(reason & 0xc0)) {
 		if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
 							== NOTIFY_STOP)
-			return;
+			goto end;
 #ifdef CONFIG_X86_LOCAL_APIC
 		/*
 		 * Ok, so this is none of the documented NMI sources,
 		 * so it must be the NMI watchdog.
 		 */
 		if (nmi_watchdog_tick(regs, reason))
-			return;
+			goto end;
 		if (!do_nmi_callback(regs, smp_processor_id()))
 #endif
 			unknown_nmi_error(reason, regs);
 
-		return;
+		goto end;
 	}
 	if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
-		return;
+		goto end;
 	if (reason & 0x80)
 		mem_parity_error(reason, regs);
 	if (reason & 0x40)
@@ -759,6 +770,8 @@ static __kprobes void default_do_nmi(str
 	 * as it's edge-triggered.
 	 */
 	reassert_nmi();
+end:
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 static int ignore_nmis;
@@ -873,7 +886,10 @@ fastcall void __kprobes do_debug(struct 
 	}
 
 	/* Ok, finally something we can handle */
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+			1, instruction_pointer(regs));
 	send_sigtrap(tsk, regs, error_code);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 
 	/* Disable additional traps. They'll be re-enabled when
 	 * the signal is delivered.
@@ -883,7 +899,10 @@ clear_dr7:
 	return;
 
 debug_vm86:
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+			1, instruction_pointer(regs));
 	handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	return;
 
 clear_TF_reenable:
@@ -1037,10 +1056,13 @@ fastcall void do_simd_coprocessor_error(
 fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
 					  long error_code)
 {
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+			16, instruction_pointer(regs));
 #if 0
 	/* No need to warn about this any longer. */
 	printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
 #endif
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
@@ -1091,8 +1113,10 @@ asmlinkage void math_emulate(long arg)
 {
 	printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n");
 	printk(KERN_EMERG "killing %s.\n",current->comm);
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", 7, 0L);
 	force_sig(SIGFPE,current);
 	schedule();
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #endif /* CONFIG_MATH_EMULATION */
Index: linux-2.6-lttng/arch/x86/kernel/entry_32.S
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/entry_32.S	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/entry_32.S	2007-12-05 21:48:05.000000000 -0500
@@ -333,7 +333,7 @@ sysenter_past_esp:
 	GET_THREAD_INFO(%ebp)
 
 	/* 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)
+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
@@ -371,7 +371,7 @@ ENTRY(system_call)
 	GET_THREAD_INFO(%ebp)
 					# 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)
+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
@@ -528,7 +528,7 @@ END(syscall_trace_entry)
 	# perform syscall exit tracing
 	ALIGN
 syscall_exit_work:
-	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
+	testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|_TIF_KERNEL_TRACE), %cx
 	jz work_pending
 	TRACE_IRQS_ON
 	ENABLE_INTERRUPTS(CLBR_ANY)	# could let do_syscall_trace() call
Index: linux-2.6-lttng/arch/x86/mm/fault_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/mm/fault_32.c	2007-12-05 21:05:50.000000000 -0500
+++ linux-2.6-lttng/arch/x86/mm/fault_32.c	2007-12-05 21:48:16.000000000 -0500
@@ -426,7 +426,10 @@ good_area:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		14, instruction_pointer(regs));
 	fault = handle_mm_fault(mm, vma, address, write);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
@@ -465,6 +468,9 @@ bad_area_nosemaphore:
 		 */
 		local_irq_enable();
 
+		trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		    14, instruction_pointer(regs));
+
 		/* 
 		 * Valid to do another page fault here because this one came 
 		 * from user space.
@@ -485,6 +491,7 @@ bad_area_nosemaphore:
 		tsk->thread.error_code = error_code | (address >= TASK_SIZE);
 		tsk->thread.trap_no = 14;
 		force_sig_info_fault(SIGSEGV, si_code, address, tsk);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
Index: linux-2.6-lttng/arch/x86/kernel/apic_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/apic_32.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/apic_32.c	2007-12-05 21:48:28.000000000 -0500
@@ -592,7 +592,14 @@ void fastcall smp_apic_timer_interrupt(s
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		LOCAL_TIMER_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	local_apic_timer_interrupt();
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 
 	set_irq_regs(old_regs);
@@ -1265,6 +1272,10 @@ void smp_spurious_interrupt(struct pt_re
 	unsigned long v;
 
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		SPURIOUS_APIC_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	/*
 	 * Check if this really is a spurious interrupt and ACK it
 	 * if it is a vectored one.  Just in case...
@@ -1278,6 +1289,9 @@ void smp_spurious_interrupt(struct pt_re
 	printk(KERN_INFO "spurious APIC interrupt on CPU#%d, "
 	       "should never happen.\n", smp_processor_id());
 	__get_cpu_var(irq_stat).irq_spurious_count++;
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
@@ -1289,6 +1303,10 @@ void smp_error_interrupt(struct pt_regs 
 	unsigned long v, v1;
 
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		ERROR_APIC_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	/* First tickle the hardware, only then report what went on. -- REW */
 	v = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
@@ -1308,6 +1326,9 @@ void smp_error_interrupt(struct pt_regs 
 	*/
 	printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
 		smp_processor_id(), v , v1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
Index: linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/p4.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/cpu/mcheck/p4.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/p4.c	2007-12-05 21:48:28.000000000 -0500
@@ -60,8 +60,15 @@ static void (*vendor_thermal_interrupt)(
 fastcall void smp_thermal_interrupt(struct pt_regs *regs)
 {
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		THERMAL_APIC_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	vendor_thermal_interrupt(regs);
 	__get_cpu_var(irq_stat).irq_thermal_count++;
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
Index: linux-2.6-lttng/arch/x86/kernel/smp_32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/smp_32.c	2007-12-05 21:05:49.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/smp_32.c	2007-12-05 21:48:28.000000000 -0500
@@ -327,6 +327,9 @@ fastcall void smp_invalidate_interrupt(s
 		 * BUG();
 		 */
 		 
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		INVALIDATE_TLB_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
 		if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
 			if (flush_va == TLB_FLUSH_ALL)
@@ -343,6 +346,8 @@ fastcall void smp_invalidate_interrupt(s
 out:
 	put_cpu_no_resched();
 	__get_cpu_var(irq_stat).irq_tlb_count++;
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
 }
 
 void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
@@ -641,7 +646,13 @@ static void native_smp_send_stop(void)
 fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
 {
 	ack_APIC_irq();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		RESCHEDULE_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	__get_cpu_var(irq_stat).irq_resched_count++;
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
 }
 
 fastcall void smp_call_function_interrupt(struct pt_regs *regs)
@@ -661,8 +672,15 @@ fastcall void smp_call_function_interrup
 	 * At this point the info structure may be out of scope unless wait==1
 	 */
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		CALL_FUNCTION_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	(*func)(info);
 	__get_cpu_var(irq_stat).irq_call_count++;
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 
 	if (wait) {

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 03/10] LTTng - MIPS instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 01/10] LTTng - ARM instrumentation Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 02/10] LTTng - x86_32 instrumentation Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 04/10] LTTng instrumentation Powerpc Mathieu Desnoyers
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-mips.patch --]
[-- Type: text/plain, Size: 8240 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/mips/kernel/entry.S     |    2 +-
 arch/mips/kernel/process.c   |    6 +++++-
 arch/mips/kernel/ptrace.c    |    7 +++++++
 arch/mips/kernel/syscall.c   |    2 ++
 arch/mips/kernel/traps.c     |   16 ++++++++++++----
 arch/mips/kernel/unaligned.c |   11 ++++++++++-
 arch/mips/mm/fault.c         |    3 +++
 include/asm-mips/mipsregs.h  |    1 +
 8 files changed, 41 insertions(+), 7 deletions(-)

Index: linux-2.6-lttng/arch/mips/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/process.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/process.c	2007-11-20 13:19:04.000000000 -0500
@@ -226,6 +226,7 @@ static void __noreturn kernel_thread_hel
 long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 	struct pt_regs regs;
+	long pid;
 
 	memset(&regs, 0, sizeof(regs));
 
@@ -241,7 +242,10 @@ long kernel_thread(int (*fn)(void *), vo
 #endif
 
 	/* 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);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
 }
 
 /*
Index: linux-2.6-lttng/arch/mips/kernel/ptrace.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/ptrace.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/ptrace.c	2007-11-20 13:19:52.000000000 -0500
@@ -466,6 +466,13 @@ static inline int audit_arch(void)
  */
 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
+	if (!entryexit)
+		trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+			(int)regs->regs[2], instruction_pointer(regs));
+	else
+		trace_mark(kernel_arch_syscall_exit, "ret %ld",
+			regs->regs[2]);
+
 	/* do the secure computing check first */
 	if (!entryexit)
 		secure_computing(regs->regs[0]);
Index: linux-2.6-lttng/arch/mips/kernel/syscall.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/syscall.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/syscall.c	2007-11-20 13:19:04.000000000 -0500
@@ -327,6 +327,8 @@ asmlinkage int sys_ipc(unsigned int call
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	switch (call) {
 	case SEMOP:
 		return sys_semtimedop(first, (struct sembuf __user *)ptr,
Index: linux-2.6-lttng/arch/mips/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/traps.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/traps.c	2007-11-20 13:19:04.000000000 -0500
@@ -293,7 +293,7 @@ static void __show_regs(const struct pt_
 
 	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);
 
@@ -587,6 +587,8 @@ asmlinkage void do_fpe(struct pt_regs *r
 
 	die_if_kernel("FP exception in kernel code", regs);
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %lu ip #p%ld",
+		CAUSE_EXCCODE(regs->cp0_cause), instruction_pointer(regs));
 	if (fcr31 & FPU_CSR_UNI_X) {
 		int sig;
 
@@ -800,6 +802,9 @@ asmlinkage void do_cpu(struct pt_regs *r
 	unsigned int cpid;
 	int status;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %lu ip #p%ld",
+		CAUSE_EXCCODE(regs->cp0_cause), instruction_pointer(regs));
+
 	die_if_kernel("do_cpu invoked from kernel context!", regs);
 
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -811,8 +816,10 @@ asmlinkage void do_cpu(struct pt_regs *r
 		opcode = 0;
 		status = -1;
 
-		if (unlikely(compute_return_epc(regs) < 0))
+		if (unlikely(compute_return_epc(regs) < 0)) {
+			trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 			return;
+		}
 
 		if (unlikely(get_user(opcode, epc) < 0))
 			status = SIGSEGV;
@@ -830,7 +837,7 @@ asmlinkage void do_cpu(struct pt_regs *r
 			regs->cp0_epc = old_epc;	/* Undo skip-over.  */
 			force_sig(status, current);
 		}
-
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 
 	case 1:
@@ -850,7 +857,7 @@ asmlinkage void do_cpu(struct pt_regs *r
 			else
 				mt_ase_fp_affinity();
 		}
-
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 
 	case 2:
@@ -859,6 +866,7 @@ asmlinkage void do_cpu(struct pt_regs *r
 	}
 
 	force_sig(SIGILL, current);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 asmlinkage void do_mdmx(struct pt_regs *regs)
Index: linux-2.6-lttng/arch/mips/kernel/unaligned.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/unaligned.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/unaligned.c	2007-11-20 13:19:04.000000000 -0500
@@ -503,14 +503,19 @@ asmlinkage void do_ade(struct pt_regs *r
 	unsigned int __user *pc;
 	mm_segment_t seg;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %lu ip #p%ld",
+		CAUSE_EXCCODE(regs->cp0_cause), instruction_pointer(regs));
+
 	/*
 	 * 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)) {
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
+	}
 
 	/* Otherwise handle as normal */
 
@@ -539,6 +544,8 @@ asmlinkage void do_ade(struct pt_regs *r
 	emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
 	set_fs(seg);
 
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
+
 	return;
 
 sigbus:
@@ -548,6 +555,8 @@ sigbus:
 	/*
 	 * XXX On return from the signal handler we should advance the epc
 	 */
+
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #ifdef CONFIG_DEBUG_FS
Index: linux-2.6-lttng/include/asm-mips/mipsregs.h
===================================================================
--- linux-2.6-lttng.orig/include/asm-mips/mipsregs.h	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/include/asm-mips/mipsregs.h	2007-11-20 13:19:04.000000000 -0500
@@ -384,6 +384,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
Index: linux-2.6-lttng/arch/mips/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/mips/mm/fault.c	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/mm/fault.c	2007-11-20 13:19:04.000000000 -0500
@@ -103,7 +103,10 @@ survive:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+	trace_mark(kernel_arch_trap_entry, "trap_id %lu ip #p%ld",
+		CAUSE_EXCCODE(regs->cp0_cause), instruction_pointer(regs));
 	fault = handle_mm_fault(mm, vma, address, write);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
Index: linux-2.6-lttng/arch/mips/kernel/entry.S
===================================================================
--- linux-2.6-lttng.orig/arch/mips/kernel/entry.S	2007-11-20 13:13:42.000000000 -0500
+++ linux-2.6-lttng/arch/mips/kernel/entry.S	2007-11-20 13:19:04.000000000 -0500
@@ -167,7 +167,7 @@ work_notifysig:				# deal with pending s
 FEXPORT(syscall_exit_work_partial)
 	SAVE_STATIC
 syscall_exit_work:
-	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE
 	and	t0, a2			# a2 is preloaded with TI_FLAGS
 	beqz	t0, work_pending	# trace bit set?
 	local_irq_enable		# could let do_syscall_trace()

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 04/10] LTTng instrumentation Powerpc
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (2 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 03/10] LTTng - MIPS instrumentation Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 05/10] LTTng instrumentation PPC Mathieu Desnoyers
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-powerpc.patch --]
[-- Type: text/plain, Size: 7148 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/powerpc/kernel/misc_32.S  |    2 +-
 arch/powerpc/kernel/misc_64.S  |    2 +-
 arch/powerpc/kernel/process.c  |   11 +++++++++++
 arch/powerpc/kernel/ptrace.c   |    4 ++++
 arch/powerpc/kernel/syscalls.c |    2 ++
 arch/powerpc/kernel/time.c     |    5 +++++
 arch/powerpc/kernel/traps.c    |   11 +++++++++++
 arch/powerpc/mm/fault.c        |    3 +++
 8 files changed, 38 insertions(+), 2 deletions(-)

Index: linux-2.6-lttng/arch/powerpc/kernel/misc_32.S
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/misc_32.S	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/misc_32.S	2007-11-28 09:33:42.000000000 -0500
@@ -766,7 +766,7 @@ _GLOBAL(abs)
  * Create a kernel thread
  *   kernel_thread(fn, arg, flags)
  */
-_GLOBAL(kernel_thread)
+_GLOBAL(original_kernel_thread)
 	stwu	r1,-16(r1)
 	stw	r30,8(r1)
 	stw	r31,12(r1)
Index: linux-2.6-lttng/arch/powerpc/kernel/misc_64.S
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/misc_64.S	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/misc_64.S	2007-11-28 09:33:42.000000000 -0500
@@ -427,7 +427,7 @@ _GLOBAL(scom970_write)
  * Create a kernel thread
  *   kernel_thread(fn, arg, flags)
  */
-_GLOBAL(kernel_thread)
+_GLOBAL(original_kernel_thread)
 	std	r29,-24(r1)
 	std	r30,-16(r1)
 	stdu	r1,-STACK_FRAME_OVERHEAD(r1)
Index: linux-2.6-lttng/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/process.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/process.c	2007-11-28 09:33:42.000000000 -0500
@@ -488,6 +488,17 @@ void show_regs(struct pt_regs * regs)
 		show_instructions(regs);
 }
 
+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);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", retval, fn);
+	return retval;
+}
+
 void exit_thread(void)
 {
 	discard_lazy_cpu_state();
Index: linux-2.6-lttng/arch/powerpc/kernel/ptrace.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/ptrace.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/ptrace.c	2007-11-28 09:33:42.000000000 -0500
@@ -624,6 +624,8 @@ static void do_syscall_trace(void)
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
+	trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+		(int)regs->gpr[0], instruction_pointer(regs));
 	secure_computing(regs->gpr[0]);
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE)
@@ -650,6 +652,8 @@ void do_syscall_trace_enter(struct pt_re
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
+	trace_mark(kernel_arch_syscall_exit, "ret %ld", regs->result);
+
 	if (unlikely(current->audit_context))
 		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
 				   regs->result);
Index: linux-2.6-lttng/arch/powerpc/kernel/syscalls.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/syscalls.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/syscalls.c	2007-11-28 09:33:42.000000000 -0500
@@ -56,6 +56,8 @@ int sys_ipc(uint call, int first, unsign
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	ret = -ENOSYS;
 	switch (call) {
 	case SEMOP:
Index: linux-2.6-lttng/arch/powerpc/kernel/time.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/time.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/time.c	2007-11-28 09:33:42.000000000 -0500
@@ -564,6 +564,9 @@ void timer_interrupt(struct pt_regs * re
 	 * some CPUs will continuue to take decrementer exceptions */
 	set_dec(DECREMENTER_MAX);
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld", regs->trap,
+		instruction_pointer(regs));
+
 #ifdef CONFIG_PPC32
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
@@ -605,6 +608,8 @@ void timer_interrupt(struct pt_regs * re
 
 	irq_exit();
 	set_irq_regs(old_regs);
+
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 void wakeup_decrementer(void)
Index: linux-2.6-lttng/arch/powerpc/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/traps.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/kernel/traps.c	2007-11-28 09:33:42.000000000 -0500
@@ -188,6 +188,9 @@ void _exception(int signr, struct pt_reg
 				addr, regs->nip, regs->link, code);
 		}
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld", regs->trap,
+		instruction_pointer(regs));
+
 	memset(&info, 0, sizeof(info));
 	info.si_signo = signr;
 	info.si_code = code;
@@ -215,6 +218,8 @@ void _exception(int signr, struct pt_reg
 			do_exit(signr);
 		}
 	}
+
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #ifdef CONFIG_PPC64
@@ -908,7 +913,10 @@ void altivec_unavailable_exception(struc
 
 void performance_monitor_exception(struct pt_regs *regs)
 {
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld", regs->trap,
+		instruction_pointer(regs));
 	perf_irq(regs);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #ifdef CONFIG_8xx
@@ -1020,12 +1028,15 @@ void altivec_assist_exception(struct pt_
 		/* got an error reading the instruction */
 		_exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
 	} else {
+		trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld",
+			regs->trap, instruction_pointer(regs));
 		/* didn't recognize the instruction */
 		/* XXX quick hack for now: set the non-Java bit in the VSCR */
 		if (printk_ratelimit())
 			printk(KERN_ERR "Unrecognized altivec instruction "
 			       "in %s at %lx\n", current->comm, regs->nip);
 		current->thread.vscr.u[3] |= 0x10000;
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	}
 }
 #endif /* CONFIG_ALTIVEC */
Index: linux-2.6-lttng/arch/powerpc/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/mm/fault.c	2007-11-28 09:27:28.000000000 -0500
+++ linux-2.6-lttng/arch/powerpc/mm/fault.c	2007-11-28 09:33:42.000000000 -0500
@@ -336,7 +336,10 @@ good_area:
 	 * the fault.
 	 */
  survive:
+ 	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld", regs->trap,
+		instruction_pointer(regs));
 	ret = handle_mm_fault(mm, vma, address, is_write);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	if (unlikely(ret & VM_FAULT_ERROR)) {
 		if (ret & VM_FAULT_OOM)
 			goto out_of_memory;

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 05/10] LTTng instrumentation PPC
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (3 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 04/10] LTTng instrumentation Powerpc Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 06/10] LTTng - instrumentation SH Mathieu Desnoyers
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-ppc.patch --]
[-- Type: text/plain, Size: 3143 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/ppc/kernel/misc.S  |    2 +-
 arch/ppc/kernel/time.c  |    4 ++++
 arch/ppc/kernel/traps.c |    3 +++
 arch/ppc/mm/fault.c     |    3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

Index: linux-2.6-lttng/arch/ppc/kernel/misc.S
===================================================================
--- linux-2.6-lttng.orig/arch/ppc/kernel/misc.S	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/ppc/kernel/misc.S	2007-11-13 09:50:11.000000000 -0500
@@ -868,7 +868,7 @@ _GLOBAL(_get_SP)
  * Create a kernel thread
  *   kernel_thread(fn, arg, flags)
  */
-_GLOBAL(kernel_thread)
+_GLOBAL(original_kernel_thread)
 	stwu	r1,-16(r1)
 	stw	r30,8(r1)
 	stw	r31,12(r1)
Index: linux-2.6-lttng/arch/ppc/kernel/time.c
===================================================================
--- linux-2.6-lttng.orig/arch/ppc/kernel/time.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/ppc/kernel/time.c	2007-11-13 09:50:11.000000000 -0500
@@ -139,7 +139,10 @@ void timer_interrupt(struct pt_regs * re
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld",
+		regs->trap, instruction_pointer(regs));
 	old_regs = set_irq_regs(regs);
+
 	irq_enter();
 
 	while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) {
@@ -192,6 +195,7 @@ void timer_interrupt(struct pt_regs * re
 
 	irq_exit();
 	set_irq_regs(old_regs);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 /*
Index: linux-2.6-lttng/arch/ppc/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/ppc/kernel/traps.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/ppc/kernel/traps.c	2007-11-13 09:50:11.000000000 -0500
@@ -108,11 +108,14 @@ void _exception(int signr, struct pt_reg
 		debugger(regs);
 		die("Exception in kernel mode", regs, signr);
 	}
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld", regs->trap,
+		instruction_pointer(regs));
 	info.si_signo = signr;
 	info.si_errno = 0;
 	info.si_code = code;
 	info.si_addr = (void __user *) addr;
 	force_sig_info(signr, &info, current);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 
 	/*
 	 * Init gets no signals that it doesn't have a handler for.
Index: linux-2.6-lttng/arch/ppc/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/ppc/mm/fault.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/ppc/mm/fault.c	2007-11-13 09:50:11.000000000 -0500
@@ -250,7 +250,10 @@ good_area:
 	 * the fault.
 	 */
  survive:
+ 	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld",
+		regs->trap, instruction_pointer(regs));
 	fault = handle_mm_fault(mm, vma, address, is_write);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 06/10] LTTng - instrumentation SH
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (4 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 05/10] LTTng instrumentation PPC Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 07/10] LTTng instrumentation SH64 Mathieu Desnoyers
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-sh.patch --]
[-- Type: text/plain, Size: 6444 bytes --]

Changelog:
- fix do_fork instrumentation

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/sh/kernel/entry-common.S |   10 ++++++----
 arch/sh/kernel/process.c      |    5 ++++-
 arch/sh/kernel/ptrace.c       |    8 +++++++-
 arch/sh/kernel/sys_sh.c       |    2 ++
 arch/sh/kernel/traps.c        |   10 ++++++++--
 arch/sh/mm/fault.c            |   12 ++++++++++++
 6 files changed, 39 insertions(+), 8 deletions(-)

Index: linux-2.6-lttng/arch/sh/kernel/entry-common.S
===================================================================
--- linux-2.6-lttng.orig/arch/sh/kernel/entry-common.S	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/kernel/entry-common.S	2007-11-26 13:37:12.000000000 -0500
@@ -224,7 +224,7 @@ work_resched:
 syscall_exit_work:
 	! r0: current_thread_info->flags
 	! r8: current_thread_info
-	tst	#_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0
+	tst	#_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_KERNEL_TRACE, r0
 	bt/s	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -233,7 +233,8 @@ syscall_exit_work:
 	 nop
 #endif
 	sti
-	! XXX setup arguments...
+	mov	r15,r4			! pass stacked regs as arg
+	mov	#0, r5			! trace entry [0]
 	mov.l	4f, r0			! do_syscall_trace
 	jsr	@r0
 	 nop
@@ -243,7 +244,8 @@ syscall_exit_work:
 	.align	2
 syscall_trace_entry:
 	!                     	Yes it is traced.
-	! XXX setup arguments...
+	mov	r15,r4		! pass stacked regs as arg
+	mov	#1, r5		! trace entry [1]
 	mov.l	4f, r11		! Call do_syscall_trace which notifies
 	jsr	@r11	    	! superior (will chomp R[0-7])
 	 nop
@@ -366,7 +368,7 @@ ENTRY(system_call)
 	!
 	get_current_thread_info r8, r10
 	mov.l	@(TI_FLAGS,r8), r8
-	mov	#_TIF_SYSCALL_TRACE, r10
+	mov	#(_TIF_SYSCALL_TRACE | _TIF_KERNEL_TRACE), r10
 	tst	r10, r8
 	bf	syscall_trace_entry
 	!
Index: linux-2.6-lttng/arch/sh/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh/kernel/process.c	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/kernel/process.c	2007-11-28 08:29:11.000000000 -0500
@@ -172,6 +172,7 @@ __asm__(".align 5\n"
 /* Don't use this in BL=1(cli).  Or else, CPU resets! */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
+	unsigned long pid;
 	struct pt_regs regs;
 
 	memset(&regs, 0, sizeof(regs));
@@ -182,8 +183,10 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.sr = (1 << 30);
 
 	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+	pid =  do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
 		       &regs, 0, NULL, NULL);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
 }
 
 /*
Index: linux-2.6-lttng/arch/sh/kernel/sys_sh.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh/kernel/sys_sh.c	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/kernel/sys_sh.c	2007-11-26 13:37:12.000000000 -0500
@@ -192,6 +192,8 @@ asmlinkage int sys_ipc(uint call, int fi
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	if (call <= SEMCTL)
 		switch (call) {
 		case SEMOP:
Index: linux-2.6-lttng/arch/sh/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh/kernel/traps.c	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/kernel/traps.c	2007-11-26 13:37:12.000000000 -0500
@@ -548,6 +548,9 @@ asmlinkage void do_address_error(struct 
 	lookup_exception_vector(error_code);
 #endif
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %lu ip #p%ld",
+		(error_code >> 5), instruction_pointer(regs));
+
 	oldfs = get_fs();
 
 	if (user_mode(regs)) {
@@ -574,8 +577,10 @@ asmlinkage void do_address_error(struct 
 		tmp = handle_unaligned_access(instruction, regs);
 		set_fs(oldfs);
 
-		if (tmp==0)
-			return; /* sorted */
+		if (tmp==0) {
+			trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
+ 			return; /* sorted */
+		}
 #endif
 
 uspace_segv:
@@ -611,6 +616,7 @@ uspace_segv:
 		force_sig(SIGSEGV, current);
 #endif
 	}
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #ifdef CONFIG_SH_DSP
Index: linux-2.6-lttng/arch/sh/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh/mm/fault.c	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/mm/fault.c	2007-11-26 13:37:12.000000000 -0500
@@ -87,6 +87,14 @@ asmlinkage void __kprobes do_page_fault(
 		return;
 	}
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%ld",
+		({
+			unsigned long trapnr;
+			asm volatile("stc	r2_bank,%0": "=r" (trapnr));
+			trapnr;
+		}) >> 5,
+		instruction_pointer(regs));
+
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
@@ -139,6 +147,7 @@ survive:
 		tsk->min_flt++;
 
 	up_read(&mm->mmap_sem);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	return;
 
 /*
@@ -155,6 +164,7 @@ bad_area_nosemaphore:
 		info.si_code = si_code;
 		info.si_addr = (void *) address;
 		force_sig_info(SIGSEGV, &info, tsk);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
@@ -233,6 +243,8 @@ do_sigbus:
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
 		goto no_context;
+
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #ifdef CONFIG_SH_STORE_QUEUES
Index: linux-2.6-lttng/arch/sh/kernel/ptrace.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh/kernel/ptrace.c	2007-11-26 13:36:40.000000000 -0500
+++ linux-2.6-lttng/arch/sh/kernel/ptrace.c	2007-11-26 13:37:12.000000000 -0500
@@ -248,10 +248,16 @@ long arch_ptrace(struct task_struct *chi
 	return ret;
 }
 
-asmlinkage void do_syscall_trace(void)
+asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
 	struct task_struct *tsk = current;
 
+	if (entryexit)
+		trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+			regs->regs[3], instruction_pointer(regs));
+	else
+		trace_mark(kernel_arch_syscall_exit, MARK_NOARGS);
+
 	if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    !test_thread_flag(TIF_SINGLESTEP))
 		return;

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 07/10] LTTng instrumentation SH64
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (5 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 06/10] LTTng - instrumentation SH Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 08/10] LTTng Sparc instrumentation Mathieu Desnoyers
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-sh64.patch --]
[-- Type: text/plain, Size: 2382 bytes --]

traps are missing.
syscall trace missing.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/sh64/kernel/entry.S    |    2 +-
 arch/sh64/kernel/process.c  |    5 ++++-
 arch/sh64/kernel/sys_sh64.c |    2 ++
 3 files changed, 7 insertions(+), 2 deletions(-)

Index: linux-2.6-lttng/arch/sh64/kernel/entry.S
===================================================================
--- linux-2.6-lttng.orig/arch/sh64/kernel/entry.S	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sh64/kernel/entry.S	2007-11-13 09:50:15.000000000 -0500
@@ -1282,7 +1282,7 @@ syscall_allowed:
 
 	getcon	KCR0, r2
 	ld.l	r2, TI_FLAGS, r4
-	movi	(1 << TIF_SYSCALL_TRACE), r6
+	movi	(_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), r6
 	and	r6, r4, r6
 	beq/l	r6, ZERO, tr0
 
Index: linux-2.6-lttng/arch/sh64/kernel/sys_sh64.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh64/kernel/sys_sh64.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sh64/kernel/sys_sh64.c	2007-11-13 09:50:15.000000000 -0500
@@ -187,6 +187,8 @@ asmlinkage int sys_ipc(uint call, int fi
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	if (call <= SEMCTL)
 		switch (call) {
 		case SEMOP:
Index: linux-2.6-lttng/arch/sh64/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/sh64/kernel/process.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sh64/kernel/process.c	2007-11-13 09:50:15.000000000 -0500
@@ -393,6 +393,7 @@ ATTRIB_NORET void kernel_thread_helper(v
  */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
+	unsigned long pid;
 	struct pt_regs regs;
 
 	memset(&regs, 0, sizeof(regs));
@@ -402,8 +403,10 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.pc = (unsigned long)kernel_thread_helper;
 	regs.sr = (1 << 30);
 
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+	pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
 		       &regs, 0, NULL, NULL);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
 }
 
 /*

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 08/10] LTTng Sparc instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (6 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 07/10] LTTng instrumentation SH64 Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:56 ` [patch-early-RFC 09/10] LTTng - x86_64 instrumentation Mathieu Desnoyers
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-sparc.patch --]
[-- Type: text/plain, Size: 3084 bytes --]

syscall trace missing
traps missing

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/sparc/kernel/entry.S     |   10 +++++-----
 arch/sparc/kernel/process.c   |    1 +
 arch/sparc/kernel/sys_sparc.c |    2 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

Index: linux-2.6-lttng/arch/sparc/kernel/entry.S
===================================================================
--- linux-2.6-lttng.orig/arch/sparc/kernel/entry.S	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sparc/kernel/entry.S	2007-11-13 09:50:18.000000000 -0500
@@ -1231,7 +1231,7 @@ sys_ptrace:
 	 add	%sp, STACKFRAME_SZ, %o0
 
 	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
+	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), %g0
 	be	1f
 	 nop
 
@@ -1280,7 +1280,7 @@ sys_sigreturn:
 	 add	%sp, STACKFRAME_SZ, %o0
 
 	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
+	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), %g0
 	be	1f
 	 nop
 
@@ -1300,7 +1300,7 @@ sys_rt_sigreturn:
 	 add	%sp, STACKFRAME_SZ, %o0
 
 	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
+	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), %g0
 	be	1f
 	 nop
 
@@ -1436,7 +1436,7 @@ syscall_is_too_hard:
 
 	ld	[%curptr + TI_FLAGS], %l5
 	mov	%i3, %o3
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
+	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), %g0
 	mov	%i4, %o4
 	bne	linux_syscall_trace
 	 mov	%i0, %l5
@@ -1453,7 +1453,7 @@ ret_sys_call:
 	ld	[%sp + STACKFRAME_SZ + PT_PSR], %g3
 	set	PSR_C, %g2
 	bgeu	1f
-	 andcc	%l6, _TIF_SYSCALL_TRACE, %g0
+	 andcc	%l6, (_TIF_SYSCALL_TRACE|_TIF_KERNEL_TRACE), %g0
 
 	/* System call success, clear Carry condition code. */
 	andn	%g3, %g2, %g3
Index: linux-2.6-lttng/arch/sparc/kernel/sys_sparc.c
===================================================================
--- linux-2.6-lttng.orig/arch/sparc/kernel/sys_sparc.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sparc/kernel/sys_sparc.c	2007-11-13 09:50:18.000000000 -0500
@@ -120,6 +120,8 @@ asmlinkage int sys_ipc (uint call, int f
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	if (call <= SEMCTL)
 		switch (call) {
 		case SEMOP:
Index: linux-2.6-lttng/arch/sparc/kernel/process.c
===================================================================
--- linux-2.6-lttng.orig/arch/sparc/kernel/process.c	2007-11-13 09:25:23.000000000 -0500
+++ linux-2.6-lttng/arch/sparc/kernel/process.c	2007-11-13 09:50:18.000000000 -0500
@@ -709,6 +709,7 @@ pid_t kernel_thread(int (*fn)(void *), v
 			     "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
 			     "i" (__NR_exit),  "r" (fn), "r" (arg) :
 			     "g1", "g2", "g3", "o0", "o1", "memory", "cc");
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", retval, fn);
 	return retval;
 }
 

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 09/10] LTTng - x86_64 instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (7 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 08/10] LTTng Sparc instrumentation Mathieu Desnoyers
@ 2007-12-06  2:56 ` Mathieu Desnoyers
  2007-12-06  2:57 ` [patch-early-RFC 10/10] LTTng - s390 instrumentation Mathieu Desnoyers
  2007-12-06 10:11 ` [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Ingo Molnar
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:56 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel
  Cc: Mathieu Desnoyers, Thomas Gleixner, Ingo Molnar, H. Peter Anvin

[-- Attachment #1: lttng-instrumentation-x86_64.patch --]
[-- Type: text/plain, Size: 16016 bytes --]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
CC: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/ia32/ia32entry.S                 |    6 +++---
 arch/x86/ia32/ipc32.c                     |    2 ++
 arch/x86/kernel/apic_64.c                 |   21 +++++++++++++++++++++
 arch/x86/kernel/cpu/mcheck/mce_intel_64.c |    6 ++++++
 arch/x86/kernel/entry_64.S                |   12 ++++++------
 arch/x86/kernel/process_64.c              |   11 +++++++++++
 arch/x86/kernel/ptrace_64.c               |    5 +++++
 arch/x86/kernel/setup64.c                 |    1 +
 arch/x86/kernel/smp_64.c                  |   18 ++++++++++++++++++
 arch/x86/kernel/traps_64.c                |   29 +++++++++++++++++++++++++----
 arch/x86/mm/fault_64.c                    |    7 +++++++
 11 files changed, 105 insertions(+), 13 deletions(-)

Index: linux-2.6-lttng/arch/x86/ia32/ia32entry.S
===================================================================
--- linux-2.6-lttng.orig/arch/x86/ia32/ia32entry.S	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/ia32/ia32entry.S	2007-12-05 21:48:46.000000000 -0500
@@ -125,7 +125,7 @@ ENTRY(ia32_sysenter_target)
  	.previous	
 	GET_THREAD_INFO(%r10)
 	orl    $TS_COMPAT,threadinfo_status(%r10)
-	testl  $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
+	testl  $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
 	CFI_REMEMBER_STATE
 	jnz  sysenter_tracesys
 sysenter_do_call:	
@@ -230,7 +230,7 @@ ENTRY(ia32_cstar_target)
 	.previous	
 	GET_THREAD_INFO(%r10)
 	orl   $TS_COMPAT,threadinfo_status(%r10)
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
 	CFI_REMEMBER_STATE
 	jnz   cstar_tracesys
 cstar_do_call:	
@@ -322,7 +322,7 @@ ENTRY(ia32_syscall)
 	SAVE_ARGS 0,0,1
 	GET_THREAD_INFO(%r10)
 	orl   $TS_COMPAT,threadinfo_status(%r10)
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
 	jnz ia32_tracesys
 ia32_do_syscall:	
 	cmpl $(IA32_NR_syscalls-1),%eax
Index: linux-2.6-lttng/arch/x86/ia32/ipc32.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/ia32/ipc32.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/ia32/ipc32.c	2007-12-05 21:48:46.000000000 -0500
@@ -18,6 +18,8 @@ sys32_ipc(u32 call, int first, int secon
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
Index: linux-2.6-lttng/arch/x86/kernel/entry_64.S
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/entry_64.S	2007-12-05 21:48:05.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/entry_64.S	2007-12-05 21:48:46.000000000 -0500
@@ -161,7 +161,7 @@ ENTRY(ret_from_fork)
 	CFI_ADJUST_CFA_OFFSET -4
 	call schedule_tail
 	GET_THREAD_INFO(%rcx)
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE),threadinfo_flags(%rcx)
 	jnz rff_trace
 rff_action:	
 	RESTORE_REST
@@ -229,7 +229,7 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%rcx)
 	jnz tracesys
 	cmpq $__NR_syscall_max,%rax
 	ja badsys
@@ -268,7 +268,7 @@ sysret_check:		
 	/* Handle reschedules */
 	/* edx:	work, edi: workmask */	
 sysret_careful:
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),%edx
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),%edx
 	jnz ret_from_sys_call_trace
 	bt $TIF_NEED_RESCHED,%edx
 	jnc sysret_signal
@@ -377,7 +377,7 @@ int_very_careful:
 	sti
 	SAVE_REST
 	/* Check for syscall exit trace */	
-	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
+	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SINGLESTEP),%edx
 	jz int_signal
 	pushq %rdi
 	CFI_ADJUST_CFA_OFFSET 8
@@ -385,7 +385,7 @@ int_very_careful:
 	call syscall_trace_leave
 	popq %rdi
 	CFI_ADJUST_CFA_OFFSET -8
-	andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
+	andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SINGLESTEP),%edi
 	jmp int_restore_rest
 	
 int_signal:
@@ -957,7 +957,7 @@ bad_gs: 
  * asm input arguments:
  *	rdi: fn, rsi: arg, rdx: flags
  */
-ENTRY(kernel_thread)
+ENTRY(kernel_thread_asm)
 	CFI_STARTPROC
 	FAKE_STACK_FRAME $child_rip
 	SAVE_ALL
Index: linux-2.6-lttng/arch/x86/kernel/process_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/process_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/process_64.c	2007-12-05 21:48:46.000000000 -0500
@@ -54,6 +54,9 @@
 
 asmlinkage extern void ret_from_fork(void);
 
+asmlinkage long kernel_thread_asm(int (*fn)(void *), void * arg,
+	 unsigned long flags);
+
 unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
 
 unsigned long boot_option_idle_override = 0;
@@ -903,3 +906,11 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+asmlinkage long kernel_thread(int (*fn)(void *), void * arg,
+	 unsigned long flags)
+{
+	long pid = kernel_thread_asm(fn, arg, flags);
+	trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
+	return pid;
+}
Index: linux-2.6-lttng/arch/x86/kernel/ptrace_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/ptrace_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/ptrace_64.c	2007-12-05 21:48:46.000000000 -0500
@@ -587,6 +587,9 @@ static void syscall_trace(struct pt_regs
 
 asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 {
+	trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+		(int)regs->orig_rax, instruction_pointer(regs));
+
 	/* do the secure computing check first */
 	secure_computing(regs->orig_rax);
 
@@ -611,6 +614,8 @@ asmlinkage void syscall_trace_enter(stru
 
 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 {
+	trace_mark(kernel_arch_syscall_exit, "ret %ld", regs->rax);
+
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
 
Index: linux-2.6-lttng/arch/x86/kernel/traps_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/traps_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/traps_64.c	2007-12-05 21:49:48.000000000 -0500
@@ -573,6 +573,9 @@ static void __kprobes do_trap(int trapnr
 {
 	struct task_struct *tsk = current;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", trapnr,
+		instruction_pointer(regs));
+
 	if (user_mode(regs)) {
 		/*
 		 * We want error_code and trap_no set for userspace
@@ -598,6 +601,7 @@ static void __kprobes do_trap(int trapnr
 			force_sig_info(signr, info, tsk);
 		else
 			force_sig(signr, tsk);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
@@ -613,8 +617,10 @@ static void __kprobes do_trap(int trapnr
 			tsk->thread.trap_no = trapnr;
 			die(str, regs, error_code);
 		}
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 #define DO_ERROR(trapnr, signr, str, name) \
@@ -699,7 +705,10 @@ asmlinkage void __kprobes do_general_pro
 			       tsk->comm, tsk->pid,
 			       regs->rip, regs->rsp, error_code); 
 
+		trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", 13,
+			instruction_pointer(regs));
 		force_sig(SIGSEGV, tsk);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	} 
 
@@ -779,6 +788,9 @@ asmlinkage __kprobes void default_do_nmi
 	unsigned char reason = 0;
 	int cpu;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		2, instruction_pointer(regs));
+
 	cpu = smp_processor_id();
 
 	/* Only the BSP gets external NMIs from the system.  */
@@ -788,20 +800,20 @@ asmlinkage __kprobes void default_do_nmi
 	if (!(reason & 0xc0)) {
 		if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
 								== NOTIFY_STOP)
-			return;
+			goto end;
 		/*
 		 * Ok, so this is none of the documented NMI sources,
 		 * so it must be the NMI watchdog.
 		 */
 		if (nmi_watchdog_tick(regs,reason))
-			return;
+			goto end;
 		if (!do_nmi_callback(regs,cpu))
 			unknown_nmi_error(reason, regs);
 
-		return;
+		goto end;
 	}
 	if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
-		return; 
+		goto end;
 
 	/* AK: following checks seem to be broken on modern chipsets. FIXME */
 
@@ -809,6 +821,8 @@ asmlinkage __kprobes void default_do_nmi
 		mem_parity_error(reason, regs);
 	if (reason & 0x40)
 		io_check_error(reason, regs);
+end:
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 /* runs on IST stack. */
@@ -902,7 +916,10 @@ asmlinkage void __kprobes do_debug(struc
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
 	info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		1, instruction_pointer(regs));
 	force_sig_info(SIGTRAP, &info, tsk);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 
 clear_dr7:
 	set_debugreg(0UL, 7);
@@ -1060,6 +1077,10 @@ asmlinkage void do_simd_coprocessor_erro
 
 asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
 {
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		16, instruction_pointer(regs));
+
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
Index: linux-2.6-lttng/arch/x86/mm/fault_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/mm/fault_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/mm/fault_64.c	2007-12-05 21:48:52.000000000 -0500
@@ -441,7 +441,10 @@ good_area:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+	trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		14, instruction_pointer(regs));
 	fault = handle_mm_fault(mm, vma, address, write);
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
@@ -472,6 +475,9 @@ bad_area_nosemaphore:
 		 */
 		local_irq_enable();
 
+		trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+		    14, instruction_pointer(regs));
+
 		if (is_prefetch(regs, address, error_code))
 			return;
 
@@ -503,6 +509,7 @@ bad_area_nosemaphore:
 		/* info.si_code has been set above */
 		info.si_addr = (void __user *)address;
 		force_sig_info(SIGSEGV, &info, tsk);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
Index: linux-2.6-lttng/arch/x86/kernel/setup64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/setup64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/setup64.c	2007-12-05 21:48:46.000000000 -0500
@@ -189,6 +189,7 @@ unsigned long kernel_eflags;
  * debugging, no special alignment required.
  */
 DEFINE_PER_CPU(struct orig_ist, orig_ist);
+EXPORT_PER_CPU_SYMBOL_GPL(orig_ist);
 
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
Index: linux-2.6-lttng/arch/x86/kernel/apic_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/apic_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/apic_64.c	2007-12-05 21:48:58.000000000 -0500
@@ -1085,7 +1085,14 @@ void smp_apic_timer_interrupt(struct pt_
 	 */
 	exit_idle();
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		LOCAL_TIMER_VECTOR, (regs)?(!user_mode(regs)):(1));
+
 	smp_local_timer_interrupt();
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 	set_irq_regs(old_regs);
 }
@@ -1145,6 +1152,10 @@ asmlinkage void smp_spurious_interrupt(v
 	unsigned int v;
 	exit_idle();
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		SPURIOUS_APIC_VECTOR, -1);
+
 	/*
 	 * Check if this really is a spurious interrupt and ACK it
 	 * if it is a vectored one.  Just in case...
@@ -1155,6 +1166,9 @@ asmlinkage void smp_spurious_interrupt(v
 		ack_APIC_irq();
 
 	add_pda(irq_spurious_count, 1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
@@ -1168,6 +1182,10 @@ asmlinkage void smp_error_interrupt(void
 
 	exit_idle();
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		ERROR_APIC_VECTOR, -1);
+
 	/* First tickle the hardware, only then report what went on. -- REW */
 	v = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
@@ -1187,6 +1205,9 @@ asmlinkage void smp_error_interrupt(void
 	*/
 	printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
 		smp_processor_id(), v , v1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
Index: linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/cpu/mcheck/mce_intel_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/mce_intel_64.c	2007-12-05 21:48:58.000000000 -0500
@@ -22,11 +22,17 @@ asmlinkage void smp_thermal_interrupt(vo
 	exit_idle();
 	irq_enter();
 
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		THERMAL_APIC_VECTOR, -1);
+
 	rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
 	if (therm_throt_process(msr_val & 1))
 		mce_log_therm_throt_event(smp_processor_id(), msr_val);
 
 	add_pda(irq_thermal_count, 1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 }
 
Index: linux-2.6-lttng/arch/x86/kernel/smp_64.c
===================================================================
--- linux-2.6-lttng.orig/arch/x86/kernel/smp_64.c	2007-12-05 21:05:48.000000000 -0500
+++ linux-2.6-lttng/arch/x86/kernel/smp_64.c	2007-12-05 21:48:58.000000000 -0500
@@ -151,6 +151,9 @@ asmlinkage void smp_invalidate_interrupt
 		 * BUG();
 		 */
 		 
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		sender, (regs)?(!user_mode(regs)):(1));
+
 	if (f->flush_mm == read_pda(active_mm)) {
 		if (read_pda(mmu_state) == TLBSTATE_OK) {
 			if (f->flush_va == FLUSH_ALL)
@@ -164,6 +167,8 @@ out:
 	ack_APIC_irq();
 	cpu_clear(cpu, f->flush_cpumask);
 	add_pda(irq_tlb_count, 1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
 }
 
 static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
@@ -501,7 +506,13 @@ void smp_send_stop(void)
 asmlinkage void smp_reschedule_interrupt(void)
 {
 	ack_APIC_irq();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		RESCHEDULE_VECTOR, -1);
+
 	add_pda(irq_resched_count, 1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
 }
 
 asmlinkage void smp_call_function_interrupt(void)
@@ -522,8 +533,15 @@ asmlinkage void smp_call_function_interr
 	 */
 	exit_idle();
 	irq_enter();
+
+	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
+		CALL_FUNCTION_VECTOR, -1);
+
 	(*func)(info);
 	add_pda(irq_call_count, 1);
+
+	trace_mark(kernel_irq_exit, MARK_NOARGS);
+
 	irq_exit();
 	if (wait) {
 		mb();

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch-early-RFC 10/10] LTTng - s390 instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (8 preceding siblings ...)
  2007-12-06  2:56 ` [patch-early-RFC 09/10] LTTng - x86_64 instrumentation Mathieu Desnoyers
@ 2007-12-06  2:57 ` Mathieu Desnoyers
  2007-12-06 10:11 ` [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Ingo Molnar
  10 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06  2:57 UTC (permalink / raw)
  To: akpm, Ingo Molnar, linux-kernel; +Cc: Mathieu Desnoyers

[-- Attachment #1: lttng-instrumentation-s390.patch --]
[-- Type: text/plain, Size: 9068 bytes --]

Changelog :
- added syscall entry/exit instrumentation.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/s390/kernel/entry.S    |   10 ++++++++--
 arch/s390/kernel/entry64.S  |   10 ++++++++--
 arch/s390/kernel/ptrace.c   |    6 ++++++
 arch/s390/kernel/sys_s390.c |    2 ++
 arch/s390/kernel/traps.c    |   17 +++++++++++++++++
 arch/s390/mm/fault.c        |    6 ++++++
 6 files changed, 47 insertions(+), 4 deletions(-)

Index: linux-2.6-lttng/arch/s390/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/s390/kernel/traps.c	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/kernel/traps.c	2007-11-28 09:33:55.000000000 -0500
@@ -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
@@ -307,6 +308,9 @@ static void __kprobes inline do_trap(lon
 				interruption_code, signr) == NOTIFY_STOP)
 		return;
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%lu",
+		interruption_code & 0xffff, instruction_pointer(regs));
+
         if (regs->psw.mask & PSW_MASK_PSTATE) {
                 struct task_struct *tsk = current;
 
@@ -327,6 +331,7 @@ static void __kprobes inline do_trap(lon
 			die(str, regs, interruption_code);
 		}
         }
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 static inline void __user *get_check_address(struct pt_regs *regs)
@@ -437,6 +442,9 @@ static void illegal_op(struct pt_regs * 
 	if (regs->psw.mask & PSW_MASK_PSTATE)
 		local_irq_enable();
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%lu",
+		interruption_code & 0xffff, instruction_pointer(regs));
+
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
 		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
 			return;
@@ -501,6 +509,7 @@ static void illegal_op(struct pt_regs * 
 		do_trap(interruption_code, signal,
 			"illegal operation", regs, &info);
 	}
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 
@@ -521,6 +530,9 @@ specification_exception(struct pt_regs *
         if (regs->psw.mask & PSW_MASK_PSTATE)
 		local_irq_enable();
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%lu",
+		interruption_code & 0xffff, instruction_pointer(regs));
+
         if (regs->psw.mask & PSW_MASK_PSTATE) {
 		get_user(*((__u16 *) opcode), location);
 		switch (opcode[0]) {
@@ -565,6 +577,7 @@ specification_exception(struct pt_regs *
 		do_trap(interruption_code, signal, 
 			"specification exception", regs, &info);
 	}
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 #else
 DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
@@ -585,6 +598,9 @@ static void data_exception(struct pt_reg
 	if (regs->psw.mask & PSW_MASK_PSTATE)
 		local_irq_enable();
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%lu",
+		interruption_code & 0xffff, instruction_pointer(regs));
+
 	if (MACHINE_HAS_IEEE)
 		asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
 
@@ -659,6 +675,7 @@ static void data_exception(struct pt_reg
 		do_trap(interruption_code, signal, 
 			"data exception", regs, &info);
 	}
+	trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 }
 
 static void space_switch_exception(struct pt_regs * regs, long int_code)
Index: linux-2.6-lttng/arch/s390/kernel/sys_s390.c
===================================================================
--- linux-2.6-lttng.orig/arch/s390/kernel/sys_s390.c	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/kernel/sys_s390.c	2007-11-28 09:33:55.000000000 -0500
@@ -150,6 +150,8 @@ asmlinkage long sys_ipc(uint call, int f
         struct ipc_kludge tmp;
 	int ret;
 
+        trace_mark(ipc_call, "call %u first %d", call, first);
+
         switch (call) {
         case SEMOP:
 		return sys_semtimedop(first, (struct sembuf __user *)ptr,
Index: linux-2.6-lttng/arch/s390/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/s390/mm/fault.c	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/mm/fault.c	2007-11-28 09:33:55.000000000 -0500
@@ -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
@@ -169,6 +170,7 @@ static void do_no_context(struct pt_regs
 	fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK);
 	if (fixup) {
 		regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE;
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
@@ -334,6 +336,9 @@ do_exception(struct pt_regs *regs, unsig
 	 */
 	local_irq_enable();
 
+	trace_mark(kernel_arch_trap_entry, "trap_id %ld ip #p%lu",
+		error_code & 0xffff, instruction_pointer(regs));
+
 	down_read(&mm->mmap_sem);
 
 	si_code = SEGV_MAPERR;
@@ -415,6 +420,7 @@ bad_area:
 		tsk->thread.prot_addr = address;
 		tsk->thread.trap_no = error_code;
 		do_sigsegv(regs, error_code, si_code, address);
+		trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
 		return;
 	}
 
Index: linux-2.6-lttng/arch/s390/kernel/entry.S
===================================================================
--- linux-2.6-lttng.orig/arch/s390/kernel/entry.S	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/kernel/entry.S	2007-11-28 09:33:55.000000000 -0500
@@ -270,8 +270,10 @@ sysc_do_svc:
 sysc_nr_ok:
 	mvc	SP_ARGS(4,%r15),SP_R7(%r15)
 sysc_do_restart:
+	l	%r8,__TI_flags+3(%r9)
+	n	%r8,BASED(.Lc_tif_syscall_trace_or_audit_or_kernel_trace)
+	ltr	%r8,%r8
 	l	%r8,BASED(.Lsysc_table)
-	tm	__TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
 	l	%r8,0(%r7,%r8)	  # get system call addr.
 	bnz	BASED(sysc_tracesys)
 	basr	%r14,%r8	  # call sys_xxxx
@@ -398,7 +400,9 @@ sysc_tracego:
 	basr	%r14,%r8		# call sys_xxx
 	st	%r2,SP_R2(%r15)		# store return value
 sysc_tracenogo:
-	tm	__TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+	l	%r8,__TI_flags+3(%r9)
+	n	%r8,BASED(.Lc_tif_syscall_trace_or_audit_or_kernel_trace)
+	ltr	%r8,%r8
 	bz	BASED(sysc_return)
 	l	%r1,BASED(.Ltrace)
 	la	%r2,SP_PTREGS(%r15)	# load pt_regs
@@ -1063,6 +1067,8 @@ cleanup_io_leave_insn:
 .L0x030:	.short	0x030
 .L0x038:	.short	0x038
 .Lc_1:		.long	1
+.Lc_tif_syscall_trace_or_audit_or_kernel_trace:
+		.long	_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE
 
 /*
  * Symbol constants
Index: linux-2.6-lttng/arch/s390/kernel/entry64.S
===================================================================
--- linux-2.6-lttng.orig/arch/s390/kernel/entry64.S	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/kernel/entry64.S	2007-11-28 09:33:55.000000000 -0500
@@ -263,7 +263,9 @@ sysc_do_restart:
 	larl	%r10,sys_call_table_emu  # use 31 bit emulation system calls
 sysc_noemu:
 #endif
-	tm	__TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+	l	%r8,__TI_flags+7(%r9)
+	n	%r8,BASED(.Lc_tif_syscall_trace_or_audit_or_kernel_trace)
+	ltr	%r8,%r8
 	lgf	%r8,0(%r7,%r10) # load address of system call routine
 	jnz	sysc_tracesys
 	basr	%r14,%r8	# call sys_xxxx
@@ -387,7 +389,9 @@ sysc_tracego:
 	basr	%r14,%r8		# call sys_xxx
 	stg	%r2,SP_R2(%r15)		# store return value
 sysc_tracenogo:
-	tm	__TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+	l	%r8,__TI_flags+7(%r9)
+	n	%r8,BASED(.Lc_tif_syscall_trace_or_audit_or_kernel_trace)
+	ltr	%r8,%r8
 	jz	sysc_return
 	la	%r2,SP_PTREGS(%r15)	# load pt_regs
 	la	%r3,1
@@ -1023,6 +1027,8 @@ cleanup_io_leave_insn:
 		.align	4
 .Lconst:
 .Lnr_syscalls:	.long	NR_syscalls
+.Lc_tif_syscall_trace_or_audit_or_kernel_trace:
+		.long	_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE
 .L0x0130:	.short	0x130
 .L0x0140:	.short	0x140
 .L0x0150:	.short	0x150
Index: linux-2.6-lttng/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6-lttng.orig/arch/s390/kernel/ptrace.c	2007-11-28 09:27:27.000000000 -0500
+++ linux-2.6-lttng/arch/s390/kernel/ptrace.c	2007-11-28 09:33:55.000000000 -0500
@@ -723,6 +723,12 @@ out:
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
+	if (!entryexit)
+		trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
+			(int)regs->gprs[2], instruction_pointer(regs));
+	else
+		trace_mark(kernel_arch_syscall_exit, "ret %ld", regs->gprs[2]);
+
 	if (unlikely(current->audit_context) && entryexit)
 		audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
 

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch-early-RFC 00/10] LTTng architecture dependent instrumentation
  2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
                   ` (9 preceding siblings ...)
  2007-12-06  2:57 ` [patch-early-RFC 10/10] LTTng - s390 instrumentation Mathieu Desnoyers
@ 2007-12-06 10:11 ` Ingo Molnar
  2007-12-06 14:19   ` Mathieu Desnoyers
  2007-12-08 19:05   ` Mathieu Desnoyers
  10 siblings, 2 replies; 15+ messages in thread
From: Ingo Molnar @ 2007-12-06 10:11 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: akpm, linux-kernel, Thomas Gleixner, H. Peter Anvin, Arjan van de Ven


hi Mathieu,

* Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> wrote:

> Hi,
> 
> Here is the architecture dependent instrumentation for LTTng. [...]

A fundamental observation about markers, and i raised this point many 
many months ago already, so it might sound repetitive, but i'm unsure 
wether it's addressed. Documentation/markers.txt still says:

| * Purpose of markers
|
| A marker placed in code provides a hook to call a function (probe) 
| that you can provide at runtime. A marker can be "on" (a probe is 
| connected to it) or "off" (no probe is attached). When a marker is 
| "off" it has no effect, except for adding a tiny time penalty 
| (checking a condition for a branch) and space penalty (adding a few 
| bytes for the function call at the end of the instrumented function 
| and adds a data structure in a separate section).

could you please eliminate the checking of the flag, and insert a pure 
NOP sequence by default (no extra branches), which is then patched in 
with a function call instruction sequence, when the trace point is 
turned on? (on architectures that have code patching infrastructure - 
such as x86)

	Ingo

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch-early-RFC 00/10] LTTng architecture dependent instrumentation
  2007-12-06 10:11 ` [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Ingo Molnar
@ 2007-12-06 14:19   ` Mathieu Desnoyers
  2007-12-08 19:05   ` Mathieu Desnoyers
  1 sibling, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-06 14:19 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: akpm, linux-kernel, Thomas Gleixner, H. Peter Anvin, Arjan van de Ven

* Ingo Molnar (mingo@elte.hu) wrote:
> 
> hi Mathieu,
> 
> * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> wrote:
> 
> > Hi,
> > 
> > Here is the architecture dependent instrumentation for LTTng. [...]
> 
> A fundamental observation about markers, and i raised this point many 
> many months ago already, so it might sound repetitive, but i'm unsure 
> wether it's addressed. Documentation/markers.txt still says:
> 
> | * Purpose of markers
> |
> | A marker placed in code provides a hook to call a function (probe) 
> | that you can provide at runtime. A marker can be "on" (a probe is 
> | connected to it) or "off" (no probe is attached). When a marker is 
> | "off" it has no effect, except for adding a tiny time penalty 
> | (checking a condition for a branch) and space penalty (adding a few 
> | bytes for the function call at the end of the instrumented function 
> | and adds a data structure in a separate section).
> 
> could you please eliminate the checking of the flag, and insert a pure 
> NOP sequence by default (no extra branches), which is then patched in 
> with a function call instruction sequence, when the trace point is 
> turned on? (on architectures that have code patching infrastructure - 
> such as x86)
> 
> 	Ingo

Hi Ingo,

Do you propose that we NOP out the entire function call stack setup and
other related inline functions and pointer dereferences that would be
needed by the call ?

I don't see how we can do this on optimized code without having
side-effects. So there, I think markers could have even less side-effect
than the dtrace NOPs, because I can jump over all the function call
preparation, which they can't. And branch prediction logic is cheap
nowadays, especially since this is a likely branch. However,
benchmarking the "real" impact of this becomes kind of crazy, because it
may depend on workloads, memory pressure, .... so it leaves us mostly
with microbenchmarks.

I also tried to use an unconditional jump to skip the function call, but
the problem here, as has been discussed about a year ago, is gcc : it
does not allow to jump getween two different inline assembly. And since
I don't want to create the a number of macros equivalent to the powerset
of the number of arguments/types we want to support (this is why I use
var args), and I don't see how we could declare var args in inline
assembly portably, I guess the best solution left was what I have done :
loading an immediate value and let gcc handle the conditional jump.

Mathieu

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch-early-RFC 00/10] LTTng architecture dependent instrumentation
  2007-12-06 10:11 ` [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Ingo Molnar
  2007-12-06 14:19   ` Mathieu Desnoyers
@ 2007-12-08 19:05   ` Mathieu Desnoyers
  2007-12-10  0:28     ` Mathieu Desnoyers
  1 sibling, 1 reply; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-08 19:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: akpm, linux-kernel, Thomas Gleixner, H. Peter Anvin, Arjan van de Ven

* Ingo Molnar (mingo@elte.hu) wrote:
> 
> hi Mathieu,
> 
> * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> wrote:
> 
> > Hi,
> > 
> > Here is the architecture dependent instrumentation for LTTng. [...]
> 
> A fundamental observation about markers, and i raised this point many 
> many months ago already, so it might sound repetitive, but i'm unsure 
> wether it's addressed. Documentation/markers.txt still says:
> 
> | * Purpose of markers
> |
> | A marker placed in code provides a hook to call a function (probe) 
> | that you can provide at runtime. A marker can be "on" (a probe is 
> | connected to it) or "off" (no probe is attached). When a marker is 
> | "off" it has no effect, except for adding a tiny time penalty 
> | (checking a condition for a branch) and space penalty (adding a few 
> | bytes for the function call at the end of the instrumented function 
> | and adds a data structure in a separate section).
> 
> could you please eliminate the checking of the flag, and insert a pure 
> NOP sequence by default (no extra branches), which is then patched in 
> with a function call instruction sequence, when the trace point is 
> turned on? (on architectures that have code patching infrastructure - 
> such as x86)
> 

Hi Ingo,

Here are the results of a test I made, hacking a binary to put nops
instead of a function call.

The test is 20000 loops calling a function that contains a marker with
interrupts disabled. It is performed on a x86 32, Pentium 4 3GHz.

__my_trace_mark(0, kernel_debug_test, NULL, "%d %d %ld %ld", 2, current->pid,
  arg, arg2);

The number here include the function call (present in both cases) the
counter increment/tests and the marker.

* No marker at all

240300 cycles total
12.02 cycles per loop

void test(unsigned long arg, unsigned long arg2)
{
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
        asm volatile ("");
}
   3:   5d                      pop    %ebp
   4:   c3                      ret    


* With my marker implementation (load immediate 0, branch predicted) :

between 200355 and 200580 cycles total (avg 200400 cycles)
10.02 cycles per loop (yes, adding the marker increases performance)


void test(unsigned long arg, unsigned long arg2)
{
  4d:   55                      push   %ebp
  4e:   89 e5                   mov    %esp,%ebp
  50:   83 ec 1c                sub    $0x1c,%esp
  53:   89 c1                   mov    %eax,%ecx
        __my_trace_mark(0, kernel_debug_test, NULL, "%d %d %ld %ld", 2, current-
>pid, arg, arg2);
  55:   b0 00                   mov    $0x0,%al
  57:   84 c0                   test   %al,%al
  59:   75 02                   jne    5d <test+0x10>
}
  5b:   c9                      leave  
  5c:   c3                      ret    


* With NOPs :

avg around 410000 cycles total
20.5 cycles/loop (slowdown of 2)

void test(unsigned long arg, unsigned long arg2)
{
  4d:   55                      push   %ebp
  4e:   89 e5                   mov    %esp,%ebp
  50:   83 ec 1c                sub    $0x1c,%esp
struct task_struct;

DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
        return x86_read_percpu(current_task);
  53:   64 8b 0d 00 00 00 00    mov    %fs:0x0,%ecx
        __my_trace_mark(0, kernel_debug_test, NULL, "%d %d %ld %ld", 2, current-
>pid, arg, arg2);
  5a:   89 54 24 18             mov    %edx,0x18(%esp)
  5e:   89 44 24 14             mov    %eax,0x14(%esp)
  62:   8b 81 c4 00 00 00       mov    0xc4(%ecx),%eax
  68:   89 44 24 10             mov    %eax,0x10(%esp)
  6c:   c7 44 24 0c 02 00 00    movl   $0x2,0xc(%esp)
  73:   00 
  74:   c7 44 24 08 0e 00 00    movl   $0xe,0x8(%esp)
  7b:   00 
  7c:   c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
  83:   00 
  84:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  8b:   90                      nop    
  8c:   90                      nop    
  8d:   90                      nop    
  8e:   90                      nop    
  8f:   90                      nop    
}
  90:   c9                      leave  
  91:   c3                      ret    


Therefore, because of the cost of stack setup, the load immediate and
conditionnal branch seems to be _much_ faster than the NOP alternative.

Mathieu

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch-early-RFC 00/10] LTTng architecture dependent instrumentation
  2007-12-08 19:05   ` Mathieu Desnoyers
@ 2007-12-10  0:28     ` Mathieu Desnoyers
  0 siblings, 0 replies; 15+ messages in thread
From: Mathieu Desnoyers @ 2007-12-10  0:28 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: akpm, linux-kernel, Thomas Gleixner, H. Peter Anvin, Arjan van de Ven

* Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca) wrote:
> * Ingo Molnar (mingo@elte.hu) wrote:
> > 
> > hi Mathieu,
> > 
> > * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> wrote:
> > 
> > > Hi,
> > > 
> > > Here is the architecture dependent instrumentation for LTTng. [...]
> > 
> > A fundamental observation about markers, and i raised this point many 
> > many months ago already, so it might sound repetitive, but i'm unsure 
> > wether it's addressed. Documentation/markers.txt still says:
> > 
> > | * Purpose of markers
> > |
> > | A marker placed in code provides a hook to call a function (probe) 
> > | that you can provide at runtime. A marker can be "on" (a probe is 
> > | connected to it) or "off" (no probe is attached). When a marker is 
> > | "off" it has no effect, except for adding a tiny time penalty 
> > | (checking a condition for a branch) and space penalty (adding a few 
> > | bytes for the function call at the end of the instrumented function 
> > | and adds a data structure in a separate section).
> > 
> > could you please eliminate the checking of the flag, and insert a pure 
> > NOP sequence by default (no extra branches), which is then patched in 
> > with a function call instruction sequence, when the trace point is 
> > turned on? (on architectures that have code patching infrastructure - 
> > such as x86)
> > 
> 
> Hi Ingo,
> 
[...] 
> * No marker at all
> 
> 240300 cycles total
> 12.02 cycles per loop
> 
[...]
> * With my marker implementation (load immediate 0, branch predicted) :
> 
> between 200355 and 200580 cycles total (avg 200400 cycles)
> 10.02 cycles per loop (yes, adding the marker increases performance)
> 
[...]
> * With NOPs :
> 
> avg around 410000 cycles total
> 20.5 cycles/loop (slowdown of 2)
> 
>
[...]
> Therefore, because of the cost of stack setup, the load immediate and
> conditionnal branch seems to be _much_ faster than the NOP alternative.
> 

I wanted to know what clever things the dtrace guys have done, so I just
dug into the dtrace code today, and it isn't pretty for x86.

For the kernel sdt (static dtrace), the closest match to markers, they :

1 - Use the linker to turn the calls to an undefined symbol into 
"0x90 0x90 0x90 0x90 0x90" (5 nops)
(note that they still suffer from the stack setup cost even when
disabled. Therefore, performance-wise, I think the markers are already
faster)

But let's dig deeper..

2 - When what they call a "provider" is actvated, the first byte of the
"instruction" (actually, it would be the second NOP) is changed for a f0
lock prefix) :

"0x90 0xf0 0x90 0x90 0x90"

3 - When this site is hit, the 0xf0 0x90 instruction will produce an
illegal op fault. In the handler, they emulate a trap by incrementing
EIP of the size of the illegal op. They lookup the faulty EIP in a hash
table to know which site caused it and then they call the dtrace_probe
function to call the consumers from there.

So, if I have not missed anything, they will have the performance cost
of a fault and a hash table lookup on the critical path, which is kind
of dumb. Just the fault adds a few thousand cycles (assuming it will
perform like an int3 breakpoint).

Compared to this, my approach of load immediate + branch when disabled
and the added function call when enabled are _much_ more lighweight.

I guess the dtrace approach is good enough on sparc (except for stack
setup cost when disabled), where they patch the 4 bytes nop into a 4
byte function call and manage to get good performance, but the hack they
are doing on x86 seems to be just too slow.

Mathieu

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2007-12-10  0:34 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-06  2:56 [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 01/10] LTTng - ARM instrumentation Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 02/10] LTTng - x86_32 instrumentation Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 03/10] LTTng - MIPS instrumentation Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 04/10] LTTng instrumentation Powerpc Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 05/10] LTTng instrumentation PPC Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 06/10] LTTng - instrumentation SH Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 07/10] LTTng instrumentation SH64 Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 08/10] LTTng Sparc instrumentation Mathieu Desnoyers
2007-12-06  2:56 ` [patch-early-RFC 09/10] LTTng - x86_64 instrumentation Mathieu Desnoyers
2007-12-06  2:57 ` [patch-early-RFC 10/10] LTTng - s390 instrumentation Mathieu Desnoyers
2007-12-06 10:11 ` [patch-early-RFC 00/10] LTTng architecture dependent instrumentation Ingo Molnar
2007-12-06 14:19   ` Mathieu Desnoyers
2007-12-08 19:05   ` Mathieu Desnoyers
2007-12-10  0:28     ` Mathieu Desnoyers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).