diff -Nru linux/include/linux/jstrace.h.orig linux/include/linux/jstrace.h --- linux/include/linux/jstrace.h.orig Thu May 29 10:58:01 2003 +++ linux/include/linux/jstrace.h Thu May 29 11:34:12 2003 @@ -0,0 +1,57 @@ +/* + * A brief explanation. + * + * Copyright (C) 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +/* + * jstrace provide a simple interface anybody to quickly instruement + * kernel. + * + * Three facilities are provided: + * + * jstrace(" +#include + +extern void _jstrace(char*, int, char*, char*, ...); +extern int jstrace_flag; + +#define jstrace(fmt, arg...) \ + _jstrace(__FILE__, __LINE__, __func__, fmt, ##arg) + +#define jstrace_start() \ + do { \ + jstrace_flag =1; \ + _jstrace(__FILE__, __LINE__, __func__, "jstrace start"); \ + } while (0) + +#define jstrace_stop() \ + do { \ + _jstrace(__FILE__, __LINE__, __func__, "jstrace stop"); \ + jstrace_flag =0; \ + } while (0) + +#endif /* _LINUX_JSTRACE_H_ */ diff -Nru linux/kernel/jstrace.c.orig linux/kernel/jstrace.c --- linux/kernel/jstrace.c.orig Thu May 29 11:20:32 2003 +++ linux/kernel/jstrace.c Thu May 29 14:58:16 2003 @@ -0,0 +1,221 @@ +/* + * kernel run-time trace library. + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NUM_EVENT 64 +#define CUSTOM_LOG_SIZE 70 + +#define PROC_FS_PATH "sys/kernel/jstrace" + +#if !defined(CONFIG_PROC_FS) +#error "jstrace needs proc file system!" +#endif + +static struct jstrace_event { + struct timeval ts; + int cpu; + int pid; /* -1 : in interrupt context */ + + char * file; + int line; + char * function; + + char msg[CUSTOM_LOG_SIZE]; +} log[NUM_EVENT]; +static int index; + +static spinlock_t trace_lock = SPIN_LOCK_UNLOCKED; + +int jstrace_flag; + +void _jstrace(char *fname, int line, char *func, char *fmt, ...) +{ + va_list args; + unsigned long flags; + + if (!jstrace_flag) + return; + + spin_lock_irqsave(&trace_lock, flags); + + va_start(args, fmt); + vsnprintf(log[index].msg, CUSTOM_LOG_SIZE, fmt, args); + va_end(args); + + do_gettimeofday(&log[index].ts); + log[index].cpu = smp_processor_id(); + if (in_interrupt()) + log[index].pid = -1; + else + log[index].pid = current->pid; + log[index].file = fname; + log[index].line = line; + log[index].function = func; + + if (++index == NUM_EVENT) + index = 0; + + spin_unlock_irqrestore(&trace_lock, flags); +} + +static int +jstrace_input(struct file * file, const char * buf, unsigned long count, void *data) +{ + unsigned long flags; + char c; + + if (copy_from_user(&c, buf, 1)) + return -EFAULT; + + spin_lock_irqsave(&trace_lock, flags); + if (c == '1') { + jstrace_flag = 1; + } else { + jstrace_flag = 0; + } + spin_unlock_irqrestore(&trace_lock, flags); + return count; +} + +struct proc_write_handle { + char * buf; + int index; + int count; + + int fpos; + int length; +}; + +static void +proc_write_init(struct proc_write_handle *handle, char *buf, int count, int fpos) +{ + handle->buf = buf; + handle->count = count; + handle->fpos = fpos; + handle->index = 0; + handle->length = 0; +} + +/* + * returns: + * -1 : not logged yet due to fpos greater than current output length. + * 0 : logging output + * 1 : overflow, maybe partially logged, future logging stopped. + */ +static int +proc_write(struct proc_write_handle *h, char * fmt, ...) +{ + static char buf[512]; + + va_list args; + int size; + int old_length=h->length; + int start=0; + int overflow=0; + + va_start(args, fmt); + size=vsnprintf(buf, 512, fmt, args); + va_end(args); + + h->length += size; + if (h->length <= h->fpos) + return -1; + + if (h->index == h->count) + return 1; + + if (old_length <= h->fpos) + start = h->fpos - old_length; + + size -= start; + if (size > h->count - h->index) { + overflow=1; + size = h->count - h->index; + } + + strncpy(h->buf+h->index, buf+start, size); + h->index += size; + + if (overflow) + return 1; + else + return 0; +} + +static int +jstrace_output(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + unsigned long flags; + int i; + int ret; + struct proc_write_handle h; + + spin_lock_irqsave(&trace_lock, flags); + jstrace_flag = 0; // stop logging first + spin_unlock_irqrestore(&trace_lock, flags); + + proc_write_init(&h, page, count, off); + + proc_write(&h, "time stamp \tcpu:pid\tfile:line(func) - msg\n"); + for(i=index;;) { + if (!log[i].file) { + ret = proc_write(&h, "(EMPTY)\n"); + } else { + ret = proc_write(&h, "%lu:%lu\t%d:%d\t%s:%d(%s)-%s\n", + log[i].ts.tv_sec&0xffff, + log[i].ts.tv_usec, + log[i].cpu, log[i].pid, + log[i].file, log[i].line, + log[i].function,log[i].msg); + } + if (++i == NUM_EVENT) + i=0; + if (i == index) + break; + if (ret == 1) + break; + } + + + /* fix for user read */ + *start = page; + if (ret!=1) + *eof = 0; + else + *eof = 1; + return h.index; +} + +int __init +jstrace_init(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry(PROC_FS_PATH, S_IWUSR | S_IRUGO, NULL); + if (entry) { + entry->read_proc = jstrace_output; + entry->write_proc = jstrace_input; + } + return 0; +} + +__initcall(jstrace_init); diff -Nru linux/kernel/Makefile.orig linux/kernel/Makefile --- linux/kernel/Makefile.orig Wed May 28 10:57:13 2003 +++ linux/kernel/Makefile Thu May 29 12:08:15 2003 @@ -15,7 +15,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ sysctl.o acct.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o context.o + signal.o sys.o kmod.o context.o jstrace.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_UID16) += uid16.o