summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2009-03-13 13:22:10 -0500
committerDavid Smith <dsmith@redhat.com>2009-03-13 13:22:10 -0500
commit8d1dd679bdbe3f4c40305fdbca0c1b4002913e87 (patch)
tree1c22dea8e76cd11500f613cdad0a5472be6ea2de /runtime
parentc24cd76e91647ebdf98445439083c1b0e0a65dd4 (diff)
downloadsystemtap-steved-8d1dd679bdbe3f4c40305fdbca0c1b4002913e87.tar.gz
systemtap-steved-8d1dd679bdbe3f4c40305fdbca0c1b4002913e87.tar.xz
systemtap-steved-8d1dd679bdbe3f4c40305fdbca0c1b4002913e87.zip
More bulkmode support. Only allows for one reader of all trace files.
2009-03-13 David Smith <dsmith@redhat.com> * transport/ring_buffer.c (__stp_free_ring_buffer): Frees _stp_trace_reader_cpumask. (__stp_alloc_ring_buffer): Allocates and clears _stp_trace_reader_cpumask. (_stp_data_open_trace): Instead of using an atomic variable, uses a cpumask variable to allow for only one reader of trace files. (_stp_data_release_trace): Clears cpumask when trace files are closed.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/transport/ring_buffer.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/runtime/transport/ring_buffer.c b/runtime/transport/ring_buffer.c
index 22e62cdf..a933ff9a 100644
--- a/runtime/transport/ring_buffer.c
+++ b/runtime/transport/ring_buffer.c
@@ -2,6 +2,7 @@
#include <linux/ring_buffer.h>
#include <linux/wait.h>
#include <linux/poll.h>
+#include <linux/cpumask.h>
#ifdef STP_BULKMODE
#error "bulkmode support unfinished..."
@@ -44,8 +45,11 @@ struct _stp_ring_buffer_iterator {
static struct _stp_ring_buffer_iterator _stp_iter;
#endif
+static cpumask_var_t _stp_trace_reader_cpumask;
+
static void __stp_free_ring_buffer(void)
{
+ free_cpumask_var(_stp_trace_reader_cpumask);
if (__stp_ring_buffer)
ring_buffer_free(__stp_ring_buffer);
__stp_ring_buffer = NULL;
@@ -56,6 +60,10 @@ static int __stp_alloc_ring_buffer(void)
int i;
unsigned long buffer_size = _stp_bufsize;
+ if (!alloc_cpumask_var(&_stp_trace_reader_cpumask, GFP_KERNEL))
+ goto fail;
+ cpumask_clear(_stp_trace_reader_cpumask);
+
if (buffer_size == 0) {
dbug_trans(1, "using default buffer size...\n");
buffer_size = _stp_nsubbufs * _stp_subbuf_size;
@@ -77,25 +85,39 @@ fail:
return -ENOMEM;
}
-static atomic_t _stp_trace_attached = ATOMIC_INIT(0);
-
static int _stp_data_open_trace(struct inode *inode, struct file *file)
{
- /* We only allow for one reader */
+ long cpu_file = (long) inode->i_private;
+
+ /* We only allow for one reader per cpu */
dbug_trans(1, "trace attach\n");
- if (atomic_inc_return(&_stp_trace_attached) != 1) {
- atomic_dec(&_stp_trace_attached);
+#ifdef STP_BULKMODE
+ if (!cpumask_test_cpu(cpu_file, _stp_trace_reader_cpumask))
+ cpumask_set_cpu(cpu_file, _stp_trace_reader_cpumask);
+ else {
dbug_trans(1, "returning EBUSY\n");
return -EBUSY;
}
-
+#else
+ if (!cpumask_empty(_stp_trace_reader_cpumask)) {
+ dbug_trans(1, "returning EBUSY\n");
+ return -EBUSY;
+ }
+ cpumask_setall(_stp_trace_reader_cpumask);
+#endif
return 0;
}
static int _stp_data_release_trace(struct inode *inode, struct file *file)
{
+ long cpu_file = (long) inode->i_private;
dbug_trans(1, "trace detach\n");
- atomic_dec(&_stp_trace_attached);
+#ifdef STP_BULKMODE
+ cpumask_clear_cpu(cpu_file, _stp_trace_reader_cpumask);
+#else
+ cpumask_clear(_stp_trace_reader_cpumask);
+#endif
+
return 0;
}