diff options
Diffstat (limited to 'runtime/transport/control.c')
-rw-r--r-- | runtime/transport/control.c | 225 |
1 files changed, 22 insertions, 203 deletions
diff --git a/runtime/transport/control.c b/runtime/transport/control.c index 6a5b272d..ed7725fa 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -14,80 +14,31 @@ 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; 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 int saved_type = 0; - int type; - - if (count < sizeof(int32_t)) - return 0; - - /* 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; - return count; - } else if (saved_type) { - type = saved_type; - saved_type = 0; - } else { - if (get_user(type, (int __user *)buf)) - return -EFAULT; - count -= sizeof(int); - buf += sizeof(int); - } - -#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: - count = _stp_do_symbols(buf, count); - break; - case STP_MODULE: - if (count > 1) - count = _stp_do_module(buf, count); - else { - /* count == 1 indicates end of initial modules list */ - _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); - return -EINVAL; - } - - return count; -} static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - int type; + u32 type; static int started = 0; - if (count < sizeof(int)) + if (count < sizeof(u32)) return 0; - if (get_user(type, (int __user *)buf)) + if (get_user(type, (u32 __user *)buf)) return -EFAULT; -#if DEBUG_TRANSPORT > 0 + count -= sizeof(u32); + buf += sizeof(u32); + +#ifdef DEBUG_TRANS if (type < STP_MAX_CMD) _dbug("Got %s. len=%d\n", _stp_command_name[type], (int)count); #endif - count -= sizeof(int); - buf += sizeof(int); - switch (type) { + case STP_UNWIND: + _stp_do_unwind_data(buf, count); + break; case STP_START: if (started == 0) { struct _stp_msg_start st; @@ -110,7 +61,7 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz #endif case STP_READY: /* request symbolic information */ - _stp_ask_for_symbols(); + /* _stp_ask_for_symbols(); */ break; default: @@ -121,8 +72,6 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz return count; } -#define STP_CTL_BUFFER_SIZE 256 - struct _stp_buffer { struct list_head list; int len; @@ -131,9 +80,8 @@ struct _stp_buffer { }; static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq); -static DECLARE_WAIT_QUEUE_HEAD(_stp_sym_wq); -#if DEBUG_TRANSPORT > 0 +#ifdef DEBUG_TRANS static void _stp_ctl_write_dbug(int type, void *data, int len) { char buf[64]; @@ -155,20 +103,9 @@ static void _stp_ctl_write_dbug(int type, void *data, int len) case STP_TRANSPORT: _dbug("sending STP_TRANSPORT\n"); break; - default: - _dbug("ERROR: unknown message type: %d\n", type); - break; - } -} -static void _stp_sym_write_dbug(int type, void *data, int len) -{ - switch (type) { - case STP_SYMBOLS: - _dbug("sending STP_SYMBOLS\n"); - break; - case STP_MODULE: - _dbug("sending STP_MODULE\n"); - break; + case STP_UNWIND: + snprintf(buf, sizeof(buf), "%s", (char *)data); + _dbug("sending STP_UNWIND %s [len=%d]\n", buf, len); default: _dbug("ERROR: unknown message type: %d\n", type); break; @@ -181,7 +118,7 @@ static int _stp_ctl_write(int type, void *data, unsigned len) struct _stp_buffer *bptr; unsigned long flags; -#if DEBUG_TRANSPORT > 0 +#ifdef DEBUG_TRANS _stp_ctl_write_dbug(type, data, len); #endif @@ -206,96 +143,19 @@ static int _stp_ctl_write(int type, void *data, unsigned len) return len; } -static int _stp_sym_write(int type, void *data, unsigned len) -{ - struct _stp_buffer *bptr; - unsigned long flags; - -#if DEBUG_TRANSPORT > 0 - _stp_sym_write_dbug(type, data, len); -#endif - - /* make sure we won't overflow the buffer */ - if (unlikely(len > STP_CTL_BUFFER_SIZE)) - return 0; - - /* get a buffer from the free pool */ - bptr = _stp_mempool_alloc(_stp_pool_q); - if (unlikely(bptr == NULL)) - return -1; - - bptr->type = type; - memcpy(bptr->buf, data, len); - bptr->len = len; - - /* put it on the pool of ready buffers */ - spin_lock_irqsave(&_stp_sym_ready_lock, flags); - list_add_tail(&bptr->list, &_stp_sym_ready_q); - spin_unlock_irqrestore(&_stp_sym_ready_lock, flags); - - /* OK, it's queued. Now signal any waiters. */ - wake_up_interruptible(&_stp_sym_wq); - - return len; -} - /* send commands with timeout and retry */ 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); - } else { - while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--) - msleep(5); - if (err > 0) - wake_up_interruptible(&_stp_ctl_wq); - } - kbug(DEBUG_TRANSPORT, "returning %d\n", err); + dbug_trans(1, "ctl_send: type=%d len=%d\n", type, len); + while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--) + msleep(5); + if (err > 0) + wake_up_interruptible(&_stp_ctl_wq); + dbug_trans(1, "returning %d\n", err); return err; } -static ssize_t _stp_sym_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - struct _stp_buffer *bptr; - int len; - unsigned long flags; - - /* wait for nonempty ready queue */ - spin_lock_irqsave(&_stp_sym_ready_lock, flags); - while (list_empty(&_stp_sym_ready_q)) { - spin_unlock_irqrestore(&_stp_sym_ready_lock, flags); - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - if (wait_event_interruptible(_stp_sym_wq, !list_empty(&_stp_sym_ready_q))) - 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); - spin_unlock_irqrestore(&_stp_sym_ready_lock, flags); - - /* write it out */ - len = bptr->len + 4; - if (len > count || copy_to_user(buf, &bptr->type, len)) { - /* now what? We took it off the queue then failed to send it */ - /* we can't put it back on the queue because it will likely be out-of-order */ - /* fortunately this should never happen */ - /* FIXME need to mark this as a transport failure */ - errk("Supplied buffer too small. count:%d len:%d\n", (int)count, len); - return -EFAULT; - } - - /* put it on the pool of free buffers */ - _stp_mempool_free(bptr); - - return len; -} - static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct _stp_buffer *bptr; @@ -335,29 +195,10 @@ static ssize_t _stp_ctl_read_cmd(struct file *file, char __user *buf, size_t cou return len; } -static int _stp_sym_opens = 0; -static int _stp_sym_open_cmd(struct inode *inode, struct file *file) -{ - /* only allow one reader */ - if (_stp_sym_opens) - return -1; - - _stp_sym_opens++; - return 0; -} - -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) { if (_stp_attached) return -1; - _stp_attach(); return 0; } @@ -377,16 +218,7 @@ static struct file_operations _stp_ctl_fops_cmd = { .release = _stp_ctl_close_cmd, }; -static struct file_operations _stp_sym_fops_cmd = { - .owner = THIS_MODULE, - .read = _stp_sym_read_cmd, - .write = _stp_sym_write_cmd, - .open = _stp_sym_open_cmd, - .release = _stp_sym_close_cmd, -}; - static struct dentry *_stp_cmd_file = NULL; -static struct dentry *_stp_sym_file = NULL; static int _stp_register_ctl_channel(void) { @@ -400,7 +232,6 @@ static int _stp_register_ctl_channel(void) } INIT_LIST_HEAD(&_stp_ctl_ready_q); - INIT_LIST_HEAD(&_stp_sym_ready_q); /* allocate buffers */ _stp_pool_q = _stp_mempool_init(sizeof(struct _stp_buffer), STP_DEFAULT_BUFFERS); @@ -415,15 +246,9 @@ static int _stp_register_ctl_channel(void) _stp_cmd_file->d_inode->i_uid = _stp_uid; _stp_cmd_file->d_inode->i_gid = _stp_gid; - /* create [debugfs]/systemtap/module_name/.symbols */ - _stp_sym_file = debugfs_create_file(".symbols", 0600, _stp_utt->dir, NULL, &_stp_sym_fops_cmd); - if (_stp_sym_file == NULL) - goto err0; return 0; err0: - if (_stp_cmd_file) - debugfs_remove(_stp_cmd_file); _stp_mempool_destroy(_stp_pool_q); errk("Error creating systemtap debugfs entries.\n"); return -1; @@ -432,16 +257,10 @@ err0: 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); /* Return memory to pool and free it. */ - list_for_each_safe(p, tmp, &_stp_sym_ready_q) { - list_del(p); - _stp_mempool_free(p); - } list_for_each_safe(p, tmp, &_stp_ctl_ready_q) { list_del(p); _stp_mempool_free(p); |