diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/ChangeLog | 49 | ||||
-rw-r--r-- | runtime/io.c | 20 | ||||
-rw-r--r-- | runtime/map.c | 4 | ||||
-rw-r--r-- | runtime/mempool.c | 37 | ||||
-rw-r--r-- | runtime/print.c | 36 | ||||
-rw-r--r-- | runtime/procfs.c | 16 | ||||
-rw-r--r-- | runtime/regs.c | 37 | ||||
-rw-r--r-- | runtime/sdt.h | 232 | ||||
-rw-r--r-- | runtime/stack-i386.c | 8 | ||||
-rw-r--r-- | runtime/stack.c | 2 | ||||
-rw-r--r-- | runtime/string.c | 3 | ||||
-rw-r--r-- | runtime/string.h | 6 | ||||
-rw-r--r-- | runtime/sym.c | 4 | ||||
-rw-r--r-- | runtime/transport/ChangeLog | 48 | ||||
-rw-r--r-- | runtime/transport/control.c | 58 | ||||
-rw-r--r-- | runtime/transport/control.h | 42 | ||||
-rw-r--r-- | runtime/transport/debugfs.c | 45 | ||||
-rw-r--r-- | runtime/transport/procfs.c | 263 | ||||
-rw-r--r-- | runtime/transport/relayfs.c | 4 | ||||
-rw-r--r-- | runtime/transport/symbols.c | 95 | ||||
-rw-r--r-- | runtime/transport/transport.c | 17 | ||||
-rw-r--r-- | runtime/transport/transport.h | 10 | ||||
-rw-r--r-- | runtime/transport/utt.c | 4 | ||||
-rw-r--r-- | runtime/unwind.c | 125 |
24 files changed, 268 insertions, 897 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 35ce7c79..13f17ab1 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,52 @@ +2009-02-18 Will Cohen <wcohen@redhat.com> + + PR 9860 + * stack-i386.c (_stp_stack_print_fallback): Remove context argument. + +2009-02-18 David Smith <dsmith@redhat.com> + + * io.c (_stp_log): Removed unused function. + * map.c (_stp_cmp): Replace _stp_log() with dbug(). + * mempool.c (_stp_mempool_resize): Removed unused function. + * print.c (next_fmt): Removed unused function. + * procfs.c: Removed unused variable '_stp_num_procfs_files'. + * regs.c (_stp_ret_addr): Removed unused function. + * string.c (_stp_text_str): Removed unused variable 'len'. + * string.h: Removed unused variable '_stdout_' and function + declaration for deleted function '_stp_vsprintf'. + * sym.c: Removed unused variables. + * unwind.c (_stp_create_unwind_hdr): Removed unused function. + +2009-02-17 Mark Wielaard <scox@redhat.com> + + * sdt.h: Move to ../includes/sys. + +2009-02-16 Mark Wielaard <scox@redhat.com> + + * sdt.h (STAP_PROBE): Take provider and probe as arguments. + +2009-02-16 Mark Wielaard <scox@redhat.com> + + * sdt.h (STAP_PROBE9): Fix )( typo in parm9. + +2009-02-15 Stan Cox <scox@redhat.com> + + * sdt.h (STAP_PROBE): Handle c++ via .probe, c via .label. + +2009-02-13 David Smith <dsmith@redhat.com> + + * stack.c: Fixed compile problems on systems with older kernels + (like RHEL4). + + * procfs.c: Added macros to guard against multiple inclusion. + +2009-02-12 David Smith <dsmith@redhat.com> + + * procfs.c (_stp_rmdir_proc_module): Changed + _stp_lock_debugfs()/_stp_unlock_debugfs() to + _stp_lock_transport_dir()/_stp_unlock_transport_dir(). + (_stp_mkdir_proc_module): Ditto. + 2009-02-11 Tim Moore <timoore@redhat.com> * stack.c (_stp_stack_print_fallback): Implementation that uses kernel diff --git a/runtime/io.c b/runtime/io.c index c7223fb0..8ddb53ac 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * I/O for printing warnings, errors and debug messages - * Copyright (C) 2005-2008 Red Hat Inc. + * Copyright (C) 2005-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -56,24 +56,6 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f put_cpu(); } -/** Logs Data. - * This function sends the message immediately to staprun. It - * will also be sent over the bulk transport (relayfs) if it is - * being used. If the last character is not a newline, then one - * is added. This function is not as efficient as _stp_printf() - * and should only be used for urgent messages. You probably want - * dbug(), or _stp_warn(). - * @param fmt A variable number of args. - * @todo Evaluate if this function is necessary. - */ -static void _stp_log (const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - _stp_vlog (INFO, NULL, 0, fmt, args); - va_end(args); -} - /** Prints warning. * This function sends a warning message immediately to staprun. It * will also be sent over the bulk transport (relayfs) if it is diff --git a/runtime/map.c b/runtime/map.c index 56f67dfb..de25d6f3 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Map Functions - * Copyright (C) 2005, 2006, 2007, 2008 Red Hat Inc. + * Copyright (C) 2005-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -444,7 +444,7 @@ static int _stp_cmp (struct list_head *a, struct list_head *b, int keynum, int d ret = 1; else ret = 0; - //_stp_log ("comparing %s and %s and returning %d\n", _stp_get_str(m1), _stp_get_str(m2), ret); + //dbug ("comparing %s and %s and returning %d\n", _stp_get_str(m1), _stp_get_str(m2), ret); return ret; } else { int64_t a,b; diff --git a/runtime/mempool.c b/runtime/mempool.c index 0fbb4326..f8831428 100644 --- a/runtime/mempool.c +++ b/runtime/mempool.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Preallocated memory pools - * Copyright (C) 2008 Red Hat Inc. + * Copyright (C) 2008-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -72,41 +72,6 @@ err: return NULL; } -/* Resize a memory pool */ -static int _stp_mempool_resize(_stp_mempool_t *pool, size_t num) -{ - int i; - unsigned long flags; - struct _stp_mem_buffer *m; - - if (unlikely(num == 0 || num == pool->num)) - return pool->num; - - if (num > pool->num) { - for (i = 0; i < num - pool->num; i++) { - m = (struct _stp_mem_buffer *)_stp_kmalloc(pool->size); - if (unlikely(m == NULL)) - goto done; - m->pool = pool; - pool->num++; - spin_lock_irqsave(&pool->lock, flags); - list_add((struct list_head *)m, &pool->free_list); - spin_unlock_irqrestore(&pool->lock, flags); - } - } else { - for (i = 0; i < pool->num - num; i++) { - spin_lock_irqsave(&pool->lock, flags); - m = (struct _stp_mem_buffer *)pool->free_list.next; - list_del(&m->list); - spin_unlock_irqrestore(&pool->lock, flags); - _stp_kfree(m); - } - pool->num = num; - } -done: - return num; -} - /* allocate a buffer from a memory pool */ static void *_stp_mempool_alloc(_stp_mempool_t *pool) { diff --git a/runtime/print.c b/runtime/print.c index 54919876..2c84d3c9 100644 --- a/runtime/print.c +++ b/runtime/print.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Print Functions - * Copyright (C) 2007-2008 Red Hat Inc. + * Copyright (C) 2007-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -41,7 +41,7 @@ typedef struct __stp_pbuf { static void *Stp_pbuf = NULL; -/** private buffer for _stp_log() */ +/** private buffer for _stp_vlog() */ #define STP_LOG_BUF_LEN 256 typedef char _stp_lbuf[STP_LOG_BUF_LEN]; @@ -233,7 +233,6 @@ static void _stp_print (const char *str) static void _stp_print_char (const char c) { - char *buf; _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); int size = STP_BUFFER_SIZE - pb->len; if (unlikely(1 >= size)) @@ -243,37 +242,6 @@ static void _stp_print_char (const char c) pb->len ++; } -/* This function is used when printing maps or stats. */ -/* Probably belongs elsewhere, but is here for now. */ -/* It takes a format specification like those used for */ -/* printing maps and stats. It prints chars until it sees */ -/* a special format char (beginning with '%'. Then it */ -/* returns a pointer to that. */ -static char *next_fmt(char *fmt, int *num) -{ - char *f = fmt; - int in_fmt = 0; - *num = 0; - while (*f) { - if (in_fmt) { - if (*f == '%') { - _stp_print_char('%'); - in_fmt = 0; - } else if (*f > '0' && *f <= '9') { - *num = *f - '0'; - f++; - return f; - } else - return f; - } else if (*f == '%') - in_fmt = 1; - else - _stp_print_char(*f); - f++; - } - return f; -} - static void _stp_print_kernel_info(char *vstr, int ctx, int num_probes) { #ifdef DEBUG_MEM diff --git a/runtime/procfs.c b/runtime/procfs.c index 4011ebfc..d6b75336 100644 --- a/runtime/procfs.c +++ b/runtime/procfs.c @@ -14,9 +14,11 @@ * number of needed files. */ +#ifndef _STP_PROCFS_C_ +#define _STP_PROCFS_C_ + #define STP_MAX_PROCFS_FILES 16 static int _stp_num_pde = 0; -static int _stp_num_procfs_files = 0; static struct proc_dir_entry *_stp_pde[STP_MAX_PROCFS_FILES]; static struct proc_dir_entry *_stp_procfs_files[STP_MAX_PROCFS_FILES]; static struct proc_dir_entry *_stp_proc_stap = NULL; @@ -45,7 +47,7 @@ static void _stp_rmdir_proc_module(void) } if (_stp_proc_stap) { - if (!_stp_lock_debugfs()) { + if (!_stp_lock_transport_dir()) { errk("Unable to lock transport directory.\n"); return; } @@ -62,7 +64,7 @@ static void _stp_rmdir_proc_module(void) _stp_proc_stap = NULL; } - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); } } @@ -76,7 +78,7 @@ static int _stp_mkdir_proc_module(void) if (_stp_proc_root == NULL) { struct nameidata nd; - if (!_stp_lock_debugfs()) { + if (!_stp_lock_transport_dir()) { errk("Unable to lock transport directory.\n"); goto done; } @@ -90,7 +92,7 @@ static int _stp_mkdir_proc_module(void) /* doesn't exist, so create it */ _stp_proc_stap = proc_mkdir ("systemtap", NULL); if (_stp_proc_stap == NULL) { - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); goto done; } } else { @@ -110,7 +112,7 @@ static int _stp_mkdir_proc_module(void) _stp_proc_root->owner = THIS_MODULE; #endif - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); } done: return (_stp_proc_root) ? 1 : 0; @@ -209,3 +211,5 @@ static void _stp_close_procfs(void) _stp_num_pde = 0; _stp_rmdir_proc_module(); } + +#endif /* _STP_PROCFS_C_ */ diff --git a/runtime/regs.c b/runtime/regs.c index 2f7c741d..e963affa 100644 --- a/runtime/regs.c +++ b/runtime/regs.c @@ -23,43 +23,6 @@ * @{ */ - -/** Get the current return address. - * Call from kprobes (not jprobes). - * @param regs The pt_regs saved by the kprobe. - * @return The return address saved in the stack pointer. - * @note i386 and x86_64 only so far. - */ - -static unsigned long _stp_ret_addr (struct pt_regs *regs) -{ -#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__)) - unsigned long *ra = (unsigned long *)regs->sp; - if (ra) - return *ra; - else - return 0; -#elif defined (__x86_64__) - unsigned long *ra = (unsigned long *)regs->rsp; - if (ra) - return *ra; - else - return 0; -#elif defined (__i386__) - return regs->esp; -#elif defined (__powerpc64__) || defined (__arm__) - return REG_LINK(regs); -#elif defined (__ia64__) - return regs->b0; -#elif defined (__s390__) || defined (__s390x__) - return regs->gprs[14]; -#elif defined (__arm__) - return regs->ARM_r0; -#else - #error Unimplemented architecture -#endif -} - /** Get the current return address for a return probe. * Call from kprobe return probe. * @param ri Pointer to the struct kretprobe_instance. diff --git a/runtime/sdt.h b/runtime/sdt.h deleted file mode 100644 index 905074ad..00000000 --- a/runtime/sdt.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (C) 2005-2009 Red Hat Inc. -// Copyright (C) 2006 Intel Corporation. -// -// This file is part of systemtap, and is free software. You can -// redistribute it and/or modify it under the terms of the GNU General -// Public License (GPL); either version 2, or (at your option) any -// later version. - -#include <string.h> - -#if _LP64 -#define STAP_PROBE_STRUCT_ARG(arg) \ - __uint64_t arg; -#else -#define STAP_PROBE_STRUCT_ARG(arg) \ - long arg __attribute__ ((aligned(8))); -#endif - -#define STAP_SENTINEL 0x31425250 - -#define STAP_PROBE_STRUCT(probe,type,argc) \ -struct _probe_ ## probe \ -{ \ - int probe_type; \ - STAP_PROBE_STRUCT_ARG (probe_name); \ - STAP_PROBE_STRUCT_ARG (probe_arg); \ -}; \ -static char probe ## _ ## probe_name [strlen(#probe)+1] \ - __attribute__ ((section (".probes"))) \ - = #probe; \ -static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; - -#define STAP_CONCAT(a,b) a ## b -#define STAP_LABEL(p,n) \ - STAP_CONCAT(_stapprobe1_ ## p ## _, n) - -// The goto _probe_ prevents the label from "drifting" -#ifdef USE_STAP_PROBE -#define STAP_PROBE(provider,probe) \ - STAP_PROBE_STRUCT(probe,0,0) \ - _stap_probe_0 (_probe_ ## probe.probe_name); -#else -#define STAP_PROBE(provider,probe) \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop"); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__); -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE1(provider,probe,arg1) \ - STAP_PROBE_STRUCT(probe,0,1) \ - _stap_probe_1 (_probe_ ## probe.probe_name,(size_t)arg1); -#else -#define STAP_PROBE1(provider,probe,parm1) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE2(provider,probe,arg1,arg2) \ - STAP_PROBE_STRUCT(probe,0,2) \ - _stap_probe_2 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2); -#else -#define STAP_PROBE2(provider,probe,parm1,parm2) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE3(provider,probe,arg1,arg2,arg3) \ - STAP_PROBE_STRUCT(probe,0,3) \ - _stap_probe_3 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3); -#else -#define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE4(provider,probe,arg1,arg2,arg3,arg4) \ - STAP_PROBE_STRUCT(probe,0,4) \ - _stap_probe_4 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4); -#else -#define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE5(provider,probe,arg1,arg2,arg3,arg4,arg5) \ - STAP_PROBE_STRUCT(probe,0,5) \ - _stap_probe_5 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5); -#else -#define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE6(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6) \ - STAP_PROBE_STRUCT(probe,0,6) \ - _stap_probe_6 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6); -#else -#define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE7(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - STAP_PROBE_STRUCT(probe,0,7) \ - _stap_probe_7 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7); -#else -#define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE8(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \ - STAP_PROBE_STRUCT(probe,0,8) \ - _stap_probe_8 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7,(size_t)arg8); -#else -#define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#ifdef USE_STAP_PROBE -#define STAP_PROBE9(provider,probe,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \ - STAP_PROBE_STRUCT(probe,0,9) \ - _stap_probe_9 (_probe_ ## probe.probe_name,(size_t)arg1,(size_t)arg2,(size_t)arg3,(size_t)arg4,(size_t)arg5,(size_t)arg6,(size_t)arg7,(size_t)arg8,(size_t)arg9); -#else -#define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ - {volatile typeof((parm1)) arg1 __attribute__ ((unused)) = parm1; \ - volatile typeof((parm2)) arg2 __attribute__ ((unused)) = parm2; \ - volatile typeof((parm3)) arg3 __attribute__ ((unused)) = parm3; \ - volatile typeof((parm4)) arg4 __attribute__ ((unused)) = parm4; \ - volatile typeof((parm5)) arg5 __attribute__ ((unused)) = parm5; \ - volatile typeof((parm6)) arg6 __attribute__ ((unused)) = parm6; \ - volatile typeof((parm7)) arg7 __attribute__ ((unused)) = parm7; \ - volatile typeof((parm8)) arg8 __attribute__ ((unused)) = parm8; \ - volatile typeof((parm9)) arg9 __attribute__ ((unused)) = parm9; \ -STAP_LABEL(probe,__LINE__): \ - asm volatile ("nop" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8), "g"(arg9)); \ - STAP_PROBE_STRUCT(probe,1,(size_t)&& STAP_LABEL(probe,__LINE__)) \ - if (__builtin_expect(_probe_ ## probe.probe_type < 0, 0)) \ - goto STAP_LABEL(probe,__LINE__);} -#endif - -#define DTRACE_PROBE(provider,probe) \ -STAP_PROBE(provider,probe) -#define DTRACE_PROBE1(provider,probe,parm1) \ -STAP_PROBE1(provider,probe,parm1) -#define DTRACE_PROBE2(provider,probe,parm1,parm2) \ -STAP_PROBE2(provider,probe,parm1,parm2) -#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ -STAP_PROBE3(provider,probe,parm1,parm2,parm3) -#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ -STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) -#define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ -STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) -#define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ -STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) -#define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ -STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) -#define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ -STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) -#define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ -STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index 2d3ac53c..3c3921ea 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -15,10 +15,10 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ #ifndef CONFIG_STACKTRACE -static void _stp_stack_print_fallback(unsigned long context, unsigned long stack, int verbose, int levels) +static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; - while (levels && _stp_valid_stack_ptr(context, stack)) { + while (levels && stack & (THREAD_SIZE-1)) { if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) { /* cannot access stack. give up. */ return; @@ -71,11 +71,11 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) /* If an error happened or we hit a kretprobe trampoline, use fallback backtrace */ /* FIXME: is there a way to unwind across kretprobe trampolines? */ if (ret < 0 || (ret > 0 && UNW_PC(&info) == _stp_kretprobe_trampoline)) - _stp_stack_print_fallback(context, UNW_SP(&info), verbose, levels); + _stp_stack_print_fallback(UNW_SP(&info), verbose, levels); break; } #else /* ! STP_USE_DWARF_UNWINDER */ - _stp_stack_print_fallback(context, (unsigned long)®_SP(regs), verbose, levels); + _stp_stack_print_fallback((unsigned long)®_SP(regs), verbose, levels); #endif /* STP_USE_FRAME_POINTER */ #endif } diff --git a/runtime/stack.c b/runtime/stack.c index 25d0817d..2a133398 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -27,8 +27,10 @@ #define MAXBACKTRACE 20 +#ifdef CONFIG_STACKTRACE #include <linux/stacktrace.h> #include <asm/stacktrace.h> +#endif static void _stp_stack_print_fallback(unsigned long, int, int); diff --git a/runtime/string.c b/runtime/string.c index c087c783..cdafbf64 100644 --- a/runtime/string.c +++ b/runtime/string.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * String Functions - * Copyright (C) 2005, 2006, 2007 Red Hat Inc. + * Copyright (C) 2005, 2006, 2007, 2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -62,7 +62,6 @@ static int _stp_vscnprintf(char *buf, size_t size, const char *fmt, va_list args */ static void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) { - const int length = len; char c, *out = outstr; if (len == 0 || len > MAXSTRINGLEN-1) diff --git a/runtime/string.h b/runtime/string.h index c955da6c..f4d4cc05 100644 --- a/runtime/string.h +++ b/runtime/string.h @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * Copyright (C) 2005, 2007 Red Hat Inc. + * Copyright (C) 2005, 2007, 2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -9,11 +9,7 @@ #ifndef _STRING_H_ #define _STRING_H_ -/* set up a special stdout string */ -static char _stp_stdout[] = "_stdout_"; - #define to_oct_digit(c) ((c) + '0') -static void _stp_vsprintf (char *str, const char *fmt, va_list args); static void _stp_text_str(char *out, char *in, int len, int quoted, int user); /* diff --git a/runtime/sym.c b/runtime/sym.c index 62c9f3ce..1d88a862 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Symbolic Lookup Functions - * Copyright (C) 2005-2008 Red Hat Inc. + * Copyright (C) 2005-2009 Red Hat Inc. * Copyright (C) 2006 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -25,7 +25,6 @@ static unsigned long _stp_module_relocate(const char *module, const char *sectio { static struct _stp_module *last = NULL; static struct _stp_section *last_sec; - unsigned long flags; unsigned i, j; /* if module is -1, we invalidate last. _stp_del_module calls this when modules are deleted. */ @@ -114,7 +113,6 @@ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbo struct _stp_module *m = NULL; struct _stp_section *sec = NULL; struct _stp_symbol *s = NULL; - unsigned long flags; unsigned end, begin = 0; m = _stp_mod_sec_lookup(addr, &sec); diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index 02f9f119..14abee41 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,51 @@ +2009-02-18 David Smith <dsmith@redhat.com> + + * control.c: Removed unused variable '_stp_current_buffers'. + * procfs.c (_stp_set_buffers): Removed unused function. + (_stp_register_ctl_channel_fs): Removed unused variables and + label. + * symbols.c (u32_swap): Removed unused function. + (generic_swap): Ditto. + (_stp_sort): Ditto. + (_stp_section_is_interesting): Ditto. + * transport.c (_stp_transport_init): Removed unused variable + 'ret'. + +2009-02-17 David Smith <dsmith@redhat.com> + + * control.c: Contains generic control channel functions. + * procfs.c: Specific procfs control channel functions. All generic + control channel functions moved to control.c. + * debugfs.c: New file containing debugfs specific control channel + functions. + * control.h: New file. + * transport.c: Updated file inclusion. + +2009-02-13 David Smith <dsmith@redhat.com> + + * procfs.c: Added inclusion of ../procfs.c for + _stp_mkdir_proc_module(). + +2009-02-12 David Smith <dsmith@redhat.com> + + * transport.c: Moved inclusion of procfs.c to + procfs_derived_probe_group::emit_module_decls() in tapsets.cxx. + + * transport.c (_stp_lock_transport_dir): Renamed from + _stp_lock_debugfs(), since on older kernels this actually uses + procfs. + (_stp_unlock_transport_dir): Renamed from _stp_unlock_debugfs(), + since on older kernels this actually uses procfs. + (_stp_lock_transport_dir): Changed + _stp_lock_debugfs()/_stp_unlock_debugfs() to + _stp_lock_transport_dir()/_stp_unlock_transport_dir(). + * transport.h: Ditto. Also added _stp_transport_init() + prototype. + * utt.c (utt_remove_root): Changed + _stp_lock_debugfs()/_stp_unlock_debugfs() to + _stp_lock_transport_dir()/_stp_unlock_transport_dir(). + * relayfs.c (_stp_remove_relay_root): Ditto. + 2009-02-05 Frank Ch. Eigler <fche@elastic.org> PR9740/9816? diff --git a/runtime/transport/control.c b/runtime/transport/control.c index 93db97e1..edde244d 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -1,7 +1,7 @@ /* -*- linux-c -*- * - * debugfs control channel - * Copyright (C) 2007-2008 Red Hat Inc. + * control channel + * Copyright (C) 2007-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -9,9 +9,6 @@ * later version. */ -#define STP_DEFAULT_BUFFERS 50 -static int _stp_current_buffers = STP_DEFAULT_BUFFERS; - static _stp_mempool_t *_stp_pool_q; static struct list_head _stp_ctl_ready_q; static DEFINE_SPINLOCK(_stp_ctl_ready_lock); @@ -72,13 +69,6 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz return count; /* Pretend that we absorbed the entire message. */ } -struct _stp_buffer { - struct list_head list; - int len; - int type; - char buf[STP_CTL_BUFFER_SIZE]; -}; - static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq); #ifdef DEBUG_TRANS @@ -114,11 +104,16 @@ static int _stp_ctl_write(int type, void *data, unsigned len) { struct _stp_buffer *bptr; unsigned long flags; + unsigned hlen; #ifdef DEBUG_TRANS _stp_ctl_write_dbug(type, data, len); #endif + hlen = _stp_ctl_write_fs(type, data, len); + if (hlen > 0) + return hlen; + /* make sure we won't overflow the buffer */ if (unlikely(len > STP_CTL_BUFFER_SIZE)) return 0; @@ -153,7 +148,8 @@ static int _stp_ctl_send(int type, void *data, int len) return err; } -static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos) +static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { struct _stp_buffer *bptr; int len; @@ -178,10 +174,12 @@ static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t cou /* write it out */ len = bptr->len + 4; if (len > count || copy_to_user(buf, &bptr->type, len)) { - /* now what? We took it off the queue then failed to send it */ - /* we can't put it back on the queue because it will likely be out-of-order */ - /* fortunately this should never happen */ - /* FIXME need to mark this as a transport failure */ + /* Now what? We took it off the queue then failed to + * send it. We can't put it back on the queue because + * it will likely be out-of-order. Fortunately, this + * should never happen. + * + * FIXME: need to mark this as a transport failure. */ errk("Supplied buffer too small. count:%d len:%d\n", (int)count, len); return -EFAULT; } @@ -215,47 +213,33 @@ static struct file_operations _stp_ctl_fops_cmd = { .release = _stp_ctl_close_cmd, }; -static struct dentry *_stp_cmd_file = NULL; - static int _stp_register_ctl_channel(void) { - int i; - struct list_head *p, *tmp; - char buf[32]; - - if (_stp_utt == NULL) { - errk("_expected _stp_utt to be set.\n"); - return -1; - } - INIT_LIST_HEAD(&_stp_ctl_ready_q); /* allocate buffers */ - _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), STP_DEFAULT_BUFFERS); + _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), + STP_DEFAULT_BUFFERS); if (unlikely(_stp_pool_q == NULL)) goto err0; _stp_allocated_net_memory += sizeof(struct _stp_buffer) * STP_DEFAULT_BUFFERS; - /* create [debugfs]/systemtap/module_name/.cmd */ - _stp_cmd_file = debugfs_create_file(".cmd", 0600, _stp_utt->dir, NULL, &_stp_ctl_fops_cmd); - if (_stp_cmd_file == NULL) + if (_stp_register_ctl_channel_fs() != 0) goto err0; - _stp_cmd_file->d_inode->i_uid = _stp_uid; - _stp_cmd_file->d_inode->i_gid = _stp_gid; return 0; err0: _stp_mempool_destroy(_stp_pool_q); - errk("Error creating systemtap debugfs entries.\n"); + errk("Error creating systemtap control channel.\n"); return -1; } static void _stp_unregister_ctl_channel(void) { struct list_head *p, *tmp; - if (_stp_cmd_file) - debugfs_remove(_stp_cmd_file); + + _stp_unregister_ctl_channel_fs(); /* Return memory to pool and free it. */ list_for_each_safe(p, tmp, &_stp_ctl_ready_q) { diff --git a/runtime/transport/control.h b/runtime/transport/control.h new file mode 100644 index 00000000..5e7204ee --- /dev/null +++ b/runtime/transport/control.h @@ -0,0 +1,42 @@ +/* -*- linux-c -*- + * + * control channel header + * Copyright (C) 2009 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _CONTROL_H_ +#define _CONTROL_H_ + +#include <linux/spinlock.h> +#include <linux/list.h> + +static _stp_mempool_t *_stp_pool_q; +static struct list_head _stp_ctl_ready_q; +static spinlock_t _stp_ctl_ready_lock; +static wait_queue_head_t _stp_ctl_wq; + +struct _stp_buffer { + struct list_head list; + int len; + int type; + char buf[STP_CTL_BUFFER_SIZE]; +}; + +static struct file_operations _stp_ctl_fops_cmd; + +static int _stp_ctl_send(int type, void *data, int len); + +static int _stp_ctl_write_fs(int type, void *data, unsigned len); + +static int _stp_register_ctl_channel(void); +static void _stp_unregister_ctl_channel(void); + +static int _stp_register_ctl_channel_fs(void); +static void _stp_unregister_ctl_channel_fs(void); + +#endif /* _CONTROL_H_ */ diff --git a/runtime/transport/debugfs.c b/runtime/transport/debugfs.c new file mode 100644 index 00000000..dc651a56 --- /dev/null +++ b/runtime/transport/debugfs.c @@ -0,0 +1,45 @@ +/* -*- linux-c -*- + * + * debugfs functions + * Copyright (C) 2009 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#define STP_DEFAULT_BUFFERS 50 + +inline static int _stp_ctl_write_fs(int type, void *data, unsigned len) +{ + return 0; +} + +static struct dentry *_stp_cmd_file = NULL; + +static int _stp_register_ctl_channel_fs(void) +{ + if (_stp_utt == NULL) { + errk("_expected _stp_utt to be set.\n"); + return -1; + } + + /* create [debugfs]/systemtap/module_name/.cmd */ + _stp_cmd_file = debugfs_create_file(".cmd", 0600, _stp_utt->dir, + NULL, &_stp_ctl_fops_cmd); + if (_stp_cmd_file == NULL) { + errk("Error creating systemtap debugfs entries.\n"); + return -1; + } + _stp_cmd_file->d_inode->i_uid = _stp_uid; + _stp_cmd_file->d_inode->i_gid = _stp_gid; + + return 0; +} + +static void _stp_unregister_ctl_channel_fs(void) +{ + if (_stp_cmd_file) + debugfs_remove(_stp_cmd_file); +} diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c index ca33e0fd..6afbdea1 100644 --- a/runtime/transport/procfs.c +++ b/runtime/transport/procfs.c @@ -1,7 +1,7 @@ /* -*- linux-c -*- * * /proc transport and control - * Copyright (C) 2005-2008 Red Hat Inc. + * Copyright (C) 2005-2009 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -9,12 +9,9 @@ * later version. */ -#define STP_DEFAULT_BUFFERS 256 -static int _stp_current_buffers = STP_DEFAULT_BUFFERS; +#include "../procfs.c" // for _stp_mkdir_proc_module() -static _stp_mempool_t *_stp_pool_q; -static struct list_head _stp_ctl_ready_q; -DEFINE_SPINLOCK(_stp_ctl_ready_lock); +#define STP_DEFAULT_BUFFERS 256 #ifdef STP_BULKMODE extern int _stp_relay_flushing; @@ -60,112 +57,19 @@ static struct file_operations _stp_proc_fops = { }; #endif /* STP_BULKMODE */ - -static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos) -{ - int type; - static int started = 0; - - if (count < sizeof(int)) - return 0; - - if (get_user(type, (int __user *)buf)) - return -EFAULT; - -#if DEBUG_TRANSPORT > 0 - if (type < STP_MAX_CMD) - _dbug("Got %s. len=%d\n", _stp_command_name[type], (int)count); -#endif - - count -= sizeof(int); - buf += sizeof(int); - - switch (type) { - case STP_START: - if (started == 0) { - struct _stp_msg_start st; - if (count < sizeof(st)) - return 0; - if (copy_from_user(&st, buf, sizeof(st))) - return -EFAULT; - _stp_handle_start(&st); - started = 1; - } - break; - - case STP_EXIT: - _stp_exit_flag = 1; - break; - - case STP_RELOCATION: - _stp_do_relocation (buf, count); - break; - - case STP_READY: - break; - - default: - errk("invalid command type %d\n", type); - return -EINVAL; - } - - return count; -} - -struct _stp_buffer { - struct list_head list; - int len; - int type; - char buf[STP_CTL_BUFFER_SIZE]; -}; - -static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq); - -#if DEBUG_TRANSPORT > 0 -static void _stp_ctl_write_dbug(int type, void *data, int len) -{ - char buf[64]; - switch (type) { - case STP_START: - _dbug("sending STP_START\n"); - break; - case STP_EXIT: - _dbug("sending STP_EXIT\n"); - break; - case STP_OOB_DATA: - snprintf(buf, sizeof(buf), "%s", (char *)data); - _dbug("sending %d bytes of STP_OOB_DATA: %s\n", len, buf); - break; - case STP_SYSTEM: - snprintf(buf, sizeof(buf), "%s", (char *)data); - _dbug("sending STP_SYSTEM: %s\n", buf); - break; - case STP_TRANSPORT: - _dbug("sending STP_TRANSPORT\n"); - break; - default: - _dbug("ERROR: unknown message type: %d\n", type); - break; - } -} -#endif - -static int _stp_ctl_write(int type, void *data, int len) +inline static int _stp_ctl_write_fs(int type, void *data, unsigned len) { struct _stp_buffer *bptr; unsigned long flags; -#if DEBUG_TRANSPORT > 0 - _stp_ctl_write_dbug(type, data, len); -#endif - #define WRITE_AGG #ifdef WRITE_AGG - spin_lock_irqsave(&_stp_ctl_ready_lock, flags); if (!list_empty(&_stp_ctl_ready_q)) { bptr = (struct _stp_buffer *)_stp_ctl_ready_q.prev; - if (bptr->len + len <= STP_BUFFER_SIZE && type == STP_REALTIME_DATA && bptr->type == STP_REALTIME_DATA) { + if ((bptr->len + len) <= STP_CTL_BUFFER_SIZE + && type == STP_REALTIME_DATA + && bptr->type == STP_REALTIME_DATA) { memcpy(bptr->buf + bptr->len, data, len); bptr->len += len; spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags); @@ -174,121 +78,9 @@ static int _stp_ctl_write(int type, void *data, int len) } spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags); #endif - - /* make sure we won't overflow the buffer */ - if (unlikely(len > STP_BUFFER_SIZE)) - return 0; - - /* get a buffer from the free pool */ - bptr = _stp_mempool_alloc(_stp_pool_q); - if (unlikely(bptr == NULL)) - return -1; - - bptr->type = type; - memcpy(bptr->buf, data, len); - bptr->len = len; - - /* put it on the pool of ready buffers */ - spin_lock_irqsave(&_stp_ctl_ready_lock, flags); - list_add_tail(&bptr->list, &_stp_ctl_ready_q); - spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags); - - return len; -} - - -/* send commands with timeout and retry */ -static int _stp_ctl_send(int type, void *data, int len) -{ - int err, trylimit = 50; - dbug_trans(1, "ctl_send: type=%d len=%d\n", type, len); - while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--) - msleep(5); - if (err > 0) - wake_up_interruptible(&_stp_ctl_wq); - dbug_trans(1, "returning %d\n", err); - return err; -} - - -static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - struct _stp_buffer *bptr; - int len; - unsigned long flags; - - /* wait for nonempty ready queue */ - spin_lock_irqsave(&_stp_ctl_ready_lock, flags); - while (list_empty(&_stp_ctl_ready_q)) { - spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags); - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - if (wait_event_interruptible(_stp_ctl_wq, !list_empty(&_stp_ctl_ready_q))) - return -ERESTARTSYS; - spin_lock_irqsave(&_stp_ctl_ready_lock, flags); - } - - /* get the next buffer off the ready list */ - bptr = (struct _stp_buffer *)_stp_ctl_ready_q.next; - list_del_init(&bptr->list); - spin_unlock_irqrestore(&_stp_ctl_ready_lock, flags); - - /* write it out */ - len = bptr->len + 4; - if (len > count || copy_to_user(buf, &bptr->type, len)) { - /* now what? We took it off the queue then failed to send it */ - /* we can't put it back on the queue because it will likely be out-of-order */ - /* fortunately this should never happen */ - /* FIXME need to mark this as a transport failure */ - errk("Supplied buffer too small. count:%d len:%d\n", (int)count, len); - return -EFAULT; - } - - /* put it on the pool of free buffers */ - _stp_mempool_free(bptr); - - return len; -} - -static int _stp_ctl_open_cmd(struct inode *inode, struct file *file) -{ - if (_stp_attached) - return -1; - - _stp_attach(); return 0; } -static int _stp_ctl_close_cmd(struct inode *inode, struct file *file) -{ - if (_stp_attached) - _stp_detach(); - return 0; -} - -static struct file_operations _stp_proc_fops_cmd = { - .owner = THIS_MODULE, - .read = _stp_ctl_read_cmd, - .write = _stp_ctl_write_cmd, - .open = _stp_ctl_open_cmd, - .release = _stp_ctl_close_cmd, -}; - -/* copy since proc_match is not MODULE_EXPORT'd */ -static int my_proc_match(int len, const char *name, struct proc_dir_entry *de) -{ - if (de->namelen != len) - return 0; - return !memcmp(name, de->name, len); -} - -/* set the number of buffers to use to 'num' */ -static int _stp_set_buffers(int num) -{ - dbug_trans(1, "stp_set_buffers %d\n", num); - return _stp_mempool_resize(_stp_pool_q, num); -} - static int _stp_ctl_read_bufsize(char *page, char **start, off_t off, int count, int *eof, void *data) { int len = sprintf(page, "%d,%d\n", _stp_nsubbufs, _stp_subbuf_size); @@ -303,25 +95,15 @@ static int _stp_ctl_read_bufsize(char *page, char **start, off_t off, int count, return len; } -static int _stp_register_ctl_channel(void) +static int _stp_register_ctl_channel_fs(void) { - int i; - const char *dirname = "systemtap"; - char buf[32]; #ifdef STP_BULKMODE + int i; int j; + char buf[32]; + struct proc_dir_entry *bs = NULL; #endif - - struct proc_dir_entry *de, *bs = NULL; - struct list_head *p, *tmp; - - INIT_LIST_HEAD(&_stp_ctl_ready_q); - - /* allocate buffers */ - _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), STP_DEFAULT_BUFFERS); - if (unlikely(_stp_pool_q == NULL)) - goto err0; - _stp_allocated_net_memory += sizeof(struct _stp_buffer) * STP_DEFAULT_BUFFERS; + struct proc_dir_entry *de; if (!_stp_mkdir_proc_module()) goto err0; @@ -352,11 +134,10 @@ static int _stp_register_ctl_channel(void) goto err1; de->uid = _stp_uid; de->gid = _stp_gid; - de->proc_fops = &_stp_proc_fops_cmd; + de->proc_fops = &_stp_ctl_fops_cmd; return 0; -err2: - remove_proc_entry(".cmd", _stp_proc_root); + err1: #ifdef STP_BULKMODE for (de = _stp_proc_root->subdir; de; de = de->next) @@ -373,18 +154,16 @@ err1: #endif /* STP_BULKMODE */ _stp_rmdir_proc_module(); err0: - _stp_mempool_destroy(_stp_pool_q); - errk("Error creating systemtap /proc entries.\n"); return -1; } -static void _stp_unregister_ctl_channel(void) +static void _stp_unregister_ctl_channel_fs(void) { - struct list_head *p, *tmp; - char buf[32]; #ifdef STP_BULKMODE + char buf[32]; int i; struct proc_dir_entry *de; + dbug_trans(1, "unregistering procfs\n"); for (de = _stp_proc_root->subdir; de; de = de->next) _stp_kfree(de->data); @@ -396,14 +175,6 @@ static void _stp_unregister_ctl_channel(void) remove_proc_entry("bufsize", _stp_proc_root); #endif /* STP_BULKMODE */ - remove_proc_entry(".symbols", _stp_proc_root); remove_proc_entry(".cmd", _stp_proc_root); _stp_rmdir_proc_module(); - - /* Return memory to pool and free it. */ - list_for_each_safe(p, tmp, &_stp_ctl_ready_q) { - list_del(p); - _stp_mempool_free(p); - } - _stp_mempool_destroy(_stp_pool_q); } diff --git a/runtime/transport/relayfs.c b/runtime/transport/relayfs.c index 5bd3ff4d..6eefda8d 100644 --- a/runtime/transport/relayfs.c +++ b/runtime/transport/relayfs.c @@ -68,12 +68,12 @@ static void _stp_remove_relay_dir(struct dentry *dir) static void _stp_remove_relay_root(struct dentry *root) { if (root) { - if (!_stp_lock_debugfs()) { + if (!_stp_lock_transport_dir()) { errk("Unable to lock transport directory.\n"); return; } _stp_remove_relay_dir(root); - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); } } diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index b9458ada..a329effe 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -1,26 +1,18 @@ /* -*- linux-c -*- * symbols.c - stp symbol and module functions * - * Copyright (C) Red Hat Inc, 2006-2008 + * Copyright (C) Red Hat Inc, 2006-2009 * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General * Public License (GPL); either version 2, or (at your option) any * later version. - * - * The u32_swap(), generic_swap(), and sort() functions were adapted from - * lib/sort.c of kernel 2.6.22-rc5. It was written by Matt Mackall. */ #ifndef _STP_SYMBOLS_C_ #define _STP_SYMBOLS_C_ #include "../sym.h" - - -static void _stp_create_unwind_hdr(struct _stp_module *m); - - static void _stp_do_relocation(const char __user *buf, size_t count) { struct _stp_msg_relocation msg; @@ -68,89 +60,4 @@ static void _stp_do_relocation(const char __user *buf, size_t count) } /* loop over modules */ } - -static void u32_swap(void *a, void *b, int size) -{ - u32 t = *(u32 *)a; - *(u32 *)a = *(u32 *)b; - *(u32 *)b = t; -} - -static void generic_swap(void *a, void *b, int size) -{ - char *aa = a; - char *bb = b; - do { - char t = *aa; - *aa++ = *bb; - *bb++ = t; - } while (--size > 0); -} - -/** - * sort - sort an array of elements - * @base: pointer to data to sort - * @num: number of elements - * @size: size of each element - * @cmp_func: pointer to comparison function - * @swap_func: pointer to swap function or NULL - * - * This function does a heapsort on the given array. You may provide a - * swap function optimized to your element type. - * - * Sorting time is O(n log n) both on average and worst-case. While - * qsort is about 20% faster on average, it suffers from exploitable - * O(n*n) worst-case behavior and extra memory requirements that make - * it less suitable for kernel use. -*/ -static void _stp_sort(void *_base, size_t num, size_t size, - int (*cmp_func) (const void *, const void *), void (*swap_func) (void *, void *, int size)) -{ - char *base = (char*) _base; - /* pre-scale counters for performance */ - int i = (num / 2 - 1) * size, n = num * size, c, r; - - if (!swap_func) - swap_func = (size == 4 ? u32_swap : generic_swap); - - /* heapify */ - for (; i >= 0; i -= size) { - for (r = i; r * 2 + size < n; r = c) { - c = r * 2 + size; - if (c < n - size && cmp_func(base + c, base + c + size) < 0) - c += size; - if (cmp_func(base + r, base + c) >= 0) - break; - swap_func(base + r, base + c, size); - } - } - - /* sort */ - for (i = n - size; i >= 0; i -= size) { - swap_func(base, base + i, size); - for (r = 0; r * 2 + size < i; r = c) { - c = r * 2 + size; - if (c < i - size && cmp_func(base + c, base + c + size) < 0) - c += size; - if (cmp_func(base + r, base + c) >= 0) - break; - swap_func(base + r, base + c, size); - } - } -} - -/* filter out section names we don't care about */ -static int _stp_section_is_interesting(const char *name) -{ - int ret = 1; - if (!strncmp("__", name, 2) - || (!strncmp(".note", name, 5) - && strncmp(".note.gnu.build-id", name, 18)) - || !strncmp(".gnu", name, 4) - || !strncmp(".mod", name, 4)) - ret = 0; - return ret; -} - - #endif /* _STP_SYMBOLS_C_ */ diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index 97fbf860..0755781e 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -20,7 +20,6 @@ #include "time.c" #include "../mempool.c" #include "symbols.c" -#include "../procfs.c" static struct utt_trace *_stp_utt = NULL; static unsigned int utt_seq = 1; @@ -28,13 +27,15 @@ static int _stp_probes_started = 0; static pid_t _stp_target = 0; static int _stp_exit_called = 0; static int _stp_exit_flag = 0; +#include "control.h" #ifdef STP_OLD_TRANSPORT #include "relayfs.c" #include "procfs.c" #else #include "utt.c" -#include "control.c" +#include "debugfs.c" #endif +#include "control.c" /* module parameters */ static int _stp_bufsize; @@ -216,8 +217,6 @@ static struct utt_trace *_stp_utt_open(void) */ static int _stp_transport_init(void) { - int ret; - dbug_trans(1, "transport_init\n"); _stp_init_pid = current->pid; #ifdef STAPCONF_TASK_UID @@ -256,7 +255,7 @@ static int _stp_transport_init(void) goto err0; #endif - /* create debugfs/procfs control channel */ + /* create control channel */ if (_stp_register_ctl_channel() < 0) goto err1; @@ -311,7 +310,7 @@ static inline void _stp_unlock_inode(struct inode *inode) static struct dentry *_stp_lockfile = NULL; -static int _stp_lock_debugfs(void) +static int _stp_lock_transport_dir(void) { int numtries = 0; #ifdef STP_OLD_TRANSPORT @@ -326,7 +325,7 @@ static int _stp_lock_debugfs(void) return 1; } -static void _stp_unlock_debugfs(void) +static void _stp_unlock_transport_dir(void) { if (_stp_lockfile) { #ifdef STP_OLD_TRANSPORT @@ -359,7 +358,7 @@ static struct dentry *_stp_get_root_dir(const char *name) return NULL; } - if (!_stp_lock_debugfs()) { + if (!_stp_lock_transport_dir()) { errk("Couldn't lock transport directory.\n"); return NULL; } @@ -381,7 +380,7 @@ static struct dentry *_stp_get_root_dir(const char *name) errk("Could not create or find transport directory.\n"); } } - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); return root; } diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h index 11a070de..7d249c45 100644 --- a/runtime/transport/transport.h +++ b/runtime/transport/transport.h @@ -26,13 +26,17 @@ static unsigned _stp_nsubbufs = 8; static unsigned _stp_subbuf_size = 65536*4; -static void _stp_warn (const char *fmt, ...); +static int _stp_transport_init(void); static void _stp_transport_close(void); + +static void _stp_warn (const char *fmt, ...); static int _stp_print_init(void); static void _stp_print_cleanup(void); static struct dentry *_stp_get_root_dir(const char *name); -static int _stp_lock_debugfs(void); -static void _stp_unlock_debugfs(void); + +static int _stp_lock_transport_dir(void); +static void _stp_unlock_transport_dir(void); + static void _stp_attach(void); static void _stp_detach(void); static void _stp_handle_start(struct _stp_msg_start *st); diff --git a/runtime/transport/utt.c b/runtime/transport/utt.c index 59060474..915662b2 100644 --- a/runtime/transport/utt.c +++ b/runtime/transport/utt.c @@ -130,13 +130,13 @@ static void utt_set_overwrite(int overwrite) static void utt_remove_root(struct utt_trace *utt) { if (utt->utt_tree_root) { - if (!_stp_lock_debugfs()) { + if (!_stp_lock_transport_dir()) { errk("Unable to lock transport directory.\n"); return; } if (simple_empty(utt->utt_tree_root)) debugfs_remove(utt->utt_tree_root); - _stp_unlock_debugfs(); + _stp_unlock_transport_dir(); utt->utt_tree_root = NULL; } } diff --git a/runtime/unwind.c b/runtime/unwind.c index c1362237..9c704e28 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * kernel stack unwinding - * Copyright (C) 2008 Red Hat Inc. + * Copyright (C) 2008-2009 Red Hat Inc. * * Based on old kernel code that is * Copyright (C) 2002-2006 Novell, Inc. @@ -42,129 +42,6 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size) e2->fde = v; } -/* Build a binary-searchable unwind header. Also do some - * validity checks. In the future we might use */ -/* .eh_frame_hdr if it is already present. */ -static void _stp_create_unwind_hdr(struct _stp_module *m) -{ - const u8 *ptr; - unsigned long tableSize, hdrSize, last; - unsigned n = 0; - const u32 *fde; - int bad_order = 0; - struct { - u8 version; - u8 eh_frame_ptr_enc; - u8 fde_count_enc; - u8 table_enc; - unsigned long eh_frame_ptr; - unsigned int fde_count; - struct eh_frame_hdr_table_entry table[]; - } __attribute__ ((__packed__)) * header = NULL; - - /* already did this or no data? */ - if (m->unwind_hdr || m->unwind_data_len == 0) - return; - - tableSize = m->unwind_data_len; - if (tableSize & (sizeof(*fde) - 1)) { - dbug_unwind(1, "tableSize=0x%x not a multiple of 0x%x\n", (int)tableSize, (int)sizeof(*fde)); - goto bad; - } - - /* count the FDEs */ - for (fde = m->unwind_data; - tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - signed ptrType; - const u32 *cie; - - /* check for extended length */ - if ((*fde & 0xfffffff0) == 0xfffffff0) { - dbug_unwind(1, "Module %s has extended-length CIE or FDE."); - dbug_unwind(1, "This is not supported at this time."); - goto bad; - } - cie = cie_for_fde(fde, m); - if (cie == ¬_fde) - continue; /* fde was a CIE. That's OK, just skip it. */ - if (cie == NULL || cie == &bad_cie || (ptrType = fde_pointer_type(cie)) < 0) - goto bad; - /* we have a real FDE */ - ptr = (const u8 *)(fde + 2); - if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType)) - goto bad; - ++n; - } - - if (tableSize || !n) { - dbug_unwind(1, "%s: tableSize=%ld, n=%d\n", m->name, tableSize, n); - goto bad; - } - - hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) + 2 * n * sizeof(unsigned long); - header = _stp_kmalloc(hdrSize); - if (header == NULL) { - header = _stp_vmalloc(hdrSize); - if (header == NULL) - return; - } - - header->version = 1; - header->eh_frame_ptr_enc = DW_EH_PE_absptr; - header->fde_count_enc = DW_EH_PE_data4; - header->table_enc = DW_EH_PE_absptr; - _stp_put_unaligned((unsigned long)m->unwind_data, &header->eh_frame_ptr); - - BUILD_BUG_ON(offsetof(typeof(*header), fde_count) - % __alignof(typeof(header->fde_count))); - header->fde_count = n; - - BUILD_BUG_ON(offsetof(typeof(*header), table) % __alignof(typeof(*header->table))); - - n = 0; - last = 0; - tableSize = m->unwind_data_len; - for (fde = m->unwind_data; tableSize; tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - const u32 *cie = cie_for_fde(fde, m); - if (cie == ¬_fde) - continue; - if (cie == NULL || cie == &bad_cie) - goto bad; - /* we have a real FDE */ - ptr = (const u8 *)(fde + 2); - header->table[n].start = read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, fde_pointer_type(cie)); - header->table[n].fde = (unsigned long)fde; - if (header->table[n].start < last) - bad_order++; - last = header->table[n].start; - ++n; - } - WARN_ON(n != header->fde_count); - - /* Is sort ever necessary? */ - if (bad_order) - _stp_sort(header->table, n, sizeof(*header->table), cmp_eh_frame_hdr_table_entries, - swap_eh_frame_hdr_table_entries); - - m->unwind_hdr_len = hdrSize; - m->unwind_hdr = header; - return; - - /* unwind data is not acceptable. free it and return */ -bad: - dbug_unwind(1, "unwind data for %s is unacceptable. Freeing.", m->name); - if (header) { - _stp_vfree(header); - } - if (m->unwind_data) { - _stp_vfree(m->unwind_data); - m->unwind_data = NULL; - m->unwind_data_len = 0; - } - return; -} - static uleb128_t get_uleb128(const u8 **pcur, const u8 *end) { const u8 *cur = *pcur; |