diff options
author | hunt <hunt> | 2008-02-27 19:45:45 +0000 |
---|---|---|
committer | hunt <hunt> | 2008-02-27 19:45:45 +0000 |
commit | 9a5de18784b77de82e5121861fac892c2d4d2630 (patch) | |
tree | 54d0a3fb138a31627788606953bb1cb37897caf8 /runtime/transport/procfs.c | |
parent | a2dc47ddef0dbed1b0dc912c876f5f57f97c1ede (diff) | |
download | systemtap-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.
Diffstat (limited to 'runtime/transport/procfs.c')
-rw-r--r-- | runtime/transport/procfs.c | 288 |
1 files changed, 103 insertions, 185 deletions
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); } - |