diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-07-23 23:40:10 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-07-23 23:40:10 -0400 |
commit | 65e95197fa507e236d835d41dbb97a5c0eaddeef (patch) | |
tree | 078a62aebdf2d23dcec9b75b59bbcf60c9d6025b | |
parent | 4d006837b842fed343d86dfa20953763ae38067a (diff) |
feather-trace: let userspace add overhead events
This will be useful for measuring locking-related overheads
that are partially recorded in userspace.
-rw-r--r-- | litmus/trace.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/litmus/trace.c b/litmus/trace.c index f0eb2c706488..7cd09b3b436d 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 | ||
35 | static 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 | |||
34 | static inline void __save_timestamp(unsigned long event, | 47 | static inline void __save_timestamp(unsigned long event, |
35 | uint8_t type) | 48 | uint8_t type) |
36 | { | 49 | { |
@@ -108,6 +121,28 @@ 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 | ||
124 | static 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 | while (len >= sizeof(ts)) { | ||
131 | if (copy_from_user(&ts, from, sizeof(ts))) { | ||
132 | consumed = -EFAULT; | ||
133 | goto out; | ||
134 | } | ||
135 | len -= sizeof(ts); | ||
136 | from += sizeof(ts); | ||
137 | consumed += sizeof(ts); | ||
138 | |||
139 | __add_timestamp_user(&ts); | ||
140 | } | ||
141 | |||
142 | out: | ||
143 | return consumed; | ||
144 | } | ||
145 | |||
111 | static int __init init_ft_overhead_trace(void) | 146 | static int __init init_ft_overhead_trace(void) |
112 | { | 147 | { |
113 | int err; | 148 | int err; |
@@ -119,6 +154,7 @@ static int __init init_ft_overhead_trace(void) | |||
119 | 154 | ||
120 | overhead_dev.alloc = alloc_timestamp_buffer; | 155 | overhead_dev.alloc = alloc_timestamp_buffer; |
121 | overhead_dev.free = free_timestamp_buffer; | 156 | overhead_dev.free = free_timestamp_buffer; |
157 | overhead_dev.write = write_timestamp_from_user; | ||
122 | 158 | ||
123 | err = register_ftdev(&overhead_dev); | 159 | err = register_ftdev(&overhead_dev); |
124 | if (err) | 160 | if (err) |