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-11-24 15:21:06 -0500 |
| commit | e079932a0a1aab6adbc42fedefc6caa2d9a8af2b (patch) | |
| tree | b40d3cb42068da1b14db3d3e9836fbc372056a33 /litmus/trace.c | |
| parent | 12982f31a233250c7a62b17fb4bd13594cb78777 (diff) | |
Feather-trace: let userspace add overhead events
This is useful for measuring locking-related overheads
that are partially recorded in userspace.
Diffstat (limited to 'litmus/trace.c')
| -rw-r--r-- | litmus/trace.c | 40 |
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 | ||
| 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,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 | ||
| 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 | /* 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 | |||
| 146 | out: | ||
| 147 | return consumed; | ||
| 148 | } | ||
| 149 | |||
| 111 | static int __init init_ft_overhead_trace(void) | 150 | static 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) |
