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