From e079932a0a1aab6adbc42fedefc6caa2d9a8af2b Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Sat, 23 Jul 2011 23:40:10 -0400 Subject: Feather-trace: let userspace add overhead events This is useful for measuring locking-related overheads that are partially recorded in userspace. --- litmus/trace.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) 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 @@ #include #include +#include #include #include @@ -31,6 +32,18 @@ static inline void __save_timestamp_cpu(unsigned long event, } } +static void __add_timestamp_user(struct timestamp *pre_recorded) +{ + unsigned int seq_no; + struct timestamp *ts; + seq_no = fetch_and_inc((int *) &ts_seq_no); + if (ft_buffer_start_write(trace_ts_buf, (void**) &ts)) { + *ts = *pre_recorded; + ts->seq_no = seq_no; + ft_buffer_finish_write(trace_ts_buf, ts); + } +} + static inline void __save_timestamp(unsigned long event, uint8_t type) { @@ -108,6 +121,32 @@ static void free_timestamp_buffer(struct ftdev* ftdev, unsigned int idx) ftdev->minor[idx].buf = NULL; } +static ssize_t write_timestamp_from_user(struct ft_buffer* buf, size_t len, + const char __user *from) +{ + ssize_t consumed = 0; + struct timestamp ts; + + /* don't give us partial timestamps */ + if (len % sizeof(ts)) + return -EINVAL; + + while (len >= sizeof(ts)) { + if (copy_from_user(&ts, from, sizeof(ts))) { + consumed = -EFAULT; + goto out; + } + len -= sizeof(ts); + from += sizeof(ts); + consumed += sizeof(ts); + + __add_timestamp_user(&ts); + } + +out: + return consumed; +} + static int __init init_ft_overhead_trace(void) { int err; @@ -119,6 +158,7 @@ static int __init init_ft_overhead_trace(void) overhead_dev.alloc = alloc_timestamp_buffer; overhead_dev.free = free_timestamp_buffer; + overhead_dev.write = write_timestamp_from_user; err = register_ftdev(&overhead_dev); if (err) -- cgit v1.2.2