summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhunt <hunt>2008-02-27 19:45:45 +0000
committerhunt <hunt>2008-02-27 19:45:45 +0000
commit9a5de18784b77de82e5121861fac892c2d4d2630 (patch)
tree54d0a3fb138a31627788606953bb1cb37897caf8
parenta2dc47ddef0dbed1b0dc912c876f5f57f97c1ede (diff)
downloadsystemtap-steved-9a5de18784b77de82e5121861fac892c2d4d2630.tar.gz
systemtap-steved-9a5de18784b77de82e5121861fac892c2d4d2630.tar.xz
systemtap-steved-9a5de18784b77de82e5121861fac892c2d4d2630.zip
2008-02-27 Martin Hunt <hunt@redhat.com>
* sym.h (_stp_module): Add text_size, lock, and unwind data pointer. * sym.c (_stp_find_module_by_addr): New function. (_stp_kallsyms_lookup): Call _stp_find_module_by_addr(). (_stp_get_unwind_info): New. * runtime.h: Move debug macros to debug.h. Include it. * debug.h: New file. * map.c: Update debug calls. * map-gen.c: Update debug calls. * pmap-gen.c: Update debug calls. * mempool.c: New file. * symbols.c: Use rwlocks. Use new dbug macros. Handle unwind info if present. * transport.c: Include mempool.c. Update dbug and kbug calls to new macros. * transport_msgs.h (_stp_command_name): Add struct containing message names for debugging. * control.c, procfs.c: Use new dbug macros. Use new mempool functions.
-rw-r--r--runtime/ChangeLog16
-rw-r--r--runtime/debug.h66
-rw-r--r--runtime/map-gen.c5
-rw-r--r--runtime/map.c6
-rw-r--r--runtime/mempool.c135
-rw-r--r--runtime/pmap-gen.c5
-rw-r--r--runtime/runtime.h18
-rw-r--r--runtime/staprun/symbols.c21
-rw-r--r--runtime/sym.c203
-rw-r--r--runtime/sym.h85
-rw-r--r--runtime/transport/ChangeLog13
-rw-r--r--runtime/transport/control.c209
-rw-r--r--runtime/transport/procfs.c288
-rw-r--r--runtime/transport/symbols.c185
-rw-r--r--runtime/transport/transport.c33
-rw-r--r--runtime/transport/transport_msgs.h23
16 files changed, 760 insertions, 551 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 512fa061..497b9d5b 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,19 @@
+2008-02-27 Martin Hunt <hunt@redhat.com>
+
+ * sym.h (_stp_module): Add text_size, lock, and unwind data
+ pointer.
+ * sym.c (_stp_find_module_by_addr): New function.
+ (_stp_kallsyms_lookup): Call _stp_find_module_by_addr().
+ (_stp_get_unwind_info): New.
+
+ * runtime.h: Move debug macros to debug.h. Include it.
+ * debug.h: New file.
+ * map.c: Update debug calls.
+ * map-gen.c: Update debug calls.
+ * pmap-gen.c: Update debug calls.
+
+ * mempool.c: New file.
+
2008-02-27 Dave Brolley <brolley@redhat.com>
PR5189
diff --git a/runtime/debug.h b/runtime/debug.h
new file mode 100644
index 00000000..8f877ede
--- /dev/null
+++ b/runtime/debug.h
@@ -0,0 +1,66 @@
+/* Systemtap Debug Macros
+ * Copyright (C) 2008 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 _STP_DEBUG_H_
+#define _STP_DEBUG_H_
+
+/* These are always on.
+ * _dbug() writes to systemtap stderr.
+ * errk() writes to the system log.
+ */
+#define _dbug(args...) _stp_dbug(__FUNCTION__, __LINE__, args)
+
+#define errk(args...) do { \
+ printk("Systemtap Error at %s:%d ",__FUNCTION__, __LINE__); \
+ printk(args); \
+ } while (0)
+
+#ifdef DEBUG_TRANSPORT
+#undef DEBUG_TRANSPORT
+#define DEBUG_TRANSPORT 1
+#else
+#define DEBUG_TRANSPORT 0
+#endif
+
+#ifdef DEBUG_UNWIND
+#undef DEBUG_UNWIND
+#define DEBUG_UNWIND 2
+#else
+#define DEBUG_UNWIND 0
+#endif
+
+#ifdef DEBUG_SYMBOLS
+#undef DEBUG_SYMBOLS
+#define DEBUG_SYMBOLS 4
+#else
+#define DEBUG_SYMBOLS 0
+#endif
+
+#define DEBUG_TYPE (DEBUG_TRANSPORT|DEBUG_UNWIND|DEBUG_SYMBOLS)
+
+#if DEBUG_TYPE > 0
+
+#define dbug(type, args...) do { \
+ if ((type) & DEBUG_TYPE) \
+ _stp_dbug(__FUNCTION__, __LINE__, args); \
+ } while (0)
+
+#define kbug(type, args...) do { \
+ if ((type) & DEBUG_TYPE) { \
+ printk("%s:%d ",__FUNCTION__, __LINE__); \
+ printk(args); \
+ } \
+ } while (0)
+
+#else
+#define dbug(type, args...) ;
+#define kbug(type, args...) ;
+#endif /* DEBUG_TYPE > 0 */
+
+#endif /* _STP_DEBUG_H_ */
diff --git a/runtime/map-gen.c b/runtime/map-gen.c
index a17f7e34..ce6e8742 100644
--- a/runtime/map-gen.c
+++ b/runtime/map-gen.c
@@ -229,7 +229,6 @@ static key_data KEYSYM(map_get_key) (struct map_node *mn, int n, int *type)
key_data ptr;
struct KEYSYM(map_node) *m = (struct KEYSYM(map_node) *)mn;
- dbug ("n = %d type=%lx\n", n, type);
if (n > KEY_ARITY || n < 1) {
if (type)
*type = END;
@@ -359,7 +358,6 @@ MAP KEYSYM(_stp_map_new) (unsigned max_entries, int htype, ...)
start = va_arg(ap, int);
stop = va_arg(ap, int);
interval = va_arg(ap, int);
- // dbug ("start=%d stop=%d interval=%d\n", start, stop, interval);
va_end (ap);
}
@@ -404,7 +402,6 @@ int KEYSYM(__stp_map_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add)
hlist_for_each(e, head) {
n = (struct KEYSYM(map_node) *)((long)e - sizeof(struct list_head));
- //dbug ("n=%lx key1=%ld n->key1=%ld\n", (long)n, key1, n->key1);
if (KEY1_EQ_P(n->key1, key1)
#if KEY_ARITY > 1
&& KEY2_EQ_P(n->key2, key2)
@@ -423,8 +420,6 @@ int KEYSYM(__stp_map_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add)
}
}
/* key not found */
- dbug("key not found\n");
-
n = (struct KEYSYM(map_node)*)_new_map_create (map, head);
if (n == NULL)
return -1;
diff --git a/runtime/map.c b/runtime/map.c
index 70990876..513e27df 100644
--- a/runtime/map.c
+++ b/runtime/map.c
@@ -138,7 +138,6 @@ int64_t _stp_key_get_int64 (struct map_node *mn, int n)
if (mn) {
res = (*mn->map->get_key)(mn, n, &type).val;
- dbug("type=%d\n", type);
if (type != INT64)
res = 0;
}
@@ -159,7 +158,6 @@ char *_stp_key_get_str (struct map_node *mn, int n)
if (mn) {
str = (*mn->map->get_key)(mn, n, &type).strp;
- dbug("type=%d\n", type);
if (type != STRING)
str = "bad type";
}
@@ -716,7 +714,6 @@ void _stp_map_printn (MAP map, int n, const char *fmt)
struct map_node *ptr;
int type, num;
key_data kd;
- dbug ("print map %lx fmt=%s\n", (long)map, fmt);
if (n < 0)
return;
@@ -763,7 +760,6 @@ static struct map_node *_stp_new_agg(MAP agg, struct hlist_head *ahead, struct m
{
struct map_node *aptr;
/* copy keys and aggregate */
- dbug("creating new entry in %lx\n", (long)agg);
aptr = _new_map_create(agg, ahead);
if (aptr == NULL)
return NULL;
@@ -952,12 +948,10 @@ static struct map_node *_new_map_create (MAP map, struct hlist_head *head)
return NULL;
}
m = (struct map_node *)map->head.next;
- dbug ("got %lx off head\n", (long)m);
hlist_del_init(&m->hnode);
} else {
m = (struct map_node *)map->pool.next;
map->num++;
- dbug ("got %lx off pool\n", (long)m);
}
list_move_tail(&m->lnode, &map->head);
diff --git a/runtime/mempool.c b/runtime/mempool.c
new file mode 100644
index 00000000..0fbb4326
--- /dev/null
+++ b/runtime/mempool.c
@@ -0,0 +1,135 @@
+/* -*- linux-c -*-
+ * Preallocated memory pools
+ * Copyright (C) 2008 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 _STP_MEMPOOL_C_
+#define _STP_MEMPOOL_C_
+
+/* An opaque struct identifying the memory pool. */
+typedef struct {
+ struct list_head free_list;
+ unsigned num;
+ unsigned size;
+ spinlock_t lock;
+} _stp_mempool_t;
+
+/* for internal use only */
+struct _stp_mem_buffer {
+ struct list_head list;
+ _stp_mempool_t *pool;
+ void *buf;
+};
+
+/* Delete a memory pool */
+static void _stp_mempool_destroy(_stp_mempool_t *pool)
+{
+ struct list_head *p, *tmp;
+ if (pool) {
+ list_for_each_safe(p, tmp, &pool->free_list) {
+ list_del(p);
+ _stp_kfree(p);
+ }
+ _stp_kfree(pool);
+ }
+}
+
+/* Create a new memory pool */
+static _stp_mempool_t *_stp_mempool_init(size_t size, size_t num)
+{
+ int i, alloc_size;
+ struct _stp_mem_buffer *m;
+
+ _stp_mempool_t *pool = (_stp_mempool_t *)_stp_kmalloc(sizeof(_stp_mempool_t));
+ if (unlikely(pool == NULL)) {
+ errk("Memory allocation failed.\n");
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&pool->free_list);
+ spin_lock_init(&pool->lock);
+
+ alloc_size = size + sizeof(struct _stp_mem_buffer) - sizeof(void *);
+
+ for (i = 0; i < num; i++) {
+ m = (struct _stp_mem_buffer *)_stp_kmalloc(alloc_size);
+ if (unlikely(m == NULL))
+ goto err;
+ m->pool = pool;
+ list_add((struct list_head *)m, &pool->free_list);
+ }
+ pool->num = num;
+ pool->size = alloc_size;
+ return pool;
+
+err:
+ _stp_mempool_destroy(pool);
+ 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)
+{
+ unsigned long flags;
+ struct _stp_mem_buffer *ptr = NULL;
+ spin_lock_irqsave(&pool->lock, flags);
+ if (likely(!list_empty(&pool->free_list))) {
+ ptr = (struct _stp_mem_buffer *)pool->free_list.next;
+ list_del_init(&ptr->list);
+ spin_unlock_irqrestore(&pool->lock, flags);
+ return &ptr->buf;
+ }
+ spin_unlock_irqrestore(&pool->lock, flags);
+ return NULL;
+}
+
+/* return a buffer to its memory pool */
+static void _stp_mempool_free(void *buf)
+{
+ unsigned long flags;
+ struct _stp_mem_buffer *m = container_of(buf, struct _stp_mem_buffer, buf);
+ spin_lock_irqsave(&m->pool->lock, flags);
+ list_add(&m->list, &m->pool->free_list);
+ spin_unlock_irqrestore(&m->pool->lock, flags);
+}
+#endif /* _STP_MEMPOOL_C_ */
diff --git a/runtime/pmap-gen.c b/runtime/pmap-gen.c
index 0efffdb6..8666549b 100644
--- a/runtime/pmap-gen.c
+++ b/runtime/pmap-gen.c
@@ -437,7 +437,6 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries, int htype, ...)
start = va_arg(ap, int);
stop = va_arg(ap, int);
interval = va_arg(ap, int);
- // dbug ("start=%d stop=%d interval=%d\n", start, stop, interval);
va_end (ap);
}
@@ -515,8 +514,6 @@ int KEYSYM(__stp_pmap_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add)
}
/* key not found */
- dbug("key not found\n");
-
n = (struct KEYSYM(pmap_node)*)_new_map_create (map, head);
if (n == NULL)
return -1;
@@ -678,7 +675,6 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
#endif
) {
if (anode == NULL) {
- // dbug("agg=%lx ahead=%lx\n", (long)agg, (long)ahead);
anode = _stp_new_agg(agg, ahead, (struct map_node *)n);
} else {
if (clear_agg) {
@@ -738,7 +734,6 @@ int KEYSYM(__stp_pmap_del) (MAP map, ALLKEYSD(key))
}
/* key not found */
- dbug("key not found\n");
return 0;
}
diff --git a/runtime/runtime.h b/runtime/runtime.h
index d951833d..318d3038 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -1,5 +1,5 @@
/* main header file
- * Copyright (C) 2005-2007 Red Hat Inc.
+ * Copyright (C) 2005-2008 Red Hat Inc.
* Copyright (C) 2005, 2006 Intel Corporation.
*
* This file is part of systemtap, and is free software. You can
@@ -46,21 +46,7 @@
static void _stp_dbug (const char *func, int line, const char *fmt, ...);
void _stp_error (const char *fmt, ...);
-#ifdef DEBUG
-/** Prints debug line.
- * This function prints a debug message immediately to staprun.
- * If the last character is not a newline, then one is added.
- * @param args A variable number of args in a format like printf.
- * @ingroup io
- */
-#define dbug(args...) _stp_dbug(__FUNCTION__, __LINE__, args)
-#define kbug(args...) {printk("%s:%d ",__FUNCTION__, __LINE__); printk(args); }
-#else
-#define dbug(args...) ;
-#define kbug(args...) ;
-#endif /* DEBUG */
-#define _dbug(args...) _stp_dbug(__FUNCTION__, __LINE__, args)
-#define errk(args...) {printk("Systemtap Error at %s:%d ",__FUNCTION__, __LINE__); printk(args); }
+#include "debug.h"
/* atomic globals */
static atomic_t _stp_transport_failures = ATOMIC_INIT (0);
diff --git a/runtime/staprun/symbols.c b/runtime/staprun/symbols.c
index e33ee624..c7362d9e 100644
--- a/runtime/staprun/symbols.c
+++ b/runtime/staprun/symbols.c
@@ -19,9 +19,10 @@ static int send_data(int32_t type, void *data, int len)
return write(control_channel, data, len);
}
+
/* Get the sections for a module. Put them in the supplied buffer */
/* in the following order: */
-/* [struct _stp_msg_module][struct _stp_symbol sections ...][string data]*/
+/* [struct _stp_msg_module][struct _stp_symbol sections ...][string data][unwind data] */
/* Return the total length of all the data. */
#define SECDIR "/sys/module/%s/sections"
@@ -31,8 +32,9 @@ static int get_sections(char *name, char *data_start, int datalen)
char filename[STP_MODULE_NAME_LEN + 256];
char buf[32], strdata_start[32768];
char *strdata=strdata_start, *data=data_start;
- int fd, len, res;
+ int fd, len, res, unwind_data_len=0;
struct _stp_msg_module *mod = (struct _stp_msg_module *)data_start;
+
struct dirent *d;
DIR *secdir;
void *sec;
@@ -63,6 +65,9 @@ static int get_sections(char *name, char *data_start, int datalen)
return -1;
}
+ /* FIXME: optionally fill in unwind data here */
+ mod->unwind_len = unwind_data_len;
+
while ((d = readdir(secdir))) {
char *secname = d->d_name;
@@ -138,6 +143,14 @@ static int get_sections(char *name, char *data_start, int datalen)
while (len--)
*data++ = *strdata++;
+#if 0
+ if (unwind_data_len) {
+ if ((unwind_data_len + data - data_start) > datalen)
+ goto err0;
+ memcpy(data, unwind_data, unwind_data_len);
+ data += unwind_data_len;
+ }
+#endif
return data - data_start;
err1:
@@ -211,7 +224,7 @@ int do_kernel_symbols(void)
int ret, num_syms, i = 0, struct_symbol_size;
int max_syms= MAX_SYMBOLS, data_basesize = MAX_SYMBOLS*32;
- if (kernel_ptr_size == 8)
+ if (kernel_ptr_size == 8)
struct_symbol_size = sizeof(struct _stp_symbol64);
else
struct_symbol_size = sizeof(struct _stp_symbol32);
@@ -285,10 +298,12 @@ int do_kernel_symbols(void)
if (num_syms <= 0)
goto err;
+
/* send header */
struct _stp_msg_symbol_hdr smsh;
smsh.num_syms = num_syms;
smsh.sym_size = (uint32_t)(dataptr - data_base);
+ smsh.unwind_size = (uint32_t)0;
if (send_request(STP_SYMBOLS, &smsh, sizeof(smsh)) <= 0)
goto err;
diff --git a/runtime/sym.c b/runtime/sym.c
index 56c93064..3c2f859a 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* Symbolic Lookup Functions
- * Copyright (C) 2005, 2006, 2007 Red Hat Inc.
+ * Copyright (C) 2005-2008 Red Hat Inc.
* Copyright (C) 2006 Intel Corporation.
*
* This file is part of systemtap, and is free software. You can
@@ -9,8 +9,8 @@
* later version.
*/
-#ifndef _SYM_C_
-#define _SYM_C_
+#ifndef _STP_SYM_C_
+#define _STP_SYM_C_
#include "string.c"
@@ -20,11 +20,12 @@
* @{
*/
-unsigned long _stp_module_relocate (const char *module, const char *section, unsigned long offset) {
+unsigned long _stp_module_relocate(const char *module, const char *section, unsigned long offset)
+{
static struct _stp_module *last = NULL;
static struct _stp_symbol *last_sec;
unsigned long flags;
- int i,j;
+ int i, j;
/* if module is -1, we invalidate last. _stp_del_module calls this when modules are deleted. */
if ((long)module == -1) {
@@ -32,53 +33,52 @@ unsigned long _stp_module_relocate (const char *module, const char *section, uns
return 0;
}
- dbug("%s, %s, %lx\n", module, section, offset);
+ dbug(DEBUG_SYMBOLS, "%s, %s, %lx\n", module, section, offset);
- STP_LOCK_MODULES;
- if (! module
- || !strcmp (section, "") /* absolute, unrelocated address */
- || _stp_num_modules == 0) {
- STP_UNLOCK_MODULES;
- return offset;
+ STP_RLOCK_MODULES;
+ if (!module || !strcmp(section, "") /* absolute, unrelocated address */
+ ||_stp_num_modules == 0) {
+ STP_RUNLOCK_MODULES;
+ return offset;
}
/* Most likely our relocation is in the same section of the same module as the last. */
if (last) {
- if (!strcmp (module, last->name) && !strcmp (section, last_sec->symbol)) {
+ if (!strcmp(module, last->name) && !strcmp(section, last_sec->symbol)) {
offset += last_sec->addr;
- STP_UNLOCK_MODULES;
- dbug("offset = %lx\n", offset);
+ STP_RUNLOCK_MODULES;
+ dbug(DEBUG_SYMBOLS, "offset = %lx\n", offset);
return offset;
}
}
/* not cached. need to scan all modules */
- if (! strcmp (module, "kernel")) {
- STP_UNLOCK_MODULES;
+ if (!strcmp(module, "kernel")) {
+ STP_RUNLOCK_MODULES;
/* See also transport/symbols.c (_stp_do_symbols). */
- if (strcmp (section, "_stext"))
+ if (strcmp(section, "_stext"))
return 0;
else
return offset + _stp_modules[0]->text;
} else {
/* relocatable module */
- for (i = 1; i < _stp_num_modules; i++) { /* skip over [0]=kernel */
+ for (i = 1; i < _stp_num_modules; i++) { /* skip over [0]=kernel */
last = _stp_modules[i];
if (strcmp(module, last->name))
continue;
for (j = 0; j < (int)last->num_sections; j++) {
last_sec = &last->sections[j];
- if (!strcmp (section, last_sec->symbol)) {
+ if (!strcmp(section, last_sec->symbol)) {
offset += last_sec->addr;
- STP_UNLOCK_MODULES;
- dbug("offset = %lx\n", offset);
+ STP_RUNLOCK_MODULES;
+ dbug(DEBUG_SYMBOLS, "offset = %lx\n", offset);
return offset;
}
}
}
}
- STP_UNLOCK_MODULES;
+ STP_RUNLOCK_MODULES;
last = NULL;
return 0;
}
@@ -97,24 +97,15 @@ static unsigned long _stp_kallsyms_lookup_name(const char *name)
return 0;
}
-static const char * _stp_kallsyms_lookup (
- unsigned long addr,
- unsigned long *symbolsize,
- unsigned long *offset,
- char **modname,
- char *namebuf)
+static struct _stp_module *_stp_find_module_by_addr(unsigned long addr)
{
- struct _stp_module *m;
- struct _stp_symbol *s;
- unsigned long flags;
- unsigned end, begin = 0;
+ unsigned begin = 0;
+ unsigned end = _stp_num_modules;
- if (STP_TRYLOCK_MODULES)
+ if (unlikely(addr < _stp_modules_by_addr[0]->text))
return NULL;
- end = _stp_num_modules;
-
- if (_stp_num_modules >= 2 && addr > _stp_modules_by_addr[1]->text) {
+ if (_stp_num_modules > 1 && addr > _stp_modules_by_addr[0]->data) {
/* binary search on index [begin,end) */
do {
unsigned mid = (begin + end) / 2;
@@ -125,18 +116,51 @@ static const char * _stp_kallsyms_lookup (
} while (begin + 1 < end);
/* result index in $begin, guaranteed between [0,_stp_num_modules) */
}
- m = _stp_modules_by_addr[begin];
- begin = 0;
- end = m->num_symbols;
+ /* check if addr is past the last module */
+ if (unlikely(begin == _stp_num_modules - 1
+ && (addr > _stp_modules_by_addr[begin]->text + _stp_modules_by_addr[begin]->text_size)))
+ return NULL;
+
+ return _stp_modules_by_addr[begin];
+}
- /* m->data is the lowest address of a data section. It should be */
- /* after the text section. */
- /* If our address is in the data section, then return now. */
- if (m->data > m->text && addr >= m->data) {
- STP_UNLOCK_MODULES;
+static struct _stp_module *_stp_get_unwind_info(unsigned long addr)
+{
+ struct _stp_module *m;
+ struct _stp_symbol *s;
+ unsigned long flags;
+
+ STP_RLOCK_MODULES;
+ m = _stp_find_module_by_addr(addr);
+ if (unlikely(m == NULL)) {
+ STP_RUNLOCK_MODULES;
return NULL;
}
-
+ /* Lock the module struct so it doesn't go away while being used. */
+ /* Probably could never happen, but lock it to be sure for now. */
+ read_lock(&m->lock);
+
+ STP_RUNLOCK_MODULES;
+ return m;
+}
+
+static const char *_stp_kallsyms_lookup(unsigned long addr,
+ unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf)
+{
+ struct _stp_module *m;
+ struct _stp_symbol *s;
+ unsigned long flags;
+ unsigned end, begin = 0;
+
+ STP_RLOCK_MODULES;
+ m = _stp_find_module_by_addr(addr);
+ if (unlikely(m == NULL)) {
+ STP_RUNLOCK_MODULES;
+ return NULL;
+ }
+
+ end = m->num_symbols;
+
/* binary search for symbols within the module */
do {
unsigned mid = (begin + end) / 2;
@@ -148,31 +172,29 @@ static const char * _stp_kallsyms_lookup (
/* result index in $begin */
s = &m->symbols[begin];
- if (addr < s->addr) {
- STP_UNLOCK_MODULES;
- return NULL;
- } else {
- if (offset) *offset = addr - s->addr;
- if (modname) *modname = m->name;
+ if (likely(addr >= s->addr)) {
+ if (offset)
+ *offset = addr - s->addr;
+ if (modname)
+ *modname = m->name;
if (symbolsize) {
if ((begin + 1) < m->num_symbols)
- *symbolsize = m->symbols[begin+1].addr - s->addr;
+ *symbolsize = m->symbols[begin + 1].addr - s->addr;
else
*symbolsize = 0;
// NB: This is only a heuristic. Sometimes there are large
// gaps between text areas of modules.
}
if (namebuf) {
- strlcpy (namebuf, s->symbol, KSYM_NAME_LEN+1);
- STP_UNLOCK_MODULES;
+ strlcpy(namebuf, s->symbol, KSYM_NAME_LEN + 1);
+ STP_RUNLOCK_MODULES;
return namebuf;
- }
- else {
- STP_UNLOCK_MODULES;
+ } else {
+ STP_RUNLOCK_MODULES;
return s->symbol;
}
}
- STP_UNLOCK_MODULES;
+ STP_RUNLOCK_MODULES;
return NULL;
}
@@ -182,31 +204,31 @@ static const char * _stp_kallsyms_lookup (
* a probe because it is too time-consuming. Use at module exit time.
*/
-void _stp_symbol_print (unsigned long address)
-{
+void _stp_symbol_print(unsigned long address)
+{
char *modname;
- const char *name;
- unsigned long offset, size;
+ const char *name;
+ unsigned long offset, size;
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
- _stp_printf ("%p", (int64_t)address);
+ _stp_printf("%p", (int64_t) address);
- if (name) {
+ if (name) {
if (modname && *modname)
- _stp_printf (" : %s+%#lx/%#lx [%s]", name, offset, size, modname);
+ _stp_printf(" : %s+%#lx/%#lx [%s]", name, offset, size, modname);
else
- _stp_printf (" : %s+%#lx/%#lx", name, offset, size);
+ _stp_printf(" : %s+%#lx/%#lx", name, offset, size);
}
}
/* Like _stp_symbol_print, except only print if the address is a valid function address */
-void _stp_func_print (unsigned long address, int verbose, int exact)
-{
+void _stp_func_print(unsigned long address, int verbose, int exact)
+{
char *modname;
- const char *name;
- unsigned long offset, size;
+ const char *name;
+ unsigned long offset, size;
char *exstr;
if (exact)
@@ -214,33 +236,32 @@ void _stp_func_print (unsigned long address, int verbose, int exact)
else
exstr = " (inexact)";
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
if (name) {
if (verbose) {
if (modname && *modname)
- _stp_printf (" %p : %s+%#lx/%#lx [%s]%s\n",
- (int64_t)address, name, offset, size, modname, exstr);
+ _stp_printf(" %p : %s+%#lx/%#lx [%s]%s\n",
+ (int64_t) address, name, offset, size, modname, exstr);
else
- _stp_printf (" %p : %s+%#lx/%#lx%s\n",
- (int64_t)address, name, offset, size, exstr);
- } else
- _stp_printf ("%p ", (int64_t)address);
+ _stp_printf(" %p : %s+%#lx/%#lx%s\n", (int64_t) address, name, offset, size, exstr);
+ } else
+ _stp_printf("%p ", (int64_t) address);
}
}
-void _stp_symbol_snprint (char *str, size_t len, unsigned long address)
-{
- char *modname;
- const char *name;
- unsigned long offset, size;
-
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
- if (name)
- strlcpy(str, name, len);
- else
- _stp_snprintf(str, len, "%p", (int64_t)address);
+void _stp_symbol_snprint(char *str, size_t len, unsigned long address)
+{
+ char *modname;
+ const char *name;
+ unsigned long offset, size;
+
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ if (name)
+ strlcpy(str, name, len);
+ else
+ _stp_snprintf(str, len, "%p", (int64_t) address);
}
/** @} */
-#endif /* _SYM_C_ */
+#endif /* _STP_SYM_C_ */
diff --git a/runtime/sym.h b/runtime/sym.h
index 6a55a22e..b124882a 100644
--- a/runtime/sym.h
+++ b/runtime/sym.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2005, 2006 Red Hat Inc.
+/* -*- linux-c -*-
+ * Copyright (C) 2005-2008 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
@@ -13,39 +13,59 @@
#define STP_MODULE_NAME_LEN 64
struct _stp_symbol {
- unsigned long addr;
- const char *symbol;
+ unsigned long addr;
+ const char *symbol;
+};
+struct stap_symbol {
+ unsigned long addr;
+ const char *symbol;
+ const char *module;
};
-struct _stp_module {
- /* the module name, or "" for kernel */
- char name[STP_MODULE_NAME_LEN];
-
- /* A pointer to the struct module. Note that we cannot */
- /* trust this because as of 2.6.19, there are not yet */
- /* any notifier hooks that will tell us when a module */
- /* is unloading. */
- unsigned long module;
-
- /* the start of the module's text and data sections */
- unsigned long text;
- unsigned long data;
-
- /* how many symbols this module has that we are interested in */
- uint32_t num_symbols;
-
- /* how many sections this module has */
- uint32_t num_sections;
- struct _stp_symbol *sections;
-
- /* how the symbol_data below was allocated */
- int32_t allocated; /* 0 = kmalloc, 1 = vmalloc */
-
- /* an array of num_symbols _stp_symbol structs */
- struct _stp_symbol *symbols; /* ordered by address */
+DEFINE_RWLOCK(_stp_module_lock);
+#define STP_RLOCK_MODULES read_lock_irqsave(&_stp_module_lock, flags)
+#define STP_WLOCK_MODULES write_lock_irqsave(&_stp_module_lock, flags)
+#define STP_RUNLOCK_MODULES read_unlock_irqrestore(&_stp_module_lock, flags)
+#define STP_WUNLOCK_MODULES write_unlock_irqrestore(&_stp_module_lock, flags)
- /* where we stash our copy of the strtab */
- void *symbol_data; /* private */
+struct _stp_module {
+ /* the module name, or "" for kernel */
+ char name[STP_MODULE_NAME_LEN];
+
+ /* A pointer to the struct module. Note that we cannot */
+ /* trust this because as of 2.6.19, there are not yet */
+ /* any notifier hooks that will tell us when a module */
+ /* is unloading. */
+ unsigned long module;
+
+ /* the start of the module's text and data sections */
+ unsigned long text;
+ unsigned long data;
+
+ uint32_t text_size;
+
+ /* how many symbols this module has that we are interested in */
+ uint32_t num_symbols;
+
+ /* how many sections this module has */
+ uint32_t num_sections;
+
+ /* how the symbol_data below was allocated */
+ int32_t allocated; /* 0 = kmalloc, 1 = vmalloc */
+
+ struct _stp_symbol *sections;
+
+ /* an array of num_symbols _stp_symbol structs */
+ struct _stp_symbol *symbols; /* ordered by address */
+
+ /* where we stash our copy of the strtab */
+ void *symbol_data;
+
+ /* the stack unwind data for this module */
+ void *unwind_data;
+ uint32_t unwind_data_len;
+ rwlock_t lock; /* lock while unwinding is happening */
+
};
#ifndef STP_MAX_MODULES
@@ -62,4 +82,5 @@ struct _stp_module *_stp_modules_by_addr[STP_MAX_MODULES];
int _stp_num_modules = 0;
unsigned long _stp_module_relocate (const char *module, const char *section, unsigned long offset);
+static struct _stp_module *_stp_get_unwind_info (unsigned long addr);
#endif /* _STAP_SYMBOLS_H_ */
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 764e3579..c3837f86 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,16 @@
+2008-02-27 Martin Hunt <hunt@redhat.com>
+
+ * symbols.c: Use rwlocks. Use new dbug macros. Handle
+ unwind info if present.
+
+ * transport.c: Include mempool.c. Update dbug and kbug calls
+ to new macros.
+ * transport_msgs.h (_stp_command_name): Add
+ struct containing message names for debugging.
+
+ * control.c, procfs.c: Use new dbug macros. Use
+ new mempool functions.
+
2008-01-28 Martin Hunt <hunt@redhat.com>
* control.c, procfs.c, symbols.c: Use DEFINE_SPINLOCK
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index 0bf99fc8..6a5b272d 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -12,15 +12,13 @@
#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 struct list_head _stp_sym_ready_q;
-static struct list_head _stp_pool_q;
-DEFINE_SPINLOCK(_stp_pool_lock);
DEFINE_SPINLOCK(_stp_ctl_ready_lock);
DEFINE_SPINLOCK(_stp_sym_ready_lock);
-static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t _stp_sym_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
static int saved_type = 0;
int type;
@@ -28,7 +26,7 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
if (count < sizeof(int32_t))
return 0;
- /* Allow sending of packet type followed by data in the next packet.*/
+ /* Allow sending of packet type followed by data in the next packet. */
if (count == sizeof(int32_t)) {
if (get_user(saved_type, (int __user *)buf))
return -EFAULT;
@@ -42,11 +40,14 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
count -= sizeof(int);
buf += sizeof(int);
}
-
- kbug ("count:%d type:%d\n", (int)count, type);
+
+#if DEBUG_TRANSPORT > 0
+ if (type < STP_MAX_CMD)
+ _dbug("Got %s. len=%d\n", _stp_command_name[type], (int)count);
+#endif
switch (type) {
- case STP_SYMBOLS:
+ case STP_SYMBOLS:
count = _stp_do_symbols(buf, count);
break;
case STP_MODULE:
@@ -54,21 +55,20 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
count = _stp_do_module(buf, count);
else {
/* count == 1 indicates end of initial modules list */
- _stp_ctl_send(STP_TRANSPORT, NULL, 0);
+ _stp_ctl_send(STP_TRANSPORT, NULL, 0);
}
break;
case STP_EXIT:
_stp_exit_flag = 1;
break;
default:
- errk ("invalid symbol command type %d\n", type);
+ errk("invalid symbol command type %d\n", type);
return -EINVAL;
}
return count;
}
-static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+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;
@@ -79,7 +79,10 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
if (get_user(type, (int __user *)buf))
return -EFAULT;
- kbug ("count:%d type:%d\n", (int)count, type);
+#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);
@@ -90,9 +93,9 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
struct _stp_msg_start st;
if (count < sizeof(st))
return 0;
- if (copy_from_user (&st, buf, sizeof(st)))
+ if (copy_from_user(&st, buf, sizeof(st)))
return -EFAULT;
- _stp_handle_start (&st);
+ _stp_handle_start(&st);
started = 1;
}
break;
@@ -107,11 +110,11 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
#endif
case STP_READY:
/* request symbolic information */
- _stp_ask_for_symbols();
+ _stp_ask_for_symbols();
break;
-
+
default:
- errk ("invalid command type %d\n", type);
+ errk("invalid command type %d\n", type);
return -EINVAL;
}
@@ -130,55 +133,55 @@ struct _stp_buffer {
static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq);
static DECLARE_WAIT_QUEUE_HEAD(_stp_sym_wq);
-#ifdef DEBUG
-static void _stp_ctl_write_dbug (int type, void *data, int len)
+#if DEBUG_TRANSPORT > 0
+static void _stp_ctl_write_dbug(int type, void *data, int len)
{
char buf[64];
switch (type) {
case STP_START:
- printk("_stp_ctl_write: sending STP_START\n");
+ _dbug("sending STP_START\n");
break;
case STP_EXIT:
- printk("_stp_ctl_write: sending STP_EXIT\n");
+ _dbug("sending STP_EXIT\n");
break;
case STP_OOB_DATA:
- snprintf(buf, sizeof(buf), "%s", (char *)data);
- printk("_stp_ctl_write: sending %d bytes of STP_OOB_DATA: %s\n", len, buf);
+ 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);
- printk("_stp_ctl_write: sending STP_SYSTEM: %s\n", buf);
+ snprintf(buf, sizeof(buf), "%s", (char *)data);
+ _dbug("sending STP_SYSTEM: %s\n", buf);
break;
case STP_TRANSPORT:
- printk("_stp_ctl_write: sending STP_TRANSPORT\n");
+ _dbug("sending STP_TRANSPORT\n");
break;
default:
- printk("_stp_ctl_write: ERROR: unknown message type: %d\n", type);
+ _dbug("ERROR: unknown message type: %d\n", type);
break;
}
}
-static void _stp_sym_write_dbug (int type, void *data, int len)
+static void _stp_sym_write_dbug(int type, void *data, int len)
{
switch (type) {
case STP_SYMBOLS:
- printk("_stp_sym_write: sending STP_SYMBOLS\n");
+ _dbug("sending STP_SYMBOLS\n");
break;
case STP_MODULE:
- printk("_stp_sym_write: sending STP_MODULE\n");
+ _dbug("sending STP_MODULE\n");
break;
default:
- printk("_stp_sym_write: ERROR: unknown message type: %d\n", type);
+ _dbug("ERROR: unknown message type: %d\n", type);
break;
}
}
#endif
-static int _stp_ctl_write (int type, void *data, unsigned len)
+static int _stp_ctl_write(int type, void *data, unsigned len)
{
struct _stp_buffer *bptr;
unsigned long flags;
- unsigned numtrylock;
-#ifdef DEBUG
+
+#if DEBUG_TRANSPORT > 0
_stp_ctl_write_dbug(type, data, len);
#endif
@@ -186,47 +189,29 @@ static int _stp_ctl_write (int type, void *data, unsigned len)
if (unlikely(len > STP_CTL_BUFFER_SIZE))
return 0;
- numtrylock = 0;
- while (!spin_trylock_irqsave (&_stp_pool_lock, flags) && (++numtrylock < MAXTRYLOCK))
- ndelay (TRYLOCKDELAY);
- if (unlikely (numtrylock >= MAXTRYLOCK))
- return 0;
-
- if (unlikely(list_empty(&_stp_pool_q))) {
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- dbug("_stp_pool_q empty\n");
+ /* get a buffer from the free pool */
+ bptr = _stp_mempool_alloc(_stp_pool_q);
+ if (unlikely(bptr == NULL))
return -1;
- }
-
- /* get the next buffer from the pool */
- bptr = (struct _stp_buffer *)_stp_pool_q.next;
- list_del_init(&bptr->list);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
bptr->type = type;
memcpy(bptr->buf, data, len);
bptr->len = len;
-
- /* put it on the pool of ready buffers */
- numtrylock = 0;
- while (!spin_trylock_irqsave (&_stp_ctl_ready_lock, flags) && (++numtrylock < MAXTRYLOCK))
- ndelay (TRYLOCKDELAY);
-
- if (unlikely (numtrylock >= MAXTRYLOCK))
- return 0;
+ /* 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;
}
-static int _stp_sym_write (int type, void *data, unsigned len)
+static int _stp_sym_write(int type, void *data, unsigned len)
{
struct _stp_buffer *bptr;
unsigned long flags;
-#ifdef DEBUG
+#if DEBUG_TRANSPORT > 0
_stp_sym_write_dbug(type, data, len);
#endif
@@ -234,24 +219,17 @@ static int _stp_sym_write (int type, void *data, unsigned len)
if (unlikely(len > STP_CTL_BUFFER_SIZE))
return 0;
- spin_lock_irqsave (&_stp_pool_lock, flags);
- if (unlikely(list_empty(&_stp_pool_q))) {
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- dbug("_stp_pool_q empty\n");
+ /* get a buffer from the free pool */
+ bptr = _stp_mempool_alloc(_stp_pool_q);
+ if (unlikely(bptr == NULL))
return -1;
- }
-
- /* get the next buffer from the pool */
- bptr = (struct _stp_buffer *)_stp_pool_q.next;
- list_del_init(&bptr->list);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
bptr->type = type;
memcpy(bptr->buf, data, len);
bptr->len = len;
-
+
/* put it on the pool of ready buffers */
- spin_lock_irqsave (&_stp_sym_ready_lock, flags);
+ spin_lock_irqsave(&_stp_sym_ready_lock, flags);
list_add_tail(&bptr->list, &_stp_sym_ready_q);
spin_unlock_irqrestore(&_stp_sym_ready_lock, flags);
@@ -262,25 +240,24 @@ static int _stp_sym_write (int type, void *data, unsigned len)
}
/* send commands with timeout and retry */
-static int _stp_ctl_send (int type, void *data, int len)
+static int _stp_ctl_send(int type, void *data, int len)
{
int err, trylimit = 50;
- kbug("ctl_send: type=%d len=%d\n", type, len);
+ kbug(DEBUG_TRANSPORT, "ctl_send: type=%d len=%d\n", type, len);
if (unlikely(type == STP_SYMBOLS || type == STP_MODULE)) {
while ((err = _stp_sym_write(type, data, len)) < 0 && trylimit--)
- msleep (5);
+ msleep(5);
} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
- msleep (5);
+ msleep(5);
if (err > 0)
wake_up_interruptible(&_stp_ctl_wq);
}
- kbug("returning %d\n", err);
+ kbug(DEBUG_TRANSPORT, "returning %d\n", err);
return err;
}
-static ssize_t
-_stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t _stp_sym_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct _stp_buffer *bptr;
int len;
@@ -296,7 +273,7 @@ _stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
return -ERESTARTSYS;
spin_lock_irqsave(&_stp_sym_ready_lock, flags);
}
-
+
/* get the next buffer off the ready list */
bptr = (struct _stp_buffer *)_stp_sym_ready_q.next;
list_del_init(&bptr->list);
@@ -314,15 +291,12 @@ _stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
}
/* put it on the pool of free buffers */
- spin_lock_irqsave(&_stp_pool_lock, flags);
- list_add_tail(&bptr->list, &_stp_pool_q);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
+ _stp_mempool_free(bptr);
return len;
}
-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;
@@ -338,7 +312,7 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
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);
@@ -356,15 +330,13 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
}
/* put it on the pool of free buffers */
- spin_lock_irqsave(&_stp_pool_lock, flags);
- list_add_tail(&bptr->list, &_stp_pool_q);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
+ _stp_mempool_free(bptr);
return len;
}
static int _stp_sym_opens = 0;
-static int _stp_sym_open_cmd (struct inode *inode, struct file *file)
+static int _stp_sym_open_cmd(struct inode *inode, struct file *file)
{
/* only allow one reader */
if (_stp_sym_opens)
@@ -374,14 +346,14 @@ static int _stp_sym_open_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_sym_close_cmd (struct inode *inode, struct file *file)
+static int _stp_sym_close_cmd(struct inode *inode, struct file *file)
{
if (_stp_sym_opens)
_stp_sym_opens--;
return 0;
}
-static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
+static int _stp_ctl_open_cmd(struct inode *inode, struct file *file)
{
if (_stp_attached)
return -1;
@@ -390,7 +362,7 @@ static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
+static int _stp_ctl_close_cmd(struct inode *inode, struct file *file)
{
if (_stp_attached)
_stp_detach();
@@ -416,12 +388,12 @@ static struct file_operations _stp_sym_fops_cmd = {
static struct dentry *_stp_cmd_file = NULL;
static struct dentry *_stp_sym_file = NULL;
-static int _stp_register_ctl_channel (void)
+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;
@@ -429,21 +401,16 @@ static int _stp_register_ctl_channel (void)
INIT_LIST_HEAD(&_stp_ctl_ready_q);
INIT_LIST_HEAD(&_stp_sym_ready_q);
- INIT_LIST_HEAD(&_stp_pool_q);
/* allocate buffers */
- for (i = 0; i < STP_DEFAULT_BUFFERS; i++) {
- p = (struct list_head *)_stp_kmalloc(sizeof(struct _stp_buffer));
- // printk("allocated buffer at %lx\n", (long)p);
- if (!p)
- goto err0;
- _stp_allocated_net_memory += sizeof(struct _stp_buffer);
- list_add (p, &_stp_pool_q);
- }
+ _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_cmd_file == NULL)
goto err0;
_stp_cmd_file->d_inode->i_uid = _stp_uid;
_stp_cmd_file->d_inode->i_gid = _stp_gid;
@@ -455,35 +422,29 @@ static int _stp_register_ctl_channel (void)
return 0;
err0:
- if (_stp_cmd_file) debugfs_remove(_stp_cmd_file);
-
- list_for_each_safe(p, tmp, &_stp_pool_q) {
- list_del(p);
- _stp_kfree(p);
- }
- errk ("Error creating systemtap debugfs entries.\n");
+ if (_stp_cmd_file)
+ debugfs_remove(_stp_cmd_file);
+ _stp_mempool_destroy(_stp_pool_q);
+ errk("Error creating systemtap debugfs entries.\n");
return -1;
}
-
-static void _stp_unregister_ctl_channel (void)
+static void _stp_unregister_ctl_channel(void)
{
struct list_head *p, *tmp;
- if (_stp_sym_file) debugfs_remove(_stp_sym_file);
- if (_stp_cmd_file) debugfs_remove(_stp_cmd_file);
+ if (_stp_sym_file)
+ debugfs_remove(_stp_sym_file);
+ if (_stp_cmd_file)
+ debugfs_remove(_stp_cmd_file);
- /* free memory pools */
- list_for_each_safe(p, tmp, &_stp_pool_q) {
- list_del(p);
- _stp_kfree(p);
- }
+ /* Return memory to pool and free it. */
list_for_each_safe(p, tmp, &_stp_sym_ready_q) {
list_del(p);
- _stp_kfree(p);
+ _stp_mempool_free(p);
}
list_for_each_safe(p, tmp, &_stp_ctl_ready_q) {
list_del(p);
- _stp_kfree(p);
+ _stp_mempool_free(p);
}
+ _stp_mempool_destroy(_stp_pool_q);
}
-
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index 33f6db33..2afea1c9 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -12,18 +12,16 @@
#define STP_DEFAULT_BUFFERS 256
static int _stp_current_buffers = STP_DEFAULT_BUFFERS;
+static _stp_mempool_t *_stp_pool_q;
static struct list_head _stp_ctl_ready_q;
static struct list_head _stp_sym_ready_q;
-static struct list_head _stp_pool_q;
-DEFINE_SPINLOCK(_stp_pool_lock);
DEFINE_SPINLOCK(_stp_ctl_ready_lock);
DEFINE_SPINLOCK(_stp_sym_ready_lock);
#ifdef STP_BULKMODE
extern int _stp_relay_flushing;
/* handle the per-cpu subbuf info read for relayfs */
-static ssize_t
-_stp_proc_read (struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t _stp_proc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
int num;
struct _stp_buf_info out;
@@ -46,8 +44,7 @@ _stp_proc_read (struct file *file, char __user *buf, size_t count, loff_t *ppos)
}
/* handle the per-cpu subbuf info write for relayfs */
-static ssize_t _stp_proc_write (struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t _stp_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
struct _stp_consumed_info info;
int cpu = *(int *)(PDE(file->f_dentry->d_inode)->data);
@@ -65,8 +62,7 @@ static struct file_operations _stp_proc_fops = {
};
#endif /* STP_BULKMODE */
-static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t _stp_sym_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
static int saved_type = 0;
int type;
@@ -74,7 +70,7 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
if (count < sizeof(int32_t))
return 0;
- /* Allow sending of packet type followed by data in the next packet.*/
+ /* Allow sending of packet type followed by data in the next packet. */
if (count == sizeof(int32_t)) {
if (get_user(saved_type, (int __user *)buf))
return -EFAULT;
@@ -88,11 +84,14 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
count -= sizeof(int);
buf += sizeof(int);
}
-
- // kbug ("count:%d type:%d\n", (int)count, type);
+
+#if DEBUG_TRANSPORT > 0
+ if (type < STP_MAX_CMD)
+ _dbug("Got %s. len=%d\n", _stp_command_name[type], (int)count);
+#endif
switch (type) {
- case STP_SYMBOLS:
+ case STP_SYMBOLS:
count = _stp_do_symbols(buf, count);
break;
case STP_MODULE:
@@ -100,19 +99,19 @@ static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf,
count = _stp_do_module(buf, count);
else {
/* count == 1 indicates end of initial modules list */
- _stp_ctl_send(STP_TRANSPORT, NULL, 0);
+ _stp_ctl_send(STP_TRANSPORT, NULL, 0);
}
break;
default:
- errk ("invalid symbol command type %d\n", type);
+ errk("invalid symbol command type %d\n", type);
return -EINVAL;
}
return count;
}
-static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+
+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;
@@ -123,7 +122,10 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
if (get_user(type, (int __user *)buf))
return -EFAULT;
- // kbug ("count:%d type:%d\n", count, type);
+#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);
@@ -134,9 +136,9 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
struct _stp_msg_start st;
if (count < sizeof(st))
return 0;
- if (copy_from_user (&st, buf, sizeof(st)))
+ if (copy_from_user(&st, buf, sizeof(st)))
return -EFAULT;
- _stp_handle_start (&st);
+ _stp_handle_start(&st);
started = 1;
}
break;
@@ -145,10 +147,10 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf,
break;
case STP_READY:
/* request symbolic information */
- _stp_ask_for_symbols();
+ _stp_ask_for_symbols();
break;
default:
- errk ("invalid command type %d\n", type);
+ errk("invalid command type %d\n", type);
return -EINVAL;
}
@@ -165,76 +167,66 @@ struct _stp_buffer {
static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq);
static DECLARE_WAIT_QUEUE_HEAD(_stp_sym_wq);
-#ifdef DEBUG
-static void _stp_ctl_write_dbug (int type, void *data, int len)
+#if DEBUG_TRANSPORT > 0
+static void _stp_ctl_write_dbug(int type, void *data, int len)
{
char buf[64];
switch (type) {
- case STP_REALTIME_DATA:
- break;
case STP_START:
- printk("_stp_ctl_write: sending STP_START\n");
+ _dbug("sending STP_START\n");
break;
case STP_EXIT:
- printk("_stp_ctl_write: sending STP_EXIT\n");
+ _dbug("sending STP_EXIT\n");
break;
case STP_OOB_DATA:
- snprintf(buf, sizeof(buf), "%s", (char *)data);
- printk("_stp_ctl_write: sending %d bytes of STP_OOB_DATA: %s\n", len, buf);
+ 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);
- printk("_stp_ctl_write: sending STP_SYSTEM: %s\n", buf);
+ snprintf(buf, sizeof(buf), "%s", (char *)data);
+ _dbug("sending STP_SYSTEM: %s\n", buf);
break;
case STP_TRANSPORT:
- printk("_stp_ctl_write: sending STP_TRANSPORT\n");
+ _dbug("sending STP_TRANSPORT\n");
break;
default:
- printk("_stp_ctl_write: ERROR: unknown message type: %d\n", type);
+ _dbug("ERROR: unknown message type: %d\n", type);
break;
}
}
-static void _stp_sym_write_dbug (int type, void *data, int len)
+static void _stp_sym_write_dbug(int type, void *data, int len)
{
switch (type) {
case STP_SYMBOLS:
- printk("_stp_sym_write: sending STP_SYMBOLS\n");
+ _dbug("sending STP_SYMBOLS\n");
break;
case STP_MODULE:
- printk("_stp_sym_write: sending STP_MODULE\n");
+ _dbug("sending STP_MODULE\n");
break;
default:
- printk("_stp_sym_write: ERROR: unknown message type: %d\n", type);
+ _dbug("ERROR: unknown message type: %d\n", type);
break;
}
}
#endif
-static int _stp_ctl_write (int type, void *data, int len)
+static int _stp_ctl_write(int type, void *data, int len)
{
struct _stp_buffer *bptr;
unsigned long flags;
- unsigned numtrylock;
-#ifdef DEBUG
+#if DEBUG_TRANSPORT > 0
_stp_ctl_write_dbug(type, data, len);
#endif
#define WRITE_AGG
#ifdef WRITE_AGG
- numtrylock = 0;
- while (!spin_trylock_irqsave (&_stp_ctl_ready_lock, flags) && (++numtrylock < MAXTRYLOCK))
- ndelay (TRYLOCKDELAY);
- if (unlikely (numtrylock >= MAXTRYLOCK))
- return 0;
-
+ 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) {
- memcpy (bptr->buf + bptr->len, data, len);
+ if (bptr->len + len <= STP_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);
return len;
@@ -247,47 +239,29 @@ static int _stp_ctl_write (int type, void *data, int len)
if (unlikely(len > STP_BUFFER_SIZE))
return 0;
- numtrylock = 0;
- while (!spin_trylock_irqsave (&_stp_pool_lock, flags) && (++numtrylock < MAXTRYLOCK))
- ndelay (TRYLOCKDELAY);
- if (unlikely (numtrylock >= MAXTRYLOCK))
- return 0;
-
- if (unlikely(list_empty(&_stp_pool_q))) {
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- dbug("_stp_pool_q empty\n");
+ /* get a buffer from the free pool */
+ bptr = _stp_mempool_alloc(_stp_pool_q);
+ if (unlikely(bptr == NULL))
return -1;
- }
-
- /* get the next buffer from the pool */
- bptr = (struct _stp_buffer *)_stp_pool_q.next;
- list_del_init(&bptr->list);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
bptr->type = type;
- memcpy (bptr->buf, data, len);
+ memcpy(bptr->buf, data, len);
bptr->len = len;
-
- /* put it on the pool of ready buffers */
- numtrylock = 0;
- while (!spin_trylock_irqsave (&_stp_ctl_ready_lock, flags) && (++numtrylock < MAXTRYLOCK))
- ndelay (TRYLOCKDELAY);
-
- if (unlikely (numtrylock >= MAXTRYLOCK))
- return 0;
+ /* 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;
}
-static int _stp_sym_write (int type, void *data, unsigned len)
+static int _stp_sym_write(int type, void *data, unsigned len)
{
struct _stp_buffer *bptr;
unsigned long flags;
-#ifdef DEBUG
+#if DEBUG_TRANSPORT > 0
_stp_sym_write_dbug(type, data, len);
#endif
@@ -295,24 +269,17 @@ static int _stp_sym_write (int type, void *data, unsigned len)
if (unlikely(len > STP_BUFFER_SIZE))
return 0;
- spin_lock_irqsave (&_stp_pool_lock, flags);
- if (unlikely(list_empty(&_stp_pool_q))) {
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- dbug("_stp_pool_q empty\n");
+ /* get a buffer from the free pool */
+ bptr = _stp_mempool_alloc(_stp_pool_q);
+ if (unlikely(bptr == NULL))
return -1;
- }
-
- /* get the next buffer from the pool */
- bptr = (struct _stp_buffer *)_stp_pool_q.next;
- list_del_init(&bptr->list);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
bptr->type = type;
memcpy(bptr->buf, data, len);
bptr->len = len;
/* put it on the pool of ready buffers */
- spin_lock_irqsave (&_stp_sym_ready_lock, flags);
+ spin_lock_irqsave(&_stp_sym_ready_lock, flags);
list_add_tail(&bptr->list, &_stp_sym_ready_q);
spin_unlock_irqrestore(&_stp_sym_ready_lock, flags);
@@ -323,23 +290,24 @@ static int _stp_sym_write (int type, void *data, unsigned len)
}
/* send commands with timeout and retry */
-static int _stp_ctl_send (int type, void *data, int len)
+static int _stp_ctl_send(int type, void *data, int len)
{
int err, trylimit = 50;
+ kbug(DEBUG_TRANSPORT, "ctl_send: type=%d len=%d\n", type, len);
if (unlikely(type == STP_SYMBOLS || type == STP_MODULE)) {
while ((err = _stp_sym_write(type, data, len)) < 0 && trylimit--)
- msleep (5);
+ msleep(5);
} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
- msleep (5);
+ msleep(5);
if (err > 0)
wake_up_interruptible(&_stp_ctl_wq);
}
+ kbug(DEBUG_TRANSPORT, "returning %d\n", err);
return err;
}
-static ssize_t
-_stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t _stp_sym_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct _stp_buffer *bptr;
int len;
@@ -355,7 +323,7 @@ _stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
return -ERESTARTSYS;
spin_lock_irqsave(&_stp_sym_ready_lock, flags);
}
-
+
/* get the next buffer off the ready list */
bptr = (struct _stp_buffer *)_stp_sym_ready_q.next;
list_del_init(&bptr->list);
@@ -373,15 +341,12 @@ _stp_sym_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
}
/* put it on the pool of free buffers */
- spin_lock_irqsave(&_stp_pool_lock, flags);
- list_add_tail(&bptr->list, &_stp_pool_q);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
+ _stp_mempool_free(bptr);
return len;
}
-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;
@@ -397,7 +362,7 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
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);
@@ -415,15 +380,13 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp
}
/* put it on the pool of free buffers */
- spin_lock_irqsave(&_stp_pool_lock, flags);
- list_add_tail(&bptr->list, &_stp_pool_q);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
+ _stp_mempool_free(bptr);
return len;
}
static int _stp_sym_opens = 0;
-static int _stp_sym_open_cmd (struct inode *inode, struct file *file)
+static int _stp_sym_open_cmd(struct inode *inode, struct file *file)
{
/* only allow one reader */
if (_stp_sym_opens)
@@ -433,14 +396,14 @@ static int _stp_sym_open_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_sym_close_cmd (struct inode *inode, struct file *file)
+static int _stp_sym_close_cmd(struct inode *inode, struct file *file)
{
if (_stp_sym_opens)
_stp_sym_opens--;
return 0;
}
-static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
+static int _stp_ctl_open_cmd(struct inode *inode, struct file *file)
{
if (_stp_attached)
return -1;
@@ -449,7 +412,7 @@ static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
+static int _stp_ctl_close_cmd(struct inode *inode, struct file *file)
{
if (_stp_attached)
_stp_detach();
@@ -482,46 +445,14 @@ static int my_proc_match(int len, const char *name, struct proc_dir_entry *de)
/* set the number of buffers to use to 'num' */
static int _stp_set_buffers(int num)
{
- int i;
- struct list_head *p;
- unsigned long flags;
-
- //printk("stp_set_buffers %d\n", num);
-
- if (num == 0 || num == _stp_current_buffers)
- return _stp_current_buffers;
-
- if (num > _stp_current_buffers) {
- for (i = 0; i < num - _stp_current_buffers; i++) {
- p = (struct list_head *)_stp_kmalloc(sizeof(struct _stp_buffer));
- if (!p) {
- _stp_current_buffers += i;
- goto err;
- }
- _stp_allocated_net_memory += sizeof(struct _stp_buffer);
- spin_lock_irqsave(&_stp_pool_lock, flags);
- list_add (p, &_stp_pool_q);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- }
- } else {
- for (i = 0; i < _stp_current_buffers - num; i++) {
- spin_lock_irqsave(&_stp_pool_lock, flags);
- p = _stp_pool_q.next;
- list_del(p);
- spin_unlock_irqrestore(&_stp_pool_lock, flags);
- _stp_kfree(p);
- }
- }
- _stp_current_buffers = num;
-err:
- return _stp_current_buffers;
+ kbug(DEBUG_TRANSPORT, "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)
+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);
- if (len <= off+count)
+ if (len <= off + count)
*eof = 1;
*start = page + off;
len -= off;
@@ -532,7 +463,7 @@ static int _stp_ctl_read_bufsize (char *page, char **start, off_t off,
return len;
}
-static int _stp_register_ctl_channel (void)
+static int _stp_register_ctl_channel(void)
{
int i;
const char *dirname = "systemtap";
@@ -546,17 +477,12 @@ static int _stp_register_ctl_channel (void)
INIT_LIST_HEAD(&_stp_ctl_ready_q);
INIT_LIST_HEAD(&_stp_sym_ready_q);
- INIT_LIST_HEAD(&_stp_pool_q);
/* allocate buffers */
- for (i = 0; i < STP_DEFAULT_BUFFERS; i++) {
- p = (struct list_head *)_stp_kmalloc(sizeof(struct _stp_buffer));
- // printk("allocated buffer at %lx\n", (long)p);
- if (!p)
- goto err0;
- _stp_allocated_net_memory += sizeof(struct _stp_buffer);
- list_add (p, &_stp_pool_q);
- }
+ _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;
if (!_stp_mkdir_proc_module())
goto err0;
@@ -565,15 +491,15 @@ static int _stp_register_ctl_channel (void)
/* now for each cpu "n", create /proc/systemtap/module_name/n */
for_each_cpu(i) {
sprintf(buf, "%d", i);
- de = create_proc_entry (buf, 0600, _stp_proc_root);
- if (de == NULL)
+ de = create_proc_entry(buf, 0600, _stp_proc_root);
+ if (de == NULL)
goto err1;
de->uid = _stp_uid;
de->gid = _stp_gid;
de->proc_fops = &_stp_proc_fops;
de->data = _stp_kmalloc(sizeof(int));
if (de->data == NULL) {
- remove_proc_entry (buf, _stp_proc_root);
+ remove_proc_entry(buf, _stp_proc_root);
goto err1;
}
*(int *)de->data = i;
@@ -582,48 +508,44 @@ static int _stp_register_ctl_channel (void)
#endif /* STP_BULKMODE */
/* create /proc/systemtap/module_name/.cmd */
- de = create_proc_entry (".cmd", 0600, _stp_proc_root);
- if (de == NULL)
+ de = create_proc_entry(".cmd", 0600, _stp_proc_root);
+ if (de == NULL)
goto err1;
de->uid = _stp_uid;
de->gid = _stp_gid;
de->proc_fops = &_stp_proc_fops_cmd;
/* create /proc/systemtap/module_name/.symbols */
- de = create_proc_entry (".symbols", 0600, _stp_proc_root);
- if (de == NULL)
+ de = create_proc_entry(".symbols", 0600, _stp_proc_root);
+ if (de == NULL)
goto err2;
de->proc_fops = &_stp_sym_fops_cmd;
return 0;
err2:
- remove_proc_entry (".cmd", _stp_proc_root);
+ remove_proc_entry(".cmd", _stp_proc_root);
err1:
#ifdef STP_BULKMODE
for (de = _stp_proc_root->subdir; de; de = de->next)
- _stp_kfree (de->data);
+ _stp_kfree(de->data);
for_each_cpu(j) {
if (j == i)
break;
sprintf(buf, "%d", j);
- remove_proc_entry (buf, _stp_proc_root);
-
+ remove_proc_entry(buf, _stp_proc_root);
+
}
- if (bs) remove_proc_entry ("bufsize", _stp_proc_root);
+ if (bs)
+ remove_proc_entry("bufsize", _stp_proc_root);
#endif /* STP_BULKMODE */
_stp_rmdir_proc_module();
err0:
- list_for_each_safe(p, tmp, &_stp_pool_q) {
- list_del(p);
- _stp_kfree(p);
- }
-
- errk ("Error creating systemtap /proc entries.\n");
+ _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(void)
{
struct list_head *p, *tmp;
char buf[32];
@@ -632,31 +554,27 @@ static void _stp_unregister_ctl_channel (void)
struct proc_dir_entry *de;
kbug("unregistering procfs\n");
for (de = _stp_proc_root->subdir; de; de = de->next)
- _stp_kfree (de->data);
+ _stp_kfree(de->data);
for_each_cpu(i) {
sprintf(buf, "%d", i);
- remove_proc_entry (buf, _stp_proc_root);
+ remove_proc_entry(buf, _stp_proc_root);
}
- remove_proc_entry ("bufsize", _stp_proc_root);
+ remove_proc_entry("bufsize", _stp_proc_root);
#endif /* STP_BULKMODE */
- remove_proc_entry (".symbols", _stp_proc_root);
- remove_proc_entry (".cmd", _stp_proc_root);
+ remove_proc_entry(".symbols", _stp_proc_root);
+ remove_proc_entry(".cmd", _stp_proc_root);
_stp_rmdir_proc_module();
- /* free memory pools */
- list_for_each_safe(p, tmp, &_stp_pool_q) {
- list_del(p);
- _stp_kfree(p);
- }
+ /* Return memory to pool and free it. */
list_for_each_safe(p, tmp, &_stp_sym_ready_q) {
list_del(p);
- _stp_kfree(p);
+ _stp_mempool_free(p);
}
list_for_each_safe(p, tmp, &_stp_ctl_ready_q) {
list_del(p);
- _stp_kfree(p);
+ _stp_mempool_free(p);
}
+ _stp_mempool_destroy(_stp_pool_q);
}
-
diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index e740dde8..8c453a55 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -16,16 +16,6 @@
#define _SYMBOLS_C_
#include "../sym.h"
-DEFINE_SPINLOCK(_stp_module_lock);
-#define STP_TRYLOCK_MODULES ({ \
- int numtrylock = 0; \
- while (!spin_trylock_irqsave (&_stp_module_lock, flags) && (++numtrylock < MAXTRYLOCK)) \
- ndelay (TRYLOCKDELAY); \
- (numtrylock >= MAXTRYLOCK); \
- })
-#define STP_LOCK_MODULES spin_lock_irqsave(&_stp_module_lock, flags)
-#define STP_UNLOCK_MODULES spin_unlock_irqrestore(&_stp_module_lock, flags)
-
static char *_stp_symbol_data = NULL;
static int _stp_symbol_state = 0;
static char *_stp_module_data = NULL;
@@ -63,7 +53,7 @@ static unsigned _stp_get_sym_sizes(struct module *m, unsigned *dsize)
}
/* allocate space for a module and symbols */
-static struct _stp_module * _stp_alloc_module(unsigned num, unsigned datasize)
+static struct _stp_module * _stp_alloc_module(unsigned num, unsigned datasize, unsigned unwindsize)
{
struct _stp_module *mod = (struct _stp_module *)_stp_kzalloc(sizeof(struct _stp_module));
if (mod == NULL)
@@ -85,6 +75,14 @@ static struct _stp_module * _stp_alloc_module(unsigned num, unsigned datasize)
mod->allocated |= 2;
}
+ mod->unwind_data = _stp_kmalloc(unwindsize);
+ if (mod->unwind_data == NULL) {
+ mod->unwind_data = _stp_vmalloc(unwindsize);
+ if (mod->unwind_data == NULL)
+ goto bad;
+ mod->allocated |= 4;
+ }
+
mod->num_symbols = num;
return mod;
@@ -97,19 +95,40 @@ bad:
_stp_kfree(mod->symbols);
mod->symbols = NULL;
}
+ if (mod->symbol_data) {
+ if (mod->allocated & 2)
+ _stp_vfree(mod->symbol_data);
+ else
+ _stp_kfree(mod->symbol_data);
+ mod->symbol_data = NULL;
+ }
+ _stp_kfree(mod);
+ if (mod->symbols) {
+ if (mod->allocated & 1)
+ _stp_vfree(mod->symbols);
+ else
+ _stp_kfree(mod->symbols);
+ mod->symbols = NULL;
+ }
_stp_kfree(mod);
}
return NULL;
}
-static struct _stp_module * _stp_alloc_module_from_module (struct module *m)
+static struct _stp_module * _stp_alloc_module_from_module (struct module *m, uint32_t unwind_len)
{
unsigned datasize, num = _stp_get_sym_sizes(m, &datasize);
- return _stp_alloc_module(num, datasize);
+ return _stp_alloc_module(num, datasize, unwind_len);
}
static void _stp_free_module(struct _stp_module *mod)
{
+ /* The module write lock is held. Any prior readers of this */
+ /* module's data will have read locks and need to finish before */
+ /* the memory is freed. */
+ write_lock(&mod->lock);
+ write_unlock(&mod->lock); /* there will be no more readers */
+
/* free symbol memory */
if (mod->symbols) {
if (mod->allocated & 1)
@@ -126,21 +145,30 @@ static void _stp_free_module(struct _stp_module *mod)
mod->symbol_data = NULL;
}
+ if (mod->unwind_data) {
+ if (mod->allocated & 4)
+ _stp_vfree(mod->unwind_data);
+ else
+ _stp_kfree(mod->unwind_data);
+ mod->unwind_data = NULL;
+
+ }
if (mod->sections) {
_stp_kfree(mod->sections);
mod->sections = NULL;
}
+
/* free module memory */
_stp_kfree(mod);
}
/* Delete a module and free its memory. */
-/* The lock should already be held before calling this. */
+/* The module lock should already be held before calling this. */
static void _stp_del_module(struct _stp_module *mod)
{
int i, num;
- // kbug("deleting %s\n", mod->name);
+ // kbug(DEBUG_SYMBOLS, "deleting %s\n", mod->name);
/* signal relocation code to clear its cache */
_stp_module_relocate((char *)-1, NULL, 0);
@@ -185,7 +213,7 @@ static unsigned long _stp_kallsyms_lookup_name(const char *name);
static int _stp_do_symbols(const char __user *buf, int count)
{
struct _stp_symbol *s;
- unsigned datasize, num;
+ unsigned datasize, num, unwindsize;
int i;
switch (_stp_symbol_state) {
@@ -198,23 +226,26 @@ static int _stp_do_symbols(const char __user *buf, int count)
return -EFAULT;
if (get_user(datasize, (unsigned __user *)(buf+4)))
return -EFAULT;
- //kbug("num=%d datasize=%d\n", num, datasize);
+ if (get_user(unwindsize, (unsigned __user *)(buf+8)))
+ return -EFAULT;
+ dbug(DEBUG_UNWIND, "num=%d datasize=%d unwindsize=%d\n", num, datasize, unwindsize);
- _stp_modules[0] = _stp_alloc_module(num, datasize);
+ _stp_modules[0] = _stp_alloc_module(num, datasize, unwindsize);
if (_stp_modules[0] == NULL) {
errk("cannot allocate memory\n");
return -EFAULT;
}
+ rwlock_init(&_stp_modules[0]->lock);
_stp_symbol_state = 1;
break;
case 1:
- //kbug("got stap_symbols, count=%d\n", count);
+ dbug(DEBUG_SYMBOLS, "got stap_symbols, count=%d\n", count);
if (copy_from_user ((char *)_stp_modules[0]->symbols, buf, count))
return -EFAULT;
_stp_symbol_state = 2;
break;
case 2:
- //kbug("got symbol data, count=%d buf=%p\n", count, buf);
+ dbug(DEBUG_SYMBOLS, "got symbol data, count=%d buf=%p\n", count, buf);
if (copy_from_user (_stp_modules[0]->symbol_data, buf, count))
return -EFAULT;
_stp_num_modules = 1;
@@ -227,8 +258,19 @@ static int _stp_do_symbols(const char __user *buf, int count)
/* NB: this mapping is used by kernel/_stext pseudo-relocations. */
_stp_modules[0]->text = _stp_kallsyms_lookup_name("_stext");
_stp_modules[0]->data = _stp_kallsyms_lookup_name("_etext");
+ _stp_modules[0]->text_size = _stp_modules[0]->data - _stp_modules[0]->text;
_stp_modules_by_addr[0] = _stp_modules[0];
- //kbug("done with symbol data\n");
+ dbug(DEBUG_SYMBOLS, "Got kernel symbols. text=%p len=%u\n",
+ (int64_t)_stp_modules[0]->text, _stp_modules[0]->text_size);
+ break;
+ case 3:
+ dbug(DEBUG_UNWIND, "got unwind data, count=%d\n", count);
+ _stp_symbol_state = 4;
+ if (copy_from_user (_stp_modules[0]->unwind_data, buf, count)) {
+ _dbug("cfu failed\n");
+ return -EFAULT;
+ }
+ _stp_modules[0]->unwind_data_len = count;
break;
default:
errk("unexpected symbol data of size %d.\n", count);
@@ -266,10 +308,8 @@ static void u32_swap(void *a, void *b, int size)
static void generic_swap(void *a, void *b, int size)
{
- char t;
-
do {
- t = *(char *)a;
+ char t = *(char *)a;
*(char *)a++ = *(char *)b;
*(char *)b++ = t;
} while (--size > 0);
@@ -328,7 +368,7 @@ void _stp_sort(void *base, size_t num, size_t size,
}
/* Create a new _stp_module and load the symbols */
-static struct _stp_module *_stp_load_module_symbols (struct _stp_module *imod)
+static struct _stp_module *_stp_load_module_symbols (struct _stp_module *imod, uint32_t unwind_len)
{
unsigned i, num=0;
struct module *m = (struct module *)imod->module;
@@ -336,12 +376,12 @@ static struct _stp_module *_stp_load_module_symbols (struct _stp_module *imod)
char *dataptr;
if (m == NULL) {
- kbug("imod->module is NULL\n");
+ kbug(DEBUG_SYMBOLS, "imod->module is NULL\n");
return NULL;
}
if (try_module_get(m)) {
- mod = _stp_alloc_module_from_module(m);
+ mod = _stp_alloc_module_from_module(m, unwind_len);
if (mod == NULL) {
module_put(m);
errk("failed to allocate memory for module.\n");
@@ -354,6 +394,8 @@ static struct _stp_module *_stp_load_module_symbols (struct _stp_module *imod)
mod->data = imod->data;
mod->num_sections = imod->num_sections;
mod->sections = imod->sections;
+ mod->text_size = m->core_text_size;
+ rwlock_init(&mod->lock);
/* now copy all the symbols we are interested in */
dataptr = mod->symbol_data;
@@ -375,24 +417,32 @@ static struct _stp_module *_stp_load_module_symbols (struct _stp_module *imod)
return mod;
}
-/* Do we already have this module? */
-static int _stp_module_exists(struct _stp_module *mod)
+/* Remove any old module info from our database */
+static void _stp_module_exists_delete (struct _stp_module *mod)
{
- int i, res;
- unsigned long flags;
- // kbug("exists? %s\n", mod->name);
- STP_LOCK_MODULES;
- for (i = 1; i < _stp_num_modules; i++) {
- res = strcmp(_stp_modules[i]->name, mod->name);
- if (res > 0)
+ int i, num;
+
+ /* remove any old modules with the same name */
+ for (num = 1; num < _stp_num_modules; num++) {
+ if (strcmp(_stp_modules[num]->name, mod->name) == 0) {
+ dbug(DEBUG_SYMBOLS, "found existing module with name %s. Deleting.\n", mod->name);
+ _stp_del_module(_stp_modules[num]);
break;
- if (res == 0 && _stp_modules[i]->module == mod->module) {
- STP_UNLOCK_MODULES;
- return 1;
}
}
- STP_UNLOCK_MODULES;
- return 0;
+
+ /* remove modules with overlapping addresses */
+ for (num = 1; num < _stp_num_modules; num++) {
+ if (mod->text + mod->text_size < _stp_modules_by_addr[num]->text)
+ continue;
+ if (mod->text < _stp_modules_by_addr[num]->text
+ + _stp_modules_by_addr[num]->text_size) {
+ dbug(DEBUG_SYMBOLS, "New module %s overlaps with old module %s. Deleting old.\n",
+ mod->name, _stp_modules_by_addr[num]->name);
+ _stp_del_module(_stp_modules_by_addr[num]);
+ }
+ }
+
}
static int _stp_ins_module(struct _stp_module *mod)
@@ -400,9 +450,11 @@ static int _stp_ins_module(struct _stp_module *mod)
int i, num, res, ret = 0;
unsigned long flags;
- // kbug("insert %s\n", mod->name);
+ // kbug(DEBUG_SYMBOLS, "insert %s\n", mod->name);
- STP_LOCK_MODULES;
+ STP_WLOCK_MODULES;
+
+ _stp_module_exists_delete(mod);
/* check for overflow */
if (_stp_num_modules == STP_MAX_MODULES) {
@@ -412,32 +464,25 @@ static int _stp_ins_module(struct _stp_module *mod)
}
/* insert alphabetically in _stp_modules[] */
- for (num = 1; num < _stp_num_modules; num++) {
- res = strcmp(_stp_modules[num]->name, mod->name);
- if (res < 0)
- continue;
- if (res > 0)
+ for (num = 1; num < _stp_num_modules; num++)
+ if (strcmp(_stp_modules[num]->name, mod->name) > 0)
break;
- _stp_del_module(_stp_modules[num]);
- break;
- }
for (i = _stp_num_modules; i > num; i--)
_stp_modules[i] = _stp_modules[i-1];
_stp_modules[num] = mod;
/* insert by text address in _stp_modules_by_addr[] */
- for (num = 1; num < _stp_num_modules; num++) {
- if (_stp_modules_by_addr[num]->text > mod->text)
+ for (num = 1; num < _stp_num_modules; num++)
+ if (mod->text < _stp_modules_by_addr[num]->text)
break;
- }
for (i = _stp_num_modules; i > num; i--)
_stp_modules_by_addr[i] = _stp_modules_by_addr[i-1];
_stp_modules_by_addr[num] = mod;
-
+
_stp_num_modules++;
done:
- STP_UNLOCK_MODULES;
+ STP_WUNLOCK_MODULES;
return ret;
}
@@ -456,13 +501,13 @@ static int _stp_do_module(const char __user *buf, int count)
if (copy_from_user ((char *)&tmpmod, buf, sizeof(tmpmod)))
return -EFAULT;
- section_len = count - sizeof(tmpmod);
+ section_len = count - sizeof(tmpmod) - tmpmod.unwind_len;
if (section_len <= 0) {
errk("section_len = %d\n", section_len);
return -EFAULT;
}
- kbug("Got module %s, count=%d section_len=%d\n",
- tmpmod.name, count, section_len);
+ dbug(DEBUG_SYMBOLS, "Got module %s, count=%d section_len=%d unwind_len=%d\n",
+ tmpmod.name, count, section_len, tmpmod.unwind_len);
strcpy(mod.name, tmpmod.name);
mod.module = tmpmod.module;
@@ -470,9 +515,6 @@ static int _stp_do_module(const char __user *buf, int count)
mod.data = tmpmod.data;
mod.num_sections = tmpmod.num_sections;
- if (_stp_module_exists(&mod))
- return count;
-
/* copy in section data */
mod.sections = _stp_kmalloc(section_len);
if (mod.sections == NULL) {
@@ -489,18 +531,27 @@ static int _stp_do_module(const char __user *buf, int count)
+ (long)((long)mod.sections + mod.num_sections * sizeof(struct _stp_symbol)));
}
- #ifdef DEBUG_SYMBOLS
+ #if 0
for (i = 0; i < mod.num_sections; i++)
- printk("section %d (stored at %p): %s %lx\n", i, &mod.sections[i], mod.sections[i].symbol, mod.sections[i].addr);
+ _dbug("section %d (stored at %p): %s %lx\n", i, &mod.sections[i], mod.sections[i].symbol, mod.sections[i].addr);
#endif
/* load symbols from tmpmod.module to mod */
- m = _stp_load_module_symbols(&mod);
+ m = _stp_load_module_symbols(&mod, tmpmod.unwind_len);
if (m == NULL) {
_stp_kfree(mod.sections);
return 0;
}
+ dbug(DEBUG_SYMBOLS, "module %s loaded. Text=%p text_size=%u\n", m->name, (int64_t)m->text, m->text_size);
+ /* finally copy unwind info */
+ if (copy_from_user (m->unwind_data, buf+sizeof(tmpmod)+section_len, tmpmod.unwind_len)) {
+ _stp_free_module(m);
+ _stp_kfree(mod.sections);
+ return -EFAULT;
+ }
+ m->unwind_data_len = tmpmod.unwind_len;
+
if (_stp_ins_module(m) < 0) {
_stp_free_module(m);
return -ENOMEM;
@@ -513,20 +564,18 @@ static int _stp_ctl_send (int type, void *data, int len);
static int _stp_module_load_notify(struct notifier_block * self, unsigned long val, void * data)
{
-#ifdef CONFIG_MODULES
struct module *mod = (struct module *)data;
struct _stp_module rmod;
switch (val) {
case MODULE_STATE_COMING:
- dbug("module %s loaded\n", mod->name);
+ dbug(DEBUG_SYMBOLS, "module %s load notify\n", mod->name);
strlcpy(rmod.name, mod->name, STP_MODULE_NAME_LEN);
_stp_ctl_send(STP_MODULE, &rmod, sizeof(struct _stp_module));
break;
default:
errk("module loaded? val=%ld\n", val);
}
-#endif
return 0;
}
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 6b90ee64..8335e44b 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -18,6 +18,7 @@
#include <linux/namei.h>
#include "transport.h"
#include "time.c"
+#include "../mempool.c"
#include "symbols.c"
#include "../procfs.c"
@@ -76,7 +77,7 @@ static void _stp_ask_for_symbols(void)
if (sent_symbols == 0) {
/* ask for symbols and modules */
- kbug("AFS\n");
+ kbug(DEBUG_SYMBOLS|DEBUG_TRANSPORT, "AFS\n");
req.endian = 0x1234;
req.ptr_size = sizeof(char *);
@@ -94,7 +95,7 @@ static void _stp_ask_for_symbols(void)
void _stp_handle_start (struct _stp_msg_start *st)
{
- kbug ("stp_handle_start\n");
+ kbug (DEBUG_TRANSPORT, "stp_handle_start\n");
if (register_module_notifier(&_stp_module_load_nb))
errk("failed to load module notifier\n");
@@ -116,7 +117,7 @@ void _stp_handle_start (struct _stp_msg_start *st)
/* when someone does /sbin/rmmod on a loaded systemtap module. */
static void _stp_cleanup_and_exit (int dont_rmmod)
{
- kbug("cleanup_and_exit (%d)\n", dont_rmmod);
+ kbug(DEBUG_TRANSPORT, "cleanup_and_exit (%d)\n", dont_rmmod);
if (!_stp_exit_called) {
int failures;
@@ -127,23 +128,23 @@ static void _stp_cleanup_and_exit (int dont_rmmod)
_stp_exit_called = 1;
if (_stp_probes_started) {
- kbug("calling probe_exit\n");
+ kbug(DEBUG_TRANSPORT, "calling probe_exit\n");
/* tell the stap-generated code to unload its probes, etc */
probe_exit();
- kbug("done with probe_exit\n");
+ kbug(DEBUG_TRANSPORT, "done with probe_exit\n");
}
failures = atomic_read(&_stp_transport_failures);
if (failures)
_stp_warn ("There were %d transport failures.\n", failures);
- kbug("************** calling startstop 0 *************\n");
+ kbug(DEBUG_TRANSPORT, "************** calling startstop 0 *************\n");
if (_stp_utt) utt_trace_startstop(_stp_utt, 0, &utt_seq);
- kbug("ctl_send STP_EXIT\n");
+ kbug(DEBUG_TRANSPORT, "ctl_send STP_EXIT\n");
/* tell staprun to exit (if it is still there) */
_stp_ctl_send(STP_EXIT, &dont_rmmod, sizeof(int));
- kbug("done with ctl_send STP_EXIT\n");
+ kbug(DEBUG_TRANSPORT, "done with ctl_send STP_EXIT\n");
}
}
@@ -152,7 +153,7 @@ static void _stp_cleanup_and_exit (int dont_rmmod)
*/
static void _stp_detach(void)
{
- kbug("detach\n");
+ kbug(DEBUG_TRANSPORT, "detach\n");
_stp_attached = 0;
_stp_pid = 0;
@@ -168,7 +169,7 @@ static void _stp_detach(void)
*/
static void _stp_attach(void)
{
- kbug("attach\n");
+ kbug(DEBUG_TRANSPORT, "attach\n");
_stp_attached = 1;
_stp_pid = current->pid;
utt_set_overwrite(0);
@@ -210,7 +211,7 @@ static void _stp_work_queue (void *data)
*/
void _stp_transport_close()
{
- kbug("%d: ************** transport_close *************\n", current->pid);
+ kbug(DEBUG_TRANSPORT, "%d: ************** transport_close *************\n", current->pid);
_stp_cleanup_and_exit(1);
destroy_workqueue(_stp_wq);
_stp_unregister_ctl_channel();
@@ -219,7 +220,7 @@ void _stp_transport_close()
_stp_kill_time();
_stp_print_cleanup(); /* free print buffers */
_stp_mem_debug_done();
- kbug("---- CLOSED ----\n");
+ kbug(DEBUG_TRANSPORT, "---- CLOSED ----\n");
}
@@ -248,7 +249,7 @@ int _stp_transport_init(void)
{
int ret;
- kbug("transport_init\n");
+ kbug(DEBUG_TRANSPORT, "transport_init\n");
_stp_init_pid = current->pid;
_stp_uid = current->uid;
_stp_gid = current->gid;
@@ -263,7 +264,7 @@ int _stp_transport_init(void)
unsigned size = _stp_bufsize * 1024 * 1024;
_stp_subbuf_size = ((size >> 2) + 1) * 65536;
_stp_nsubbufs = size / _stp_subbuf_size;
- kbug("Using %d subbufs of size %d\n", _stp_nsubbufs, _stp_subbuf_size);
+ kbug(DEBUG_TRANSPORT, "Using %d subbufs of size %d\n", _stp_nsubbufs, _stp_subbuf_size);
}
/* initialize timer code */
@@ -388,12 +389,12 @@ static struct dentry *_stp_get_root_dir(const char *name) {
_stp_lock_inode(sb->s_root->d_inode);
root = lookup_one_len(name, sb->s_root, strlen(name));
_stp_unlock_inode(sb->s_root->d_inode);
- kbug("root=%p\n", root);
+ kbug(DEBUG_TRANSPORT, "root=%p\n", root);
if (!IS_ERR(root))
dput(root);
else {
root = NULL;
- kbug("Could not create or find transport directory.\n");
+ kbug(DEBUG_TRANSPORT, "Could not create or find transport directory.\n");
}
}
_stp_unlock_debugfs();
diff --git a/runtime/transport/transport_msgs.h b/runtime/transport/transport_msgs.h
index b2187cd5..55de2d4a 100644
--- a/runtime/transport/transport_msgs.h
+++ b/runtime/transport/transport_msgs.h
@@ -36,7 +36,30 @@ enum
STP_SUBBUFS_CONSUMED,
STP_REALTIME_DATA,
#endif
+
+ STP_MAX_CMD
+};
+
+#ifdef DEBUG_TRANSPORT
+static const char *_stp_command_name[] = {
+ "STP_START",
+ "STP_EXIT",
+ "STP_OOB_DATA",
+ "STP_SYSTEM",
+ "STP_SYMBOLS",
+ "STP_MODULE",
+ "STP_TRANSPORT",
+ "STP_CONNECT",
+ "STP_DISCONNECT",
+ "STP_BULK",
+ "STP_READY",
+#ifdef STP_OLD_TRANSPORT
+ "STP_BUF_INFO",
+ "STP_SUBBUFS_CONSUMED",
+ "STP_REALTIME_DATA",
+#endif
};
+#endif /* DEBUG_TRANSPORT */
/* control channel messages */