Re: [PATCH] LTT for SH4
"Giuseppe Cavallaro" <[email protected]>
| Newsgroups | gmane.linux.kernel.tracing |
|---|---|
| Message-ID | <[email protected]> |
Mathieu, On 04/07/07, Mathieu Desnoyers <[email protected]> wrote: > > Hi Giuseppe, > > > > > Does this timer stop once it reaches the underflow ? > > > > > > Yes it does. > > Hrm, here you seems to say that the timer stops, while right after you > say that it stops... so, what happens ? :) Sorry, I was not so clear in my previous email; after an underflow the TMU counter register (TCNT) is reloaded with the start value (TCOR register) by the HW and the counter is not stopped. In attachment you will find the new patches. This new ltt.h file should be good also if you are using the latest TMU infrastructure (included in the timer-tmu.c file). Indeed, I've decided to "hack" my timer-tmu.c file adding the new functions for the tmu1. Looking at the new timer-tmu.c (tmu1_clk_init etc...), the TMU channel 1 is initialized and started during the kernel boot (and no interrupt handler is installed for this TMU channel). In my opinion, we can actually re-use this infrastructure without modifying the configuration. In the end, I've also reviewed the get_timestamp functions (following your advice) and all seems to start working. Let me know and welcome advice. Ciao Giuseppe _______________________________________________ Ltt-dev mailing list [email protected] http://listserv.shafik.org/mailman/listinfo/ltt-dev
lttng-0.9.5-sh_ptrace.patch
(application/octet-stream, 1.5 KB)
This marks the do_syscall_trace function within the ptrace.c file Signed-off by Giuseppe Cavallaro <[email protected]> --- linux-2.6.21/arch/sh/kernel/ptrace.c.orig 2007-07-03 15:49:05.000000000 +0200 +++ linux-2.6.21/arch/sh/kernel/ptrace.c 2007-07-03 15:50:14.000000000 +0200 @@ -264,10 +264,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) { + MARK(kernel_arch_syscall_entry, "%d %ld", regs->regs[3], + instruction_pointer(regs)); + } else { + MARK(kernel_arch_syscall_exit, MARK_NOARGS); + } +#endif + if (!test_thread_flag(TIF_SYSCALL_TRACE) && !test_thread_flag(TIF_SINGLESTEP)) return; --- linux-2.6.21/arch/sh/kernel/entry-common.S.orig 2007-07-03 15:48:10.000000000 +0200 +++ linux-2.6.21/arch/sh/kernel/entry-common.S 2007-07-03 15:48:58.000000000 +0200 @@ -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
lttng-sh_timestamp.patch
(application/octet-stream, 2 KB)
This patch adds the timestamping mechanism in the ltt.h arch header file. The new timestamp functions use the TMU channel 1. This code only works if the TMU channel 1 is initialized during the kernel boot Signed-off by Giuseppe Cavallaro <[email protected]> --- linux/include/asm-sh/ltt.h.orig 2007-07-03 15:45:55.000000000 +0200 +++ linux/include/asm-sh/ltt.h 2007-07-05 13:50:36.343575000 +0200 @@ -1,14 +1,44 @@ /* - * linux/include/asm-sh/ltt.h - * - * Copyright (C) 2002, Karim Yaghmour - * - * SuperH definitions for tracing system + * SH definitions for tracing system + * Author Giuseppe Cavallaro <[email protected]> */ #ifndef _ASM_SH_LTT_H #define _ASM_SH_LTT_H -#include <asm-generic/ltt.h> +#include <linux/ltt-core.h> +#include <asm/timer.h> +#include <asm/clock.h> +#define LTT_ARCH_TYPE LTT_ARCH_TYPE_SH +#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE + +#define LTT_HAS_TSC +u64 ltt_heartbeat_read_synthetic_tsc(void); + +static inline u32 ltt_get_timestamp32(void) +{ + return get_cycles(); +} + +static inline u64 ltt_get_timestamp64(void) +{ + return (ltt_heartbeat_read_synthetic_tsc()); +} + +static inline unsigned int ltt_frequency(void) +{ + unsigned long rate; + struct clk *tmu1_clk; + + tmu1_clk = clk_get(NULL, "tmu1_clk"); + rate = (clk_get_rate(tmu1_clk)); + + return (unsigned int)(rate); +} + +static inline u32 ltt_freq_scale(void) +{ + return 1; +} #endif --- linux/include/asm-sh/timex.h.orig 2007-07-05 11:46:26.000000000 +0200 +++ linux/include/asm-sh/timex.h 2007-07-05 10:34:55.888930000 +0200 @@ -5,13 +5,20 @@ */ #ifndef __ASM_SH_TIMEX_H #define __ASM_SH_TIMEX_H +#ifdef CONFIG_LTT +#include <asm/cpu/timer.h> +#include <asm/io.h> +#endif -#define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */ +#define CLOCK_TICK_RATE (HZ * 100000UL) typedef unsigned long long cycles_t; static __inline__ cycles_t get_cycles (void) { +#ifdef CONFIG_LTT + return (0xffffffff - ctrl_inl(TMU1_TCNT)); +#endif return 0; }
lttng-0.9.5-probe-kernel_arch_sh.patch
(application/octet-stream, 3.7 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-03 15:14:15.628235594 +0200 +++ linux/ltt/probes/ltt-probe-kernel_arch_sh.c 2007-06-26 09:06:04.574112000 +0200 @@ -0,0 +1,106 @@ +/* + * ltt-probe-kernel_arch_arm.c + * + * kernel_arch probe + * + * Part of LTTng + * + * 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 arch_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 "%s LTT : Error in registering facility %s\n", + "SH", facility.name); + return ret; + } + facility.id = (uint8_t)ret; + + printk("%s LTT : Facility %s registered with id %hu\n", "SH", 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_set_probe(probe_array[eID].name, + probe_array[eID].format, + ltt_trace, &probe_array[eID]); + if (!result) + printk(KERN_INFO "%s LTT unable to register probe %s\n", + "SH", probe_array[eID].name); + } + return 0; +} + +static void __exit arch_probe_exit(void) +{ + uint8_t eID; + int err; + + for (eID = 0; eID < NUM_PROBES; eID++) { + marker_remove_probe(probe_array[eID].name); + } + synchronize_sched(); /* Wait for probes to finish */ + err = ltt_facility_unregister(facility.id); + if (err) + printk(KERN_WARNING + "%s LTT : Error in unregistering facility %s\n", + "SH", facility.name); +} + +module_init(arch_probe_init); +module_exit(arch_probe_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION(FACILITY_NAME " probe"); --- linux/ltt/Kconfig.orig 2007-07-05 11:39:57.000000000 +0200 +++ linux/ltt/Kconfig 2007-07-05 11:41:00.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