Re: [PATCH] LTT for SH4
"Giuseppe Cavallaro" <[email protected]>
| Newsgroups | gmane.linux.kernel.tracing |
|---|---|
| Message-ID | <[email protected]> |
Hi Mathieu, any news? In the meantime, I've rewritten my patch using the latest lttng 0.9.10sources (hoping that could be useful). In attachment, you will find both the probe source for SH and the new instrumentation patch. In the latter I've reviewed the code (already released for this architecture) adding mark into the ptrace.c file as well. Let me know, Cheers, Giuseppe Note: concerning the timestamp, please see my previous lttng-sh_timestamp.patch file. _______________________________________________ Ltt-dev mailing list [email protected] http://listserv.shafik.org/mailman/listinfo/ltt-dev
lttng-probes-sh.patch
(application/octet-stream, 3.6 KB)
This adds the kernel_arch probe functions for SH architecture. Indeed, it is the same code used for other architectures (i.e. arm). Moreover, it also enables the LTT_HEARTBEAT support for SUPERH architecture. That is for overcoming 64 timestamp limit. Signed-off by Giuseppe Cavallaro <[email protected]> --- /dev/null 2007-07-04 14:05:26.796758801 +0200 +++ linux/ltt/probes/ltt-probe-kernel_arch_sh.c 2007-07-09 09:11:43.000000000 +0200 @@ -0,0 +1,105 @@ +/* + * kernel_arch probe + * + * Part of LTTng + * + * Mathieu Desnoyers, March 2007 + * + * Licensed under the GPLv2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/crc32.h> +#include <linux/marker.h> +#include <linux/ltt-facilities.h> +#include <linux/ltt-tracer.h> + + +#define FACILITY_NAME "kernel_arch" + +static struct ltt_probe_data probe_array[] = +{ + { "kernel_arch_trap_entry", "%ld %ld", GET_CHANNEL_INDEX(cpu) }, + { "kernel_arch_trap_exit", MARK_NOARGS, GET_CHANNEL_INDEX(cpu) }, + { "kernel_arch_syscall_entry", "%d %ld", GET_CHANNEL_INDEX(cpu) }, + { "kernel_arch_syscall_exit", MARK_NOARGS, GET_CHANNEL_INDEX(cpu) }, + { "kernel_arch_ipc_call", "%u %d", GET_CHANNEL_INDEX(cpu) }, + { "kernel_arch_kthread_create", "%ld %p", + GET_CHANNEL_INDEX(processes) }, +}; + + +#define NUM_PROBES (sizeof(probe_array) / sizeof(struct ltt_probe_data)) + +static struct ltt_facility facility = { + .name = FACILITY_NAME, + .num_events = NUM_PROBES, + .checksum = 0, + .id = 0xFF, + .alignment = 1, /* 1: true, 0: false */ +}; + +static int __init probe_init(void) +{ + int result; + uint8_t eID; + int ret; + + /* FIXME : LTTV is unable to compute this CRC (for now) */ + for (eID = 0; eID < NUM_PROBES; eID++) { + facility.checksum = + crc32(facility.checksum, probe_array[eID].name, + strlen(probe_array[eID].name)); + facility.checksum = + crc32(facility.checksum, probe_array[eID].format, + strlen(probe_array[eID].format)); + + } + ret = ltt_facility_kernel_register(&facility); + if (ret < 0) { + printk(KERN_WARNING "LTT : Error in registering facility %s\n", + facility.name); + return ret; + } + facility.id = (uint8_t)ret; + + printk("LTT : Facility %s registered with id %hu\n", facility.name, + facility.id); + + for (eID = 0; eID < NUM_PROBES; eID++) { + probe_array[eID].fID = facility.id; + probe_array[eID].eID = eID; + probe_array[eID].align = facility.alignment; + probe_array[eID].callbacks[0] = ltt_serialize_data; + result = marker_arm_probe(probe_array[eID].name, + probe_array[eID].format, + ltt_trace, &probe_array[eID]); + if (result) + printk(KERN_INFO "LTT unable to register probe %s\n", + probe_array[eID].name); + } + return 0; +} + +static void __exit probe_fini(void) +{ + uint8_t eID; + int err; + + for (eID = 0; eID < NUM_PROBES; eID++) { + marker_disarm_probe(probe_array[eID].name); + } + err = ltt_facility_unregister(facility.id); + if (err) + printk(KERN_WARNING + "LTT : Error in unregistering facility %s\n", + facility.name); +} + +module_init(probe_init); +module_exit(probe_fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION(FACILITY_NAME " probe"); --- linux/ltt/Kconfig.orig 2007-07-09 09:15:13.000000000 +0200 +++ linux/ltt/Kconfig 2007-07-09 09:15:54.000000000 +0200 @@ -2,8 +2,8 @@ config LTT bool "Linux Trace Toolkit Instrumentation Support" depends on EXPERIMENTAL depends on MARKERS - select LTT_HEARTBEAT if MIPS - select LTT_SYNTHETIC_TSC if MIPS + select LTT_HEARTBEAT if MIPS || SUPERH + select LTT_SYNTHETIC_TSC if MIPS || SUPERH default n help It is possible for the kernel to log important events to a trace
lttng-instrumentation-sh.patch
(application/octet-stream, 6.4 KB)
--- linux-2.6-lttng/arch/sh/kernel/entry-common.S.orig 2007-07-09 09:23:26.000000000 +0200
+++ linux-2.6-lttng/arch/sh/kernel/entry-common.S 2007-07-09 09:25:21.000000000 +0200
@@ -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_SYSCALL_AUDIT, r0
bt/s work_pending
tst #_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS
@@ -234,6 +234,10 @@ syscall_exit_work:
#endif
sti
! XXX setup arguments...
+#ifdef CONFIG_LTT
+ mov r15, r4
+ mov #0, r5 ! trace entry [0]
+#endif
mov.l 4f, r0 ! do_syscall_trace
jsr @r0
nop
@@ -242,6 +246,10 @@ syscall_exit_work:
.align 2
syscall_trace_entry:
+#ifdef CONFIG_LTT
+ mov r15, r4 ! pass stacked regs as arg
+ mov #1, r5 ! trace entry [1]
+#endif
! Yes it is traced.
! XXX setup arguments...
mov.l 4f, r11 ! Call do_syscall_trace which notifies
@@ -366,7 +374,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_SYSCALL_AUDIT), r10
tst r10, r8
bf syscall_trace_entry
!
--- linux-2.6-lttng/arch/sh/kernel/process.c.orig 2007-07-09 09:23:38.000000000 +0200
+++ linux-2.6-lttng/arch/sh/kernel/process.c 2007-07-09 09:28:23.000000000 +0200
@@ -169,6 +169,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(®s, 0, sizeof(regs));
@@ -181,6 +182,10 @@ int kernel_thread(int (*fn)(void *), voi
/* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
®s, 0, NULL, NULL);
+ pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ ®s, 0, NULL, NULL);
+ trace_mark(kernel_arch_kthread_create, "%ld %p", pid, fn);
+ return pid;
}
/*
--- linux-2.6-lttng/arch/sh/kernel/sys_sh.c.orig 2007-07-09 09:23:44.000000000 +0200
+++ linux-2.6-lttng/arch/sh/kernel/sys_sh.c 2007-07-09 09:29:08.000000000 +0200
@@ -22,6 +22,7 @@
#include <linux/utsname.h>
#include <linux/module.h>
#include <asm/cacheflush.h>
+
#include <asm/uaccess.h>
#include <asm/ipc.h>
#include <asm/unistd.h>
@@ -191,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, "%u %d", call, first);
+
if (call <= SEMCTL)
switch (call) {
case SEMOP:
--- linux-2.6-lttng/arch/sh/kernel/traps.c.orig 2007-07-09 09:23:50.000000000 +0200
+++ linux-2.6-lttng/arch/sh/kernel/traps.c 2007-07-09 09:30:38.000000000 +0200
@@ -23,6 +23,7 @@
#include <linux/kdebug.h>
#include <linux/kexec.h>
#include <linux/limits.h>
+
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -543,6 +544,9 @@ asmlinkage void do_address_error(struct
lookup_exception_vector(error_code);
#endif
+ trace_mark(kernel_arch_trap_entry, "%ld %ld", (error_code >> 5),
+ instruction_pointer(regs));
+
oldfs = get_fs();
if (user_mode(regs)) {
@@ -569,8 +573,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:
@@ -606,6 +612,7 @@ uspace_segv:
force_sig(SIGSEGV, current);
#endif
}
+ trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
}
#ifdef CONFIG_SH_DSP
--- linux-2.6-lttng/arch/sh/kernel/ptrace.c.orig 2007-06-05 02:57:25.000000000 +0200
+++ linux-2.6-lttng/arch/sh/kernel/ptrace.c 2007-07-09 09:33:52.000000000 +0200
@@ -263,10 +263,23 @@ long arch_ptrace(struct task_struct *chi
return ret;
}
+#ifdef CONFIG_LTT
+asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+#else
asmlinkage void do_syscall_trace(void)
+#endif
{
struct task_struct *tsk = current;
+#ifdef CONFIG_LTT
+ if (entryexit) {
+ trace_mark(kernel_arch_syscall_entry, "%d %ld", regs->regs[3],
+ instruction_pointer(regs));
+ } else {
+ trace_mark(kernel_arch_syscall_exit, MARK_NOARGS);
+ }
+#endif
+
if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
!test_thread_flag(TIF_SINGLESTEP))
return;
--- linux-2.6-lttng/arch/sh/mm/fault.c.orig 2007-07-09 09:23:58.000000000 +0200
+++ linux-2.6-lttng/arch/sh/mm/fault.c 2007-07-09 09:33:06.000000000 +0200
@@ -87,6 +87,14 @@ asmlinkage void __kprobes do_page_fault(
return;
}
+ trace_mark(kernel_arch_trap_entry, "%ld %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..
@@ -141,6 +149,7 @@ survive:
}
up_read(&mm->mmap_sem);
+ trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
return;
/*
@@ -157,6 +166,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;
}
@@ -222,6 +232,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
--- linux-2.6-lttng/include/asm-sh/thread_info.h.orig 2007-07-09 09:24:05.000000000 +0200
+++ linux-2.6-lttng/include/asm-sh/thread_info.h 2007-07-09 09:25:04.000000000 +0200
@@ -111,6 +111,7 @@ static inline struct thread_info *curren
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */
#define TIF_SINGLESTEP 4 /* singlestepping active */
+#define TIF_SYSCALL_AUDIT 6 /* syscall audit active */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18
@@ -121,6 +122,7 @@ static inline struct thread_info *curren
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1<<TIF_FREEZE)