Re: [PATCH v2 13/29] ktap: add ring buffer handling code(kernel/trace/ktap/kp_transport.[c|h])

2014-03-30 Thread Jovi Zhangwei
On Sun, Mar 30, 2014 at 11:58 AM, Andi Kleen  wrote:
>>
>> A lot of code in this file is duplicated with kernel trace_output.c.
>
> Please modify trace_output instead to avoid this.
>
Yeah, ktap transport functionality is based on ftrace ring buffer,
and reading buffer is through trace pipe.

I will try to figure out some way to reuse ftrace trace pipe reading
code as much as possible.

Thanks.

Jovi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 13/29] ktap: add ring buffer handling code(kernel/trace/ktap/kp_transport.[c|h])

2014-03-29 Thread Andi Kleen
> 
> A lot of code in this file is duplicated with kernel trace_output.c.

Please modify trace_output instead to avoid this.

-Andi

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 13/29] ktap: add ring buffer handling code(kernel/trace/ktap/kp_transport.[c|h])

2014-03-29 Thread Jovi Zhangwei
ktap transport functionality is based on ftrace ring buffer.

All contents generated by ktap runtime will send to userspace
through this ring buffer.

Actually the concept of ktap transport is similar with ftrace,
for example, it will write event binary data into ring buffer
when use call: 'print(argstr)' or 'print(stack())', and the content
will be parse in consumer side, not producer side.

Userspace reader thread will consume content in ring buffer through
'/sys/kernel/debug/ktap/trace_pipe_$pid'

A lot of code in this file is duplicated with kernel trace_output.c.

Exposed functions:
1). kp_transport_init
2). kp_transport_exit
3). __kp_bputs/__kp_puts/kp_printf
4). kp_transport_write
5). kp_transport_event_write
write a event content into ring buffer, called by: 'print(argstr)'
6). kp_transport_print_kstack
write a kernel stack into ring buffer, called by: 'print(stack())'

Signed-off-by: Jovi Zhangwei 
---
 kernel/trace/ktap/kp_transport.c | 649 +++
 kernel/trace/ktap/kp_transport.h |  13 +
 2 files changed, 662 insertions(+)
 create mode 100644 kernel/trace/ktap/kp_transport.c
 create mode 100644 kernel/trace/ktap/kp_transport.h

diff --git a/kernel/trace/ktap/kp_transport.c b/kernel/trace/ktap/kp_transport.c
new file mode 100644
index 000..5baf586
--- /dev/null
+++ b/kernel/trace/ktap/kp_transport.c
@@ -0,0 +1,649 @@
+/*
+ * kp_transport.c - ktap transport functionality
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei .
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "ktap.h"
+#include "kp_events.h"
+#include "kp_transport.h"
+
+struct ktap_trace_iterator {
+   struct ring_buffer  *buffer;
+   int print_timestamp;
+   void*private;
+
+   struct trace_iterator   iter;
+};
+
+enum ktap_trace_type {
+   __TRACE_FIRST_TYPE = 0,
+
+   TRACE_FN = 1, /* must be same as ftrace definition in kernel */
+   TRACE_PRINT,
+   TRACE_BPUTS,
+   TRACE_STACK,
+   TRACE_USER_STACK,
+
+   __TRACE_LAST_TYPE,
+};
+
+#define KTAP_TRACE_ITER(iter)  \
+   container_of(iter, struct ktap_trace_iterator, iter)
+
+static
+ssize_t _trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
+{
+   int len;
+   int ret;
+
+   if (!cnt)
+   return 0;
+
+   if (s->len <= s->readpos)
+   return -EBUSY;
+
+   len = s->len - s->readpos;
+   if (cnt > len)
+   cnt = len;
+   ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
+   if (ret == cnt)
+   return -EFAULT;
+
+   cnt -= ret;
+
+   s->readpos += cnt;
+   return cnt;
+}
+
+int _trace_seq_puts(struct trace_seq *s, const char *str)
+{
+   int len = strlen(str);
+
+   if (s->full)
+   return 0;
+
+   if (len > ((PAGE_SIZE - 1) - s->len)) {
+   s->full = 1;
+   return 0;
+   }
+
+   memcpy(s->buffer + s->len, str, len);
+   s->len += len;
+
+   return len;
+}
+
+static int trace_empty(struct trace_iterator *iter)
+{
+   struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+   int cpu;
+
+   for_each_online_cpu(cpu) {
+   if (!ring_buffer_empty_cpu(ktap_iter->buffer, cpu))
+   return 0;
+   }
+
+   return 1;
+}
+
+static void trace_consume(struct trace_iterator *iter)
+{
+   struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+
+   ring_buffer_consume(ktap_iter->buffer, iter->cpu, &iter->ts,
+   &iter->lost_events);
+}
+
+unsigned long long ns2usecs(cycle_t nsec)
+{
+   nsec += 500;
+   do_div(nsec, 1000);
+   return nsec;
+}
+
+static int trace_print_timestamp(struct trace_iterator *iter)
+{
+   struct trace_seq *s = &iter->seq;
+   unsigned long long t;
+   unsigned long secs, usec_rem;
+
+   t = ns2usecs(iter->ts);
+   usec_rem = do_div(t, USEC_PER_SEC);
+   secs = (unsigned long)t;
+
+   return trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
+}
+
+/* todo: export kernel function ftrace_find_event in future, and make faster */
+static struct trace_event *(*ftr