aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-07-23 23:40:10 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-11-24 15:21:06 -0500
commite079932a0a1aab6adbc42fedefc6caa2d9a8af2b (patch)
treeb40d3cb42068da1b14db3d3e9836fbc372056a33
parent12982f31a233250c7a62b17fb4bd13594cb78777 (diff)
Feather-trace: let userspace add overhead events
This is useful for measuring locking-related overheads that are partially recorded in userspace.
-rw-r--r--litmus/trace.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/litmus/trace.c b/litmus/trace.c
index f0eb2c706488..5d77806da647 100644
--- a/litmus/trace.c
+++ b/litmus/trace.c
@@ -1,5 +1,6 @@
1#include <linux/sched.h> 1#include <linux/sched.h>
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/uaccess.h>
3 4
4#include <litmus/ftdev.h> 5#include <litmus/ftdev.h>
5#include <litmus/litmus.h> 6#include <litmus/litmus.h>
@@ -31,6 +32,18 @@ static inline void __save_timestamp_cpu(unsigned long event,
31 } 32 }
32} 33}
33 34
35static void __add_timestamp_user(struct timestamp *pre_recorded)
36{
37 unsigned int seq_no;
38 struct timestamp *ts;
39 seq_no = fetch_and_inc((int *) &ts_seq_no);
40 if (ft_buffer_start_write(trace_ts_buf, (void**) &ts)) {
41 *ts = *pre_recorded;
42 ts->seq_no = seq_no;
43 ft_buffer_finish_write(trace_ts_buf, ts);
44 }
45}
46
34static inline void __save_timestamp(unsigned long event, 47static inline void __save_timestamp(unsigned long event,
35 uint8_t type) 48 uint8_t type)
36{ 49{
@@ -108,6 +121,32 @@ static void free_timestamp_buffer(struct ftdev* ftdev, unsigned int idx)
108 ftdev->minor[idx].buf = NULL; 121 ftdev->minor[idx].buf = NULL;
109} 122}
110 123
124static ssize_t write_timestamp_from_user(struct ft_buffer* buf, size_t len,
125 const char __user *from)
126{
127 ssize_t consumed = 0;
128 struct timestamp ts;
129
130 /* don't give us partial timestamps */
131 if (len % sizeof(ts))
132 return -EINVAL;
133
134 while (len >= sizeof(ts)) {
135 if (copy_from_user(&ts, from, sizeof(ts))) {
136 consumed = -EFAULT;
137 goto out;
138 }
139 len -= sizeof(ts);
140 from += sizeof(ts);
141 consumed += sizeof(ts);
142
143 __add_timestamp_user(&ts);
144 }
145
146out:
147 return consumed;
148}
149
111static int __init init_ft_overhead_trace(void) 150static int __init init_ft_overhead_trace(void)
112{ 151{
113 int err; 152 int err;
@@ -119,6 +158,7 @@ static int __init init_ft_overhead_trace(void)
119 158
120 overhead_dev.alloc = alloc_timestamp_buffer; 159 overhead_dev.alloc = alloc_timestamp_buffer;
121 overhead_dev.free = free_timestamp_buffer; 160 overhead_dev.free = free_timestamp_buffer;
161 overhead_dev.write = write_timestamp_from_user;
122 162
123 err = register_ftdev(&overhead_dev); 163 err = register_ftdev(&overhead_dev);
124 if (err) 164 if (err)