From: David Smith Date: Fri, 13 Mar 2009 18:22:10 +0000 (-0500) Subject: More bulkmode support. Only allows for one reader of all trace files. X-Git-Tag: release-0.9.9~137^2~34 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=8d1dd679bdbe3f4c40305fdbca0c1b4002913e87;p=systemtap.git More bulkmode support. Only allows for one reader of all trace files. 2009-03-13 David Smith * 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. --- diff --git a/runtime/transport/ring_buffer.c b/runtime/transport/ring_buffer.c index 22e62cdf8..a933ff9a3 100644 --- a/runtime/transport/ring_buffer.c +++ b/runtime/transport/ring_buffer.c @@ -2,6 +2,7 @@ #include #include #include +#include #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; }