summaryrefslogtreecommitdiffstats
path: root/runtime/transport/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/transport/control.c')
-rw-r--r--runtime/transport/control.c225
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);