2013-06-04 05:20:37

by Namhyung Kim

[permalink] [raw]
Subject: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

Hello,

This patchset is a resend version of previous work and basis of
upcoming perf ftrace patchset. Although I saw no issue on this series
when I posted earlier, it'd be great if Steve or others take a look at
it again and give comments.

I also updated 'perf/cleanup' branch on my tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git

Thanks,
Namhyung


Namhyung Kim (16):
tools lib traceevent: Remove unused install targets
tools lib traceevent: Get rid of unused gui target
tools lib traceevent: Add const qualifier to string arguments
tools lib traceevent: Add trace_seq_reset()
tools lib traceevent: Add page_size field to pevent
tools lib traceevent: Port kbuffer parser routines
perf util: Save page size in a trace file to pevent
perf util: Save long size of traced system
perf util: Make file/host_bigendian variable local
perf util: Skip reading header_event file
perf util: Parse header_page to get proper long size
perf util: Get rid of unused header_page_* variables
perf util: Move latency_format variable to builtin-script.c
perf util: Rename read_*() functions in trace-event-info.c
perf util: No need to call read_trace_init() in tracing_data_header()
perf util: Remove unused enum and macro in trace-event.h

tools/lib/traceevent/Makefile | 18 +-
tools/lib/traceevent/event-parse.c | 7 +-
tools/lib/traceevent/event-parse.h | 15 +-
tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
tools/lib/traceevent/kbuffer.h | 67 ++++
tools/lib/traceevent/trace-seq.c | 13 +
tools/perf/builtin-script.c | 1 +
tools/perf/util/trace-event-info.c | 22 +-
tools/perf/util/trace-event-parse.c | 6 -
tools/perf/util/trace-event-read.c | 52 ++-
tools/perf/util/trace-event.h | 15 -
11 files changed, 875 insertions(+), 73 deletions(-)
create mode 100644 tools/lib/traceevent/kbuffer-parse.c
create mode 100644 tools/lib/traceevent/kbuffer.h

--
1.7.11.7


2013-06-04 05:20:41

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 03/16] tools lib traceevent: Add const qualifier to string arguments

From: Namhyung Kim <[email protected]>

If pevent_register_event_handler() received a string literal as
@sys_name or @event_name parameter, it emitted a warning about const
qualifier removal. Since they're not modified in the function we can
make it have const qualifier.

Acked-by: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/event-parse.c | 7 +++----
tools/lib/traceevent/event-parse.h | 3 ++-
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 82b0606dcb8a..d1c2a6a4cd32 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5450,10 +5450,9 @@ int pevent_register_print_function(struct pevent *pevent,
* If @id is >= 0, then it is used to find the event.
* else @sys_name and @event_name are used.
*/
-int pevent_register_event_handler(struct pevent *pevent,
- int id, char *sys_name, char *event_name,
- pevent_event_handler_func func,
- void *context)
+int pevent_register_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
+ pevent_event_handler_func func, void *context)
{
struct event_format *event;
struct event_handler *handle;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 7be7e89533e4..bfceab948f22 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -561,7 +561,8 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
struct pevent_record *record, int err);

-int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
+int pevent_register_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
pevent_event_handler_func func, void *context);
int pevent_register_print_function(struct pevent *pevent,
pevent_func_handler func,
--
1.7.11.7

2013-06-04 05:20:47

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 16/16] perf util: Remove unused enum and macro in trace-event.h

From: Namhyung Kim <[email protected]>

They're internals of ftrace ring-buffer and not used in perf code
directly. As it now resides on libtraceevent/kbuffer.h, just get
rid of them.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event.h | 10 ----------
1 file changed, 10 deletions(-)

diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 96ad22f98726..929baae82f71 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -12,16 +12,6 @@ struct perf_tool;

extern struct pevent *perf_pevent;

-enum {
- RINGBUF_TYPE_PADDING = 29,
- RINGBUF_TYPE_TIME_EXTEND = 30,
- RINGBUF_TYPE_TIME_STAMP = 31,
-};
-
-#ifndef TS_SHIFT
-#define TS_SHIFT 27
-#endif
-
int bigendian(void);

struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
--
1.7.11.7

2013-06-04 05:20:44

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 04/16] tools lib traceevent: Add trace_seq_reset()

From: Namhyung Kim <[email protected]>

Sometimes it'd be useful if existing trace_seq can be reused. But
currently it's impossible since there's no API to reset the trace_seq.
Let's add trace_seq_reset() for this case.

Acked-by: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/event-parse.h | 1 +
tools/lib/traceevent/trace-seq.c | 13 +++++++++++++
2 files changed, 14 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index bfceab948f22..39f0c1dca915 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -69,6 +69,7 @@ struct trace_seq {
};

void trace_seq_init(struct trace_seq *s);
+void trace_seq_reset(struct trace_seq *s);
void trace_seq_destroy(struct trace_seq *s);

extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c
index a57db805136a..d7f2e68bc5b9 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -49,6 +49,19 @@ void trace_seq_init(struct trace_seq *s)
}

/**
+ * trace_seq_reset - re-initialize the trace_seq structure
+ * @s: a pointer to the trace_seq structure to reset
+ */
+void trace_seq_reset(struct trace_seq *s)
+{
+ if (!s)
+ return;
+ TRACE_SEQ_CHECK(s);
+ s->len = 0;
+ s->readpos = 0;
+}
+
+/**
* trace_seq_destroy - free up memory of a trace_seq
* @s: a pointer to the trace_seq to free the buffer
*
--
1.7.11.7

2013-06-04 05:21:13

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 15/16] perf util: No need to call read_trace_init() in tracing_data_header()

From: Namhyung Kim <[email protected]>

It's useless to call the read_trace_init() function at this time as we
don't need a returned pevent and it makes me confusing. :)

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-info.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 9648175e2a1c..e85cbcf298f3 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -520,8 +520,6 @@ static int tracing_data_header(void)
else
buf[0] = 0;

- read_trace_init(buf[0], buf[0]);
-
if (write(output_fd, buf, 1) != 1)
return -1;

--
1.7.11.7

2013-06-04 05:20:39

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 01/16] tools lib traceevent: Remove unused install targets

From: Namhyung Kim <[email protected]>

The html_install, img_install, install_plugin and install_python are
unused in the Makefile. Get rid of them.

Acked-by: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/Makefile | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 0b0a90787db6..fd7510d99583 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -39,13 +39,8 @@ bindir_relative = bin
bindir = $(prefix)/$(bindir_relative)
man_dir = $(prefix)/share/man
man_dir_SQ = '$(subst ','\'',$(man_dir))'
-html_install = $(prefix)/share/kernelshark/html
-html_install_SQ = '$(subst ','\'',$(html_install))'
-img_install = $(prefix)/share/kernelshark/html/images
-img_install_SQ = '$(subst ','\'',$(img_install))'

-export man_dir man_dir_SQ html_install html_install_SQ INSTALL
-export img_install img_install_SQ
+export man_dir man_dir_SQ INSTALL
export DESTDIR DESTDIR_SQ

# copy a bit from Linux kbuild
@@ -300,7 +295,7 @@ define do_install
$(INSTALL) $1 '$(DESTDIR_SQ)$2'
endef

-install_lib: all_cmd install_plugins install_python
+install_lib: all_cmd
$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))

install: install_lib
--
1.7.11.7

2013-06-04 05:21:40

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 13/16] perf util: Move latency_format variable to builtin-script.c

From: Namhyung Kim <[email protected]>

It's the only user of the variable, so move it.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-script.c | 1 +
tools/perf/util/trace-event-parse.c | 2 --
tools/perf/util/trace-event.h | 1 -
3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 92d4658f56fb..3de8979fe87d 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -24,6 +24,7 @@ static u64 last_timestamp;
static u64 nr_unordered;
extern const struct option record_options[];
static bool no_callchain;
+static bool latency_format;
static bool system_wide;
static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 0deae885c7ba..fe7a27d67d2b 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -28,8 +28,6 @@
#include "util.h"
#include "trace-event.h"

-bool latency_format;
-
struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
{
struct pevent *pevent = pevent_alloc();
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 10d6e7b202c5..96ad22f98726 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -10,7 +10,6 @@ struct perf_sample;
union perf_event;
struct perf_tool;

-extern bool latency_format;
extern struct pevent *perf_pevent;

enum {
--
1.7.11.7

2013-06-04 05:21:43

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 11/16] perf util: Parse header_page to get proper long size

From: Namhyung Kim <[email protected]>

The header_page file describes the format of the ring buffer page
which is used by ftrace (not perf). And size of "commit" field (I
guess it's older name was 'size') represents the real size of long
type used for kernel. So update the pevent's long size.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-read.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index fa45fca2a2d3..f2112270c663 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -212,6 +212,7 @@ static int read_ftrace_printk(struct pevent *pevent)
static int read_header_files(struct pevent *pevent)
{
unsigned long long size;
+ char *header_page;
char buf[BUFSIZ];
int ret = 0;

@@ -224,7 +225,26 @@ static int read_header_files(struct pevent *pevent)
}

size = read8(pevent);
- skip(size);
+
+ header_page = malloc(size);
+ if (header_page == NULL)
+ return -1;
+
+ if (do_read(header_page, size) < 0) {
+ pr_debug("did not read header page");
+ free(header_page);
+ return -1;
+ }
+
+ if (!pevent_parse_header_page(pevent, header_page, size,
+ pevent_get_long_size(pevent))) {
+ /*
+ * The commit field in the page is of type long,
+ * use that instead, since it represents the kernel.
+ */
+ pevent_set_long_size(pevent, pevent->header_page_size_size);
+ }
+ free(header_page);

if (do_read(buf, 13) < 0)
return -1;
--
1.7.11.7

2013-06-04 05:21:44

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 12/16] perf util: Get rid of unused header_page_* variables

From: Namhyung Kim <[email protected]>

They're not used anywhere and same information is kept in a pevent
already. So let's get rid of them.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-parse.c | 4 ----
tools/perf/util/trace-event.h | 4 ----
2 files changed, 8 deletions(-)

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 4454835a9ebc..0deae885c7ba 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -28,10 +28,6 @@
#include "util.h"
#include "trace-event.h"

-int header_page_size_size;
-int header_page_ts_size;
-int header_page_data_offset;
-
bool latency_format;

struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 1978c398ad87..10d6e7b202c5 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -10,10 +10,6 @@ struct perf_sample;
union perf_event;
struct perf_tool;

-extern int header_page_size_size;
-extern int header_page_ts_size;
-extern int header_page_data_offset;
-
extern bool latency_format;
extern struct pevent *perf_pevent;

--
1.7.11.7

2013-06-04 05:21:38

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 14/16] perf util: Rename read_*() functions in trace-event-info.c

From: Namhyung Kim <[email protected]>

It's confusing to have same name for two difference functions which
does something opposite way. Since what they do in this file is read
*AND* writing some of tracing metadata files, rename them to
record_*() looks better to me.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-info.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 3917eb9a8479..9648175e2a1c 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -160,7 +160,7 @@ out:
return err;
}

-static int read_header_files(void)
+static int record_header_files(void)
{
char *path;
struct stat st;
@@ -299,7 +299,7 @@ out:
return err;
}

-static int read_ftrace_files(struct tracepoint_path *tps)
+static int record_ftrace_files(struct tracepoint_path *tps)
{
char *path;
int ret;
@@ -328,7 +328,7 @@ static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
return false;
}

-static int read_event_files(struct tracepoint_path *tps)
+static int record_event_files(struct tracepoint_path *tps)
{
struct dirent *dent;
struct stat st;
@@ -403,7 +403,7 @@ out:
return err;
}

-static int read_proc_kallsyms(void)
+static int record_proc_kallsyms(void)
{
unsigned int size;
const char *path = "/proc/kallsyms";
@@ -421,7 +421,7 @@ static int read_proc_kallsyms(void)
return record_file(path, 4);
}

-static int read_ftrace_printk(void)
+static int record_ftrace_printk(void)
{
unsigned int size;
char *path;
@@ -583,19 +583,19 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
err = tracing_data_header();
if (err)
goto out;
- err = read_header_files();
+ err = record_header_files();
if (err)
goto out;
- err = read_ftrace_files(tps);
+ err = record_ftrace_files(tps);
if (err)
goto out;
- err = read_event_files(tps);
+ err = record_event_files(tps);
if (err)
goto out;
- err = read_proc_kallsyms();
+ err = record_proc_kallsyms();
if (err)
goto out;
- err = read_ftrace_printk();
+ err = record_ftrace_printk();

out:
/*
--
1.7.11.7

2013-06-04 05:22:48

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 10/16] perf util: Skip reading header_event file

From: Namhyung Kim <[email protected]>

It seems perf does not parse header_event file so we can skip it as we
do for header_page file.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-read.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 0dd9fbda88eb..fa45fca2a2d3 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -212,7 +212,6 @@ static int read_ftrace_printk(struct pevent *pevent)
static int read_header_files(struct pevent *pevent)
{
unsigned long long size;
- char *header_event;
char buf[BUFSIZ];
int ret = 0;

@@ -236,14 +235,8 @@ static int read_header_files(struct pevent *pevent)
}

size = read8(pevent);
- header_event = malloc(size);
- if (header_event == NULL)
- return -1;
-
- if (do_read(header_event, size) < 0)
- ret = -1;
+ skip(size);

- free(header_event);
return ret;
}

--
1.7.11.7

2013-06-04 05:23:34

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 08/16] perf util: Save long size of traced system

From: Namhyung Kim <[email protected]>

Save size of long type of system to struct pevent. Since original
static variable was not used anywhere, just get rid of it.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-read.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index c6b491bcb8cd..6166294d7f22 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -41,7 +41,6 @@ static int input_fd;

int file_bigendian;
int host_bigendian;
-static int long_size;

static ssize_t trace_data_size;
static bool repipe;
@@ -231,12 +230,6 @@ static int read_header_files(struct pevent *pevent)
size = read8(pevent);
skip(size);

- /*
- * The size field in the page is of type long,
- * use that instead, since it represents the kernel.
- */
- long_size = header_page_size_size;
-
if (do_read(buf, 13) < 0)
return -1;

@@ -349,6 +342,7 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_long_size;
int file_page_size;
struct pevent *pevent;
int err;
@@ -392,12 +386,13 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)

if (do_read(buf, 1) < 0)
goto out;
- long_size = buf[0];
+ file_long_size = buf[0];

file_page_size = read4(pevent);
if (!file_page_size)
goto out;

+ pevent_set_long_size(pevent, file_long_size);
pevent_set_page_size(pevent, file_page_size);

err = read_header_files(pevent);
--
1.7.11.7

2013-06-04 05:23:37

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 06/16] tools lib traceevent: Port kbuffer parser routines

From: Namhyung Kim <[email protected]>

kbuffer code is for parsing ftrace ring-buffer binary data and used
for trace-cmd. Move the code here in order to be used more widely.

Original-patch-by: Steven Rostedt <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/Makefile | 1 +
tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
tools/lib/traceevent/kbuffer.h | 67 ++++
3 files changed, 800 insertions(+)
create mode 100644 tools/lib/traceevent/kbuffer-parse.c
create mode 100644 tools/lib/traceevent/kbuffer.h

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 4505de874929..0794acca46a3 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -181,6 +181,7 @@ $(obj)/%.o: $(src)/%.c
$(Q)$(call do_compile)

PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o
+PEVENT_LIB_OBJS += kbuffer-parse.o

ALL_OBJS = $(PEVENT_LIB_OBJS)

diff --git a/tools/lib/traceevent/kbuffer-parse.c b/tools/lib/traceevent/kbuffer-parse.c
new file mode 100644
index 000000000000..dcc665228c71
--- /dev/null
+++ b/tools/lib/traceevent/kbuffer-parse.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "kbuffer.h"
+
+#define MISSING_EVENTS (1 << 31)
+#define MISSING_STORED (1 << 30)
+
+#define COMMIT_MASK ((1 << 27) - 1)
+
+enum {
+ KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0),
+ KBUFFER_FL_BIG_ENDIAN = (1<<1),
+ KBUFFER_FL_LONG_8 = (1<<2),
+ KBUFFER_FL_OLD_FORMAT = (1<<3),
+};
+
+#define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN)
+
+/** kbuffer
+ * @timestamp - timestamp of current event
+ * @lost_events - # of lost events between this subbuffer and previous
+ * @flags - special flags of the kbuffer
+ * @subbuffer - pointer to the sub-buffer page
+ * @data - pointer to the start of data on the sub-buffer page
+ * @index - index from @data to the @curr event data
+ * @curr - offset from @data to the start of current event
+ * (includes metadata)
+ * @next - offset from @data to the start of next event
+ * @size - The size of data on @data
+ * @start - The offset from @subbuffer where @data lives
+ *
+ * @read_4 - Function to read 4 raw bytes (may swap)
+ * @read_8 - Function to read 8 raw bytes (may swap)
+ * @read_long - Function to read a long word (4 or 8 bytes with needed swap)
+ */
+struct kbuffer {
+ unsigned long long timestamp;
+ long long lost_events;
+ unsigned long flags;
+ void *subbuffer;
+ void *data;
+ unsigned int index;
+ unsigned int curr;
+ unsigned int next;
+ unsigned int size;
+ unsigned int start;
+
+ unsigned int (*read_4)(void *ptr);
+ unsigned long long (*read_8)(void *ptr);
+ unsigned long long (*read_long)(struct kbuffer *kbuf, void *ptr);
+ int (*next_event)(struct kbuffer *kbuf);
+};
+
+static void *zmalloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+static int host_is_bigendian(void)
+{
+ unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
+ unsigned int *ptr;
+
+ ptr = (unsigned int *)str;
+ return *ptr == 0x01020304;
+}
+
+static int do_swap(struct kbuffer *kbuf)
+{
+ return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) &
+ ENDIAN_MASK;
+}
+
+static unsigned long long __read_8(void *ptr)
+{
+ unsigned long long data = *(unsigned long long *)ptr;
+
+ return data;
+}
+
+static unsigned long long __read_8_sw(void *ptr)
+{
+ unsigned long long data = *(unsigned long long *)ptr;
+ unsigned long long swap;
+
+ swap = ((data & 0xffULL) << 56) |
+ ((data & (0xffULL << 8)) << 40) |
+ ((data & (0xffULL << 16)) << 24) |
+ ((data & (0xffULL << 24)) << 8) |
+ ((data & (0xffULL << 32)) >> 8) |
+ ((data & (0xffULL << 40)) >> 24) |
+ ((data & (0xffULL << 48)) >> 40) |
+ ((data & (0xffULL << 56)) >> 56);
+
+ return swap;
+}
+
+static unsigned int __read_4(void *ptr)
+{
+ unsigned int data = *(unsigned int *)ptr;
+
+ return data;
+}
+
+static unsigned int __read_4_sw(void *ptr)
+{
+ unsigned int data = *(unsigned int *)ptr;
+ unsigned int swap;
+
+ swap = ((data & 0xffULL) << 24) |
+ ((data & (0xffULL << 8)) << 8) |
+ ((data & (0xffULL << 16)) >> 8) |
+ ((data & (0xffULL << 24)) >> 24);
+
+ return swap;
+}
+
+static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_8(ptr);
+}
+
+static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_4(ptr);
+}
+
+static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_8(ptr);
+}
+
+static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_4(ptr);
+}
+
+static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_long(kbuf, ptr);
+}
+
+static int calc_index(struct kbuffer *kbuf, void *ptr)
+{
+ return (unsigned long)ptr - (unsigned long)kbuf->data;
+}
+
+static int __next_event(struct kbuffer *kbuf);
+
+/**
+ * kbuffer_alloc - allocat a new kbuffer
+ * @size; enum to denote size of word
+ * @endian: enum to denote endianness
+ *
+ * Allocates and returns a new kbuffer.
+ */
+struct kbuffer *
+kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
+{
+ struct kbuffer *kbuf;
+ int flags = 0;
+
+ switch (size) {
+ case KBUFFER_LSIZE_4:
+ break;
+ case KBUFFER_LSIZE_8:
+ flags |= KBUFFER_FL_LONG_8;
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (endian) {
+ case KBUFFER_ENDIAN_LITTLE:
+ break;
+ case KBUFFER_ENDIAN_BIG:
+ flags |= KBUFFER_FL_BIG_ENDIAN;
+ break;
+ default:
+ return NULL;
+ }
+
+ kbuf = zmalloc(sizeof(*kbuf));
+ if (!kbuf)
+ return NULL;
+
+ kbuf->flags = flags;
+
+ if (host_is_bigendian())
+ kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
+
+ if (do_swap(kbuf)) {
+ kbuf->read_8 = __read_8_sw;
+ kbuf->read_4 = __read_4_sw;
+ } else {
+ kbuf->read_8 = __read_8;
+ kbuf->read_4 = __read_4;
+ }
+
+ if (kbuf->flags & KBUFFER_FL_LONG_8)
+ kbuf->read_long = __read_long_8;
+ else
+ kbuf->read_long = __read_long_4;
+
+ /* May be changed by kbuffer_set_old_format() */
+ kbuf->next_event = __next_event;
+
+ return kbuf;
+}
+
+/** kbuffer_free - free an allocated kbuffer
+ * @kbuf: The kbuffer to free
+ *
+ * Can take NULL as a parameter.
+ */
+void kbuffer_free(struct kbuffer *kbuf)
+{
+ free(kbuf);
+}
+
+static unsigned int type4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 29) & 3;
+ else
+ return type_len_ts & 3;
+}
+
+static unsigned int len4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 27) & 7;
+ else
+ return (type_len_ts >> 2) & 7;
+}
+
+static unsigned int type_len4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 27) & ((1 << 5) - 1);
+ else
+ return type_len_ts & ((1 << 5) - 1);
+}
+
+static unsigned int ts4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return type_len_ts & ((1 << 27) - 1);
+ else
+ return type_len_ts >> 5;
+}
+
+/*
+ * Linux 2.6.30 and earlier (not much ealier) had a different
+ * ring buffer format. It should be obsolete, but we handle it anyway.
+ */
+enum old_ring_buffer_type {
+ OLD_RINGBUF_TYPE_PADDING,
+ OLD_RINGBUF_TYPE_TIME_EXTEND,
+ OLD_RINGBUF_TYPE_TIME_STAMP,
+ OLD_RINGBUF_TYPE_DATA,
+};
+
+static unsigned int old_update_pointers(struct kbuffer *kbuf)
+{
+ unsigned long long extend;
+ unsigned int type_len_ts;
+ unsigned int type;
+ unsigned int len;
+ unsigned int delta;
+ unsigned int length;
+ void *ptr = kbuf->data + kbuf->curr;
+
+ type_len_ts = read_4(kbuf, ptr);
+ ptr += 4;
+
+ type = type4host(kbuf, type_len_ts);
+ len = len4host(kbuf, type_len_ts);
+ delta = ts4host(kbuf, type_len_ts);
+
+ switch (type) {
+ case OLD_RINGBUF_TYPE_PADDING:
+ kbuf->next = kbuf->size;
+ return 0;
+
+ case OLD_RINGBUF_TYPE_TIME_EXTEND:
+ extend = read_4(kbuf, ptr);
+ extend <<= TS_SHIFT;
+ extend += delta;
+ delta = extend;
+ ptr += 4;
+ break;
+
+ case OLD_RINGBUF_TYPE_TIME_STAMP:
+ /* should never happen! */
+ kbuf->curr = kbuf->size;
+ kbuf->next = kbuf->size;
+ kbuf->index = kbuf->size;
+ return -1;
+ default:
+ if (len)
+ length = len * 4;
+ else {
+ length = read_4(kbuf, ptr);
+ length -= 4;
+ ptr += 4;
+ }
+ break;
+ }
+
+ kbuf->timestamp += delta;
+ kbuf->index = calc_index(kbuf, ptr);
+ kbuf->next = kbuf->index + length;
+
+ return type;
+}
+
+static int __old_next_event(struct kbuffer *kbuf)
+{
+ int type;
+
+ do {
+ kbuf->curr = kbuf->next;
+ if (kbuf->next >= kbuf->size)
+ return -1;
+ type = old_update_pointers(kbuf);
+ } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
+
+ return 0;
+}
+
+static unsigned int
+translate_data(struct kbuffer *kbuf, void *data, void **rptr,
+ unsigned long long *delta, int *length)
+{
+ unsigned long long extend;
+ unsigned int type_len_ts;
+ unsigned int type_len;
+
+ type_len_ts = read_4(kbuf, data);
+ data += 4;
+
+ type_len = type_len4host(kbuf, type_len_ts);
+ *delta = ts4host(kbuf, type_len_ts);
+
+ switch (type_len) {
+ case KBUFFER_TYPE_PADDING:
+ *length = read_4(kbuf, data);
+ data += *length;
+ break;
+
+ case KBUFFER_TYPE_TIME_EXTEND:
+ extend = read_4(kbuf, data);
+ data += 4;
+ extend <<= TS_SHIFT;
+ extend += *delta;
+ *delta = extend;
+ *length = 0;
+ break;
+
+ case KBUFFER_TYPE_TIME_STAMP:
+ data += 12;
+ *length = 0;
+ break;
+ case 0:
+ *length = read_4(kbuf, data) - 4;
+ *length = (*length + 3) & ~3;
+ data += 4;
+ break;
+ default:
+ *length = type_len * 4;
+ break;
+ }
+
+ *rptr = data;
+
+ return type_len;
+}
+
+static unsigned int update_pointers(struct kbuffer *kbuf)
+{
+ unsigned long long delta;
+ unsigned int type_len;
+ int length;
+ void *ptr = kbuf->data + kbuf->curr;
+
+ type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
+
+ kbuf->timestamp += delta;
+ kbuf->index = calc_index(kbuf, ptr);
+ kbuf->next = kbuf->index + length;
+
+ return type_len;
+}
+
+/**
+ * kbuffer_translate_data - read raw data to get a record
+ * @swap: Set to 1 if bytes in words need to be swapped when read
+ * @data: The raw data to read
+ * @size: Address to store the size of the event data.
+ *
+ * Returns a pointer to the event data. To determine the entire
+ * record size (record metadata + data) just add the difference between
+ * @data and the returned value to @size.
+ */
+void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
+{
+ unsigned long long delta;
+ struct kbuffer kbuf;
+ int type_len;
+ int length;
+ void *ptr;
+
+ if (swap) {
+ kbuf.read_8 = __read_8_sw;
+ kbuf.read_4 = __read_4_sw;
+ kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
+ } else {
+ kbuf.read_8 = __read_8;
+ kbuf.read_4 = __read_4;
+ kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
+ }
+
+ type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
+ switch (type_len) {
+ case KBUFFER_TYPE_PADDING:
+ case KBUFFER_TYPE_TIME_EXTEND:
+ case KBUFFER_TYPE_TIME_STAMP:
+ return NULL;
+ };
+
+ *size = length;
+
+ return ptr;
+}
+
+static int __next_event(struct kbuffer *kbuf)
+{
+ int type;
+
+ do {
+ kbuf->curr = kbuf->next;
+ if (kbuf->next >= kbuf->size)
+ return -1;
+ type = update_pointers(kbuf);
+ } while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING);
+
+ return 0;
+}
+
+static int next_event(struct kbuffer *kbuf)
+{
+ return kbuf->next_event(kbuf);
+}
+
+/**
+ * kbuffer_next_event - increment the current pointer
+ * @kbuf: The kbuffer to read
+ * @ts: Address to store the next record's timestamp (may be NULL to ignore)
+ *
+ * Increments the pointers into the subbuffer of the kbuffer to point to the
+ * next event so that the next kbuffer_read_event() will return a
+ * new event.
+ *
+ * Returns the data of the next event if a new event exists on the subbuffer,
+ * NULL otherwise.
+ */
+void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
+{
+ int ret;
+
+ if (!kbuf || !kbuf->subbuffer)
+ return NULL;
+
+ ret = next_event(kbuf);
+ if (ret < 0)
+ return NULL;
+
+ if (ts)
+ *ts = kbuf->timestamp;
+
+ return kbuf->data + kbuf->index;
+}
+
+/**
+ * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
+ * @kbuf: The kbuffer to load
+ * @subbuffer: The subbuffer to load into @kbuf.
+ *
+ * Load a new subbuffer (page) into @kbuf. This will reset all
+ * the pointers and update the @kbuf timestamp. The next read will
+ * return the first event on @subbuffer.
+ *
+ * Returns 0 on succes, -1 otherwise.
+ */
+int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
+{
+ unsigned long long flags;
+ void *ptr = subbuffer;
+
+ if (!kbuf || !subbuffer)
+ return -1;
+
+ kbuf->subbuffer = subbuffer;
+
+ kbuf->timestamp = read_8(kbuf, ptr);
+ ptr += 8;
+
+ kbuf->curr = 0;
+
+ if (kbuf->flags & KBUFFER_FL_LONG_8)
+ kbuf->start = 16;
+ else
+ kbuf->start = 12;
+
+ kbuf->data = subbuffer + kbuf->start;
+
+ flags = read_long(kbuf, ptr);
+ kbuf->size = (unsigned int)flags & COMMIT_MASK;
+
+ if (flags & MISSING_EVENTS) {
+ if (flags & MISSING_STORED) {
+ ptr = kbuf->data + kbuf->size;
+ kbuf->lost_events = read_long(kbuf, ptr);
+ } else
+ kbuf->lost_events = -1;
+ } else
+ kbuf->lost_events = 0;
+
+ kbuf->index = 0;
+ kbuf->next = 0;
+
+ next_event(kbuf);
+
+ return 0;
+}
+
+/**
+ * kbuffer_read_event - read the next event in the kbuffer subbuffer
+ * @kbuf: The kbuffer to read from
+ * @ts: The address to store the timestamp of the event (may be NULL to ignore)
+ *
+ * Returns a pointer to the data part of the current event.
+ * NULL if no event is left on the subbuffer.
+ */
+void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
+{
+ if (!kbuf || !kbuf->subbuffer)
+ return NULL;
+
+ if (kbuf->curr >= kbuf->size)
+ return NULL;
+
+ if (ts)
+ *ts = kbuf->timestamp;
+ return kbuf->data + kbuf->index;
+}
+
+/**
+ * kbuffer_timestamp - Return the timestamp of the current event
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the timestamp of the current (next) event.
+ */
+unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
+{
+ return kbuf->timestamp;
+}
+
+/**
+ * kbuffer_read_at_offset - read the event that is at offset
+ * @kbuf: The kbuffer to read from
+ * @offset: The offset into the subbuffer
+ * @ts: The address to store the timestamp of the event (may be NULL to ignore)
+ *
+ * The @offset must be an index from the @kbuf subbuffer beginning.
+ * If @offset is bigger than the stored subbuffer, NULL will be returned.
+ *
+ * Returns the data of the record that is at @offset. Note, @offset does
+ * not need to be the start of the record, the offset just needs to be
+ * in the record (or beginning of it).
+ *
+ * Note, the kbuf timestamp and pointers are updated to the
+ * returned record. That is, kbuffer_read_event() will return the same
+ * data and timestamp, and kbuffer_next_event() will increment from
+ * this record.
+ */
+void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
+ unsigned long long *ts)
+{
+ void *data;
+
+ if (offset < kbuf->start)
+ offset = 0;
+ else
+ offset -= kbuf->start;
+
+ /* Reset the buffer */
+ kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
+
+ while (kbuf->curr < offset) {
+ data = kbuffer_next_event(kbuf, ts);
+ if (!data)
+ break;
+ }
+
+ return data;
+}
+
+/**
+ * kbuffer_subbuffer_size - the size of the loaded subbuffer
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the size of the subbuffer. Note, this size is
+ * where the last event resides. The stored subbuffer may actually be
+ * bigger due to padding and such.
+ */
+int kbuffer_subbuffer_size(struct kbuffer *kbuf)
+{
+ return kbuf->size;
+}
+
+/**
+ * kbuffer_curr_index - Return the index of the record
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the index from the start of the data part of
+ * the subbuffer to the current location. Note this is not
+ * from the start of the subbuffer. An index of zero will
+ * point to the first record. Use kbuffer_curr_offset() for
+ * the actually offset (that can be used by kbuffer_read_at_offset())
+ */
+int kbuffer_curr_index(struct kbuffer *kbuf)
+{
+ return kbuf->curr;
+}
+
+/**
+ * kbuffer_curr_offset - Return the offset of the record
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the offset from the start of the subbuffer to the
+ * current location.
+ */
+int kbuffer_curr_offset(struct kbuffer *kbuf)
+{
+ return kbuf->curr + kbuf->start;
+}
+
+/**
+ * kbuffer_event_size - return the size of the event data
+ * @kbuf: The kbuffer to read
+ *
+ * Returns the size of the event data (the payload not counting
+ * the meta data of the record) of the current event.
+ */
+int kbuffer_event_size(struct kbuffer *kbuf)
+{
+ return kbuf->next - kbuf->index;
+}
+
+/**
+ * kbuffer_curr_size - return the size of the entire record
+ * @kbuf: The kbuffer to read
+ *
+ * Returns the size of the entire record (meta data and payload)
+ * of the current event.
+ */
+int kbuffer_curr_size(struct kbuffer *kbuf)
+{
+ return kbuf->next - kbuf->curr;
+}
+
+/**
+ * kbuffer_missed_events - return the # of missed events from last event.
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the # of missed events (if recorded) before the current
+ * event. Note, only events on the beginning of a subbuffer can
+ * have missed events, all other events within the buffer will be
+ * zero.
+ */
+int kbuffer_missed_events(struct kbuffer *kbuf)
+{
+ /* Only the first event can have missed events */
+ if (kbuf->curr)
+ return 0;
+
+ return kbuf->lost_events;
+}
+
+/**
+ * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
+ * @kbuf: The kbuffer to set
+ *
+ * This is obsolete (or should be). The first kernels to use the
+ * new ring buffer had a slightly different ring buffer format
+ * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
+ * but should not be counted on in the future.
+ */
+void kbuffer_set_old_format(struct kbuffer *kbuf)
+{
+ kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
+
+ kbuf->next_event = __old_next_event;
+}
diff --git a/tools/lib/traceevent/kbuffer.h b/tools/lib/traceevent/kbuffer.h
new file mode 100644
index 000000000000..c831f64b17a0
--- /dev/null
+++ b/tools/lib/traceevent/kbuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#ifndef _KBUFFER_H
+#define _KBUFFER_H
+
+#ifndef TS_SHIFT
+#define TS_SHIFT 27
+#endif
+
+enum kbuffer_endian {
+ KBUFFER_ENDIAN_BIG,
+ KBUFFER_ENDIAN_LITTLE,
+};
+
+enum kbuffer_long_size {
+ KBUFFER_LSIZE_4,
+ KBUFFER_LSIZE_8,
+};
+
+enum {
+ KBUFFER_TYPE_PADDING = 29,
+ KBUFFER_TYPE_TIME_EXTEND = 30,
+ KBUFFER_TYPE_TIME_STAMP = 31,
+};
+
+struct kbuffer;
+
+struct kbuffer *kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian);
+void kbuffer_free(struct kbuffer *kbuf);
+int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer);
+void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts);
+void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts);
+unsigned long long kbuffer_timestamp(struct kbuffer *kbuf);
+
+void *kbuffer_translate_data(int swap, void *data, unsigned int *size);
+
+void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset, unsigned long long *ts);
+
+int kbuffer_curr_index(struct kbuffer *kbuf);
+
+int kbuffer_curr_offset(struct kbuffer *kbuf);
+int kbuffer_curr_size(struct kbuffer *kbuf);
+int kbuffer_event_size(struct kbuffer *kbuf);
+int kbuffer_missed_events(struct kbuffer *kbuf);
+int kbuffer_subbuffer_size(struct kbuffer *kbuf);
+
+void kbuffer_set_old_format(struct kbuffer *kbuf);
+
+#endif /* _K_BUFFER_H */
--
1.7.11.7

2013-06-04 05:23:32

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 09/16] perf util: Make file/host_bigendian variable local

From: Namhyung Kim <[email protected]>

They're not used anywhere, just make them local variables.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-read.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 6166294d7f22..0dd9fbda88eb 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -39,9 +39,6 @@

static int input_fd;

-int file_bigendian;
-int host_bigendian;
-
static ssize_t trace_data_size;
static bool repipe;

@@ -342,6 +339,8 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_bigendian;
+ int host_bigendian;
int file_long_size;
int file_page_size;
struct pevent *pevent;
--
1.7.11.7

2013-06-04 05:24:16

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 07/16] perf util: Save page size in a trace file to pevent

From: Namhyung Kim <[email protected]>

We now have page_size field in struct pevent, save the actual size of
the system.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/trace-event-read.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index af215c0d2379..c6b491bcb8cd 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -349,6 +349,7 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_page_size;
struct pevent *pevent;
int err;

@@ -393,10 +394,12 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
goto out;
long_size = buf[0];

- page_size = read4(pevent);
- if (!page_size)
+ file_page_size = read4(pevent);
+ if (!file_page_size)
goto out;

+ pevent_set_page_size(pevent, file_page_size);
+
err = read_header_files(pevent);
if (err)
goto out;
--
1.7.11.7

2013-06-04 05:24:32

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 05/16] tools lib traceevent: Add page_size field to pevent

From: Namhyung Kim <[email protected]>

The page size of traced system can be different than current system's
because the recorded data file might be analyzed in a different machine.
In this case we should use original page size of traced system when
accessing the data file, so this information needs to be saved.

Cc: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/event-parse.h | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 39f0c1dca915..c37b2026d04a 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -400,6 +400,7 @@ struct pevent {

int cpus;
int long_size;
+ int page_size;

struct cmdline *cmdlines;
struct cmdline_list *cmdlist;
@@ -621,6 +622,16 @@ static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
pevent->long_size = long_size;
}

+static inline int pevent_get_page_size(struct pevent *pevent)
+{
+ return pevent->page_size;
+}
+
+static inline void pevent_set_page_size(struct pevent *pevent, int _page_size)
+{
+ pevent->page_size = _page_size;
+}
+
static inline int pevent_is_file_bigendian(struct pevent *pevent)
{
return pevent->file_bigendian;
--
1.7.11.7

2013-06-04 05:24:48

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 02/16] tools lib traceevent: Get rid of unused gui target

From: Namhyung Kim <[email protected]>

It's came from trace-cmd's kernelshark which is not a part of
libtraceevent.

Acked-by: Steven Rostedt <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/lib/traceevent/Makefile | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index fd7510d99583..4505de874929 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -71,10 +71,7 @@ $(if $(BUILD_OUTPUT),, \

all: sub-make

-gui: force
- $(call build_output, all_cmd)
-
-$(filter-out gui,$(MAKECMDGOALS)): sub-make
+$(MAKECMDGOALS): sub-make

sub-make: force
$(call build_output, $(MAKECMDGOALS))
@@ -253,9 +250,6 @@ define check_deps
$(RM) $@.$$$$
endef

-$(gui_deps): ks_version.h
-$(non_gui_deps): tc_version.h
-
$(all_deps): .%.d: $(src)/%.c
$(Q)$(call check_deps)

--
1.7.11.7

2013-06-06 15:38:00

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 11/16] perf util: Parse header_page to get proper long size

On Tue, Jun 04, 2013 at 02:20:26PM +0900, Namhyung Kim wrote:
> From: Namhyung Kim <[email protected]>
>
> The header_page file describes the format of the ring buffer page
> which is used by ftrace (not perf). And size of "commit" field (I
> guess it's older name was 'size') represents the real size of long
> type used for kernel. So update the pevent's long size.
>
> Signed-off-by: Namhyung Kim <[email protected]>
> ---
> tools/perf/util/trace-event-read.c | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
> index fa45fca2a2d3..f2112270c663 100644
> --- a/tools/perf/util/trace-event-read.c
> +++ b/tools/perf/util/trace-event-read.c
> @@ -212,6 +212,7 @@ static int read_ftrace_printk(struct pevent *pevent)
> static int read_header_files(struct pevent *pevent)
> {
> unsigned long long size;
> + char *header_page;
> char buf[BUFSIZ];
> int ret = 0;
>
> @@ -224,7 +225,26 @@ static int read_header_files(struct pevent *pevent)
> }
>
> size = read8(pevent);
> - skip(size);
> +
> + header_page = malloc(size);
> + if (header_page == NULL)
> + return -1;
> +
> + if (do_read(header_page, size) < 0) {
> + pr_debug("did not read header page");
> + free(header_page);
> + return -1;
> + }
> +
> + if (!pevent_parse_header_page(pevent, header_page, size,
> + pevent_get_long_size(pevent))) {
> + /*
> + * The commit field in the page is of type long,
> + * use that instead, since it represents the kernel.
> + */
> + pevent_set_long_size(pevent, pevent->header_page_size_size);
> + }
> + free(header_page);

any reason why not merge this one with
83ae6eb perf util: Skip reading header_event file

jirka

2013-06-07 08:56:15

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH 11/16] perf util: Parse header_page to get proper long size

Hi Jiri,

On Thu, 6 Jun 2013 17:37:37 +0200, Jiri Olsa wrote:
> On Tue, Jun 04, 2013 at 02:20:26PM +0900, Namhyung Kim wrote:
>> From: Namhyung Kim <[email protected]>
>>
>> The header_page file describes the format of the ring buffer page
>> which is used by ftrace (not perf). And size of "commit" field (I
>> guess it's older name was 'size') represents the real size of long
>> type used for kernel. So update the pevent's long size.
>>
> any reason why not merge this one with
> 83ae6eb perf util: Skip reading header_event file

Just try to keep it doing one thing in a patch. But if you think it'd
better merging it, I'll do it. :)

Thanks,
Namhyung

2013-06-07 09:02:11

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 11/16] perf util: Parse header_page to get proper long size

On Fri, Jun 07, 2013 at 05:56:08PM +0900, Namhyung Kim wrote:
> Hi Jiri,
>
> On Thu, 6 Jun 2013 17:37:37 +0200, Jiri Olsa wrote:
> > On Tue, Jun 04, 2013 at 02:20:26PM +0900, Namhyung Kim wrote:
> >> From: Namhyung Kim <[email protected]>
> >>
> >> The header_page file describes the format of the ring buffer page
> >> which is used by ftrace (not perf). And size of "commit" field (I
> >> guess it's older name was 'size') represents the real size of long
> >> type used for kernel. So update the pevent's long size.
> >>
> > any reason why not merge this one with
> > 83ae6eb perf util: Skip reading header_event file
>
> Just try to keep it doing one thing in a patch. But if you think it'd
> better merging it, I'll do it. :)

nope, just curious if I missed something ;-) it's ok

jirka

2013-06-24 05:54:02

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

Ping!

FYI, I rebased the perf/cleanup branch on top of current acme/perf/core.

Thanks,
Namhyung


2013-06-04 PM 2:20, Namhyung Kim wrote:
> Hello,
>
> This patchset is a resend version of previous work and basis of
> upcoming perf ftrace patchset. Although I saw no issue on this series
> when I posted earlier, it'd be great if Steve or others take a look at
> it again and give comments.
>
> I also updated 'perf/cleanup' branch on my tree at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git
>
> Thanks,
> Namhyung
>
>
> Namhyung Kim (16):
> tools lib traceevent: Remove unused install targets
> tools lib traceevent: Get rid of unused gui target
> tools lib traceevent: Add const qualifier to string arguments
> tools lib traceevent: Add trace_seq_reset()
> tools lib traceevent: Add page_size field to pevent
> tools lib traceevent: Port kbuffer parser routines
> perf util: Save page size in a trace file to pevent
> perf util: Save long size of traced system
> perf util: Make file/host_bigendian variable local
> perf util: Skip reading header_event file
> perf util: Parse header_page to get proper long size
> perf util: Get rid of unused header_page_* variables
> perf util: Move latency_format variable to builtin-script.c
> perf util: Rename read_*() functions in trace-event-info.c
> perf util: No need to call read_trace_init() in tracing_data_header()
> perf util: Remove unused enum and macro in trace-event.h
>
> tools/lib/traceevent/Makefile | 18 +-
> tools/lib/traceevent/event-parse.c | 7 +-
> tools/lib/traceevent/event-parse.h | 15 +-
> tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
> tools/lib/traceevent/kbuffer.h | 67 ++++
> tools/lib/traceevent/trace-seq.c | 13 +
> tools/perf/builtin-script.c | 1 +
> tools/perf/util/trace-event-info.c | 22 +-
> tools/perf/util/trace-event-parse.c | 6 -
> tools/perf/util/trace-event-read.c | 52 ++-
> tools/perf/util/trace-event.h | 15 -
> 11 files changed, 875 insertions(+), 73 deletions(-)
> create mode 100644 tools/lib/traceevent/kbuffer-parse.c
> create mode 100644 tools/lib/traceevent/kbuffer.h
>

2013-07-04 08:39:15

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

Ping!

On Tue, 4 Jun 2013 14:20:15 +0900, Namhyung Kim wrote:
> Hello,
>
> This patchset is a resend version of previous work and basis of
> upcoming perf ftrace patchset. Although I saw no issue on this series
> when I posted earlier, it'd be great if Steve or others take a look at
> it again and give comments.
>
> I also updated 'perf/cleanup' branch on my tree at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git
>
> Thanks,
> Namhyung
>
>
> Namhyung Kim (16):
> tools lib traceevent: Remove unused install targets
> tools lib traceevent: Get rid of unused gui target
> tools lib traceevent: Add const qualifier to string arguments
> tools lib traceevent: Add trace_seq_reset()
> tools lib traceevent: Add page_size field to pevent
> tools lib traceevent: Port kbuffer parser routines
> perf util: Save page size in a trace file to pevent
> perf util: Save long size of traced system
> perf util: Make file/host_bigendian variable local
> perf util: Skip reading header_event file
> perf util: Parse header_page to get proper long size
> perf util: Get rid of unused header_page_* variables
> perf util: Move latency_format variable to builtin-script.c
> perf util: Rename read_*() functions in trace-event-info.c
> perf util: No need to call read_trace_init() in tracing_data_header()
> perf util: Remove unused enum and macro in trace-event.h
>
> tools/lib/traceevent/Makefile | 18 +-
> tools/lib/traceevent/event-parse.c | 7 +-
> tools/lib/traceevent/event-parse.h | 15 +-
> tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
> tools/lib/traceevent/kbuffer.h | 67 ++++
> tools/lib/traceevent/trace-seq.c | 13 +
> tools/perf/builtin-script.c | 1 +
> tools/perf/util/trace-event-info.c | 22 +-
> tools/perf/util/trace-event-parse.c | 6 -
> tools/perf/util/trace-event-read.c | 52 ++-
> tools/perf/util/trace-event.h | 15 -
> 11 files changed, 875 insertions(+), 73 deletions(-)
> create mode 100644 tools/lib/traceevent/kbuffer-parse.c
> create mode 100644 tools/lib/traceevent/kbuffer.h

2013-07-05 13:35:31

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

On Fri, Jul 5, 2013 at 10:16 PM, Arnaldo Carvalho de Melo
<[email protected]> wrote:
> Em Thu, Jul 04, 2013 at 05:39:06PM +0900, Namhyung Kim escreveu:
>> Ping!
>
> Pong, should be processing these today,

Great!

Thanks,
Namhyung

2013-07-05 13:50:42

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

Em Thu, Jul 04, 2013 at 05:39:06PM +0900, Namhyung Kim escreveu:
> Ping!

Pong, should be processing these today,

- Arnaldo

> On Tue, 4 Jun 2013 14:20:15 +0900, Namhyung Kim wrote:
> > Hello,
> >
> > This patchset is a resend version of previous work and basis of
> > upcoming perf ftrace patchset. Although I saw no issue on this series
> > when I posted earlier, it'd be great if Steve or others take a look at
> > it again and give comments.
> >
> > I also updated 'perf/cleanup' branch on my tree at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git
> >
> > Thanks,
> > Namhyung
> >
> >
> > Namhyung Kim (16):
> > tools lib traceevent: Remove unused install targets
> > tools lib traceevent: Get rid of unused gui target
> > tools lib traceevent: Add const qualifier to string arguments
> > tools lib traceevent: Add trace_seq_reset()
> > tools lib traceevent: Add page_size field to pevent
> > tools lib traceevent: Port kbuffer parser routines
> > perf util: Save page size in a trace file to pevent
> > perf util: Save long size of traced system
> > perf util: Make file/host_bigendian variable local
> > perf util: Skip reading header_event file
> > perf util: Parse header_page to get proper long size
> > perf util: Get rid of unused header_page_* variables
> > perf util: Move latency_format variable to builtin-script.c
> > perf util: Rename read_*() functions in trace-event-info.c
> > perf util: No need to call read_trace_init() in tracing_data_header()
> > perf util: Remove unused enum and macro in trace-event.h
> >
> > tools/lib/traceevent/Makefile | 18 +-
> > tools/lib/traceevent/event-parse.c | 7 +-
> > tools/lib/traceevent/event-parse.h | 15 +-
> > tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
> > tools/lib/traceevent/kbuffer.h | 67 ++++
> > tools/lib/traceevent/trace-seq.c | 13 +
> > tools/perf/builtin-script.c | 1 +
> > tools/perf/util/trace-event-info.c | 22 +-
> > tools/perf/util/trace-event-parse.c | 6 -
> > tools/perf/util/trace-event-read.c | 52 ++-
> > tools/perf/util/trace-event.h | 15 -
> > 11 files changed, 875 insertions(+), 73 deletions(-)
> > create mode 100644 tools/lib/traceevent/kbuffer-parse.c
> > create mode 100644 tools/lib/traceevent/kbuffer.h

2013-07-05 14:57:39

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCHSET 00/16] perf tools: Cleanups on tracepoint handling

Em Tue, Jun 04, 2013 at 02:20:15PM +0900, Namhyung Kim escreveu:
> Hello,
>
> This patchset is a resend version of previous work and basis of
> upcoming perf ftrace patchset. Although I saw no issue on this series
> when I posted earlier, it'd be great if Steve or others take a look at
> it again and give comments.

All seems ok, thanks a lot, applied.

- Arnaldo

Subject: [tip:perf/core] tools lib traceevent: Remove unused install targets

Commit-ID: 9f1efa82640b4f06c8f6c847f088c53e4100395c
Gitweb: http://git.kernel.org/tip/9f1efa82640b4f06c8f6c847f088c53e4100395c
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:16 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:07 -0300

tools lib traceevent: Remove unused install targets

The html_install, img_install, install_plugin and install_python are
unused in the Makefile. Get rid of them.

Signed-off-by: Namhyung Kim <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/Makefile | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 0b0a907..fd7510d 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -39,13 +39,8 @@ bindir_relative = bin
bindir = $(prefix)/$(bindir_relative)
man_dir = $(prefix)/share/man
man_dir_SQ = '$(subst ','\'',$(man_dir))'
-html_install = $(prefix)/share/kernelshark/html
-html_install_SQ = '$(subst ','\'',$(html_install))'
-img_install = $(prefix)/share/kernelshark/html/images
-img_install_SQ = '$(subst ','\'',$(img_install))'

-export man_dir man_dir_SQ html_install html_install_SQ INSTALL
-export img_install img_install_SQ
+export man_dir man_dir_SQ INSTALL
export DESTDIR DESTDIR_SQ

# copy a bit from Linux kbuild
@@ -300,7 +295,7 @@ define do_install
$(INSTALL) $1 '$(DESTDIR_SQ)$2'
endef

-install_lib: all_cmd install_plugins install_python
+install_lib: all_cmd
$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))

install: install_lib

Subject: [tip:perf/core] tools lib traceevent: Get rid of unused gui target

Commit-ID: 4ccdf57d46843f5c03e390bdb652c9744e30ee20
Gitweb: http://git.kernel.org/tip/4ccdf57d46843f5c03e390bdb652c9744e30ee20
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:17 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:09 -0300

tools lib traceevent: Get rid of unused gui target

It's came from trace-cmd's kernelshark which is not a part of
libtraceevent.

Signed-off-by: Namhyung Kim <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/Makefile | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index fd7510d..4505de8 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -71,10 +71,7 @@ $(if $(BUILD_OUTPUT),, \

all: sub-make

-gui: force
- $(call build_output, all_cmd)
-
-$(filter-out gui,$(MAKECMDGOALS)): sub-make
+$(MAKECMDGOALS): sub-make

sub-make: force
$(call build_output, $(MAKECMDGOALS))
@@ -253,9 +250,6 @@ define check_deps
$(RM) $@.$$$$
endef

-$(gui_deps): ks_version.h
-$(non_gui_deps): tc_version.h
-
$(all_deps): .%.d: $(src)/%.c
$(Q)$(call check_deps)

Subject: [tip:perf/core] tools lib traceevent: Add trace_seq_reset()

Commit-ID: 6a48aec3a7179b0cdae2339d5a4072214ee6c6fe
Gitweb: http://git.kernel.org/tip/6a48aec3a7179b0cdae2339d5a4072214ee6c6fe
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:19 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:12 -0300

tools lib traceevent: Add trace_seq_reset()

Sometimes it'd be useful if existing trace_seq can be reused. But
currently it's impossible since there's no API to reset the trace_seq.
Let's add trace_seq_reset() for this case.

Signed-off-by: Namhyung Kim <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/event-parse.h | 1 +
tools/lib/traceevent/trace-seq.c | 13 +++++++++++++
2 files changed, 14 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index bfceab9..39f0c1d 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -69,6 +69,7 @@ struct trace_seq {
};

void trace_seq_init(struct trace_seq *s);
+void trace_seq_reset(struct trace_seq *s);
void trace_seq_destroy(struct trace_seq *s);

extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c
index a57db80..d7f2e68 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -49,6 +49,19 @@ void trace_seq_init(struct trace_seq *s)
}

/**
+ * trace_seq_reset - re-initialize the trace_seq structure
+ * @s: a pointer to the trace_seq structure to reset
+ */
+void trace_seq_reset(struct trace_seq *s)
+{
+ if (!s)
+ return;
+ TRACE_SEQ_CHECK(s);
+ s->len = 0;
+ s->readpos = 0;
+}
+
+/**
* trace_seq_destroy - free up memory of a trace_seq
* @s: a pointer to the trace_seq to free the buffer
*

Subject: [tip:perf/core] tools lib traceevent: Add page_size field to pevent

Commit-ID: 012ac692575b1ea6ed930871850584e4c64f1382
Gitweb: http://git.kernel.org/tip/012ac692575b1ea6ed930871850584e4c64f1382
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:20 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:14 -0300

tools lib traceevent: Add page_size field to pevent

The page size of traced system can be different than current system's
because the recorded data file might be analyzed in a different machine.
In this case we should use original page size of traced system when
accessing the data file, so this information needs to be saved.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/event-parse.h | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 39f0c1d..c37b202 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -400,6 +400,7 @@ struct pevent {

int cpus;
int long_size;
+ int page_size;

struct cmdline *cmdlines;
struct cmdline_list *cmdlist;
@@ -621,6 +622,16 @@ static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
pevent->long_size = long_size;
}

+static inline int pevent_get_page_size(struct pevent *pevent)
+{
+ return pevent->page_size;
+}
+
+static inline void pevent_set_page_size(struct pevent *pevent, int _page_size)
+{
+ pevent->page_size = _page_size;
+}
+
static inline int pevent_is_file_bigendian(struct pevent *pevent)
{
return pevent->file_bigendian;

Subject: [tip:perf/core] perf util: Save page size in a trace file to pevent

Commit-ID: 30f36762aab575f2894f7528d91ecd0b6e26e3e4
Gitweb: http://git.kernel.org/tip/30f36762aab575f2894f7528d91ecd0b6e26e3e4
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:22 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:17 -0300

perf util: Save page size in a trace file to pevent

We now have page_size field in struct pevent, save the actual size of
the system.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-read.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index af215c0..c6b491b 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -349,6 +349,7 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_page_size;
struct pevent *pevent;
int err;

@@ -393,10 +394,12 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
goto out;
long_size = buf[0];

- page_size = read4(pevent);
- if (!page_size)
+ file_page_size = read4(pevent);
+ if (!file_page_size)
goto out;

+ pevent_set_page_size(pevent, file_page_size);
+
err = read_header_files(pevent);
if (err)
goto out;

Subject: [tip:perf/core] perf util: Save long size of traced system

Commit-ID: 59657f9c8dd91363f1c94c1f749b33ecf626cfc2
Gitweb: http://git.kernel.org/tip/59657f9c8dd91363f1c94c1f749b33ecf626cfc2
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:23 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:19 -0300

perf util: Save long size of traced system

Save size of long type of system to struct pevent. Since original
static variable was not used anywhere, just get rid of it.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-read.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index c6b491b..6166294 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -41,7 +41,6 @@ static int input_fd;

int file_bigendian;
int host_bigendian;
-static int long_size;

static ssize_t trace_data_size;
static bool repipe;
@@ -231,12 +230,6 @@ static int read_header_files(struct pevent *pevent)
size = read8(pevent);
skip(size);

- /*
- * The size field in the page is of type long,
- * use that instead, since it represents the kernel.
- */
- long_size = header_page_size_size;
-
if (do_read(buf, 13) < 0)
return -1;

@@ -349,6 +342,7 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_long_size;
int file_page_size;
struct pevent *pevent;
int err;
@@ -392,12 +386,13 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)

if (do_read(buf, 1) < 0)
goto out;
- long_size = buf[0];
+ file_long_size = buf[0];

file_page_size = read4(pevent);
if (!file_page_size)
goto out;

+ pevent_set_long_size(pevent, file_long_size);
pevent_set_page_size(pevent, file_page_size);

err = read_header_files(pevent);

Subject: [tip:perf/core] perf util: Make file/ host_bigendian variable local

Commit-ID: 63af28fa167374e470c32570b7c955c4d973dda4
Gitweb: http://git.kernel.org/tip/63af28fa167374e470c32570b7c955c4d973dda4
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:24 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:21 -0300

perf util: Make file/host_bigendian variable local

They're not used anywhere, just make them local variables.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-read.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 6166294..0dd9fbd 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -39,9 +39,6 @@

static int input_fd;

-int file_bigendian;
-int host_bigendian;
-
static ssize_t trace_data_size;
static bool repipe;

@@ -342,6 +339,8 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
int show_funcs = 0;
int show_printk = 0;
ssize_t size = -1;
+ int file_bigendian;
+ int host_bigendian;
int file_long_size;
int file_page_size;
struct pevent *pevent;

Subject: [tip:perf/core] perf util: Skip reading header_event file

Commit-ID: 2b2efc7fb8a3ede936580e870c5f809e491c925c
Gitweb: http://git.kernel.org/tip/2b2efc7fb8a3ede936580e870c5f809e491c925c
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:25 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:23 -0300

perf util: Skip reading header_event file

It seems perf does not parse header_event file so we can skip it as we
do for header_page file.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-read.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 0dd9fbd..fa45fca 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -212,7 +212,6 @@ static int read_ftrace_printk(struct pevent *pevent)
static int read_header_files(struct pevent *pevent)
{
unsigned long long size;
- char *header_event;
char buf[BUFSIZ];
int ret = 0;

@@ -236,14 +235,8 @@ static int read_header_files(struct pevent *pevent)
}

size = read8(pevent);
- header_event = malloc(size);
- if (header_event == NULL)
- return -1;
-
- if (do_read(header_event, size) < 0)
- ret = -1;
+ skip(size);

- free(header_event);
return ret;
}

Subject: [tip:perf/core] perf util: Parse header_page to get proper long size

Commit-ID: 94b4d89e0021fe3e10415feede364a3fccaa2f89
Gitweb: http://git.kernel.org/tip/94b4d89e0021fe3e10415feede364a3fccaa2f89
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:26 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:24 -0300

perf util: Parse header_page to get proper long size

The header_page file describes the format of the ring buffer page
which is used by ftrace (not perf). And size of "commit" field (I
guess it's older name was 'size') represents the real size of long
type used for kernel. So update the pevent's long size.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-read.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index fa45fca..f211227 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -212,6 +212,7 @@ static int read_ftrace_printk(struct pevent *pevent)
static int read_header_files(struct pevent *pevent)
{
unsigned long long size;
+ char *header_page;
char buf[BUFSIZ];
int ret = 0;

@@ -224,7 +225,26 @@ static int read_header_files(struct pevent *pevent)
}

size = read8(pevent);
- skip(size);
+
+ header_page = malloc(size);
+ if (header_page == NULL)
+ return -1;
+
+ if (do_read(header_page, size) < 0) {
+ pr_debug("did not read header page");
+ free(header_page);
+ return -1;
+ }
+
+ if (!pevent_parse_header_page(pevent, header_page, size,
+ pevent_get_long_size(pevent))) {
+ /*
+ * The commit field in the page is of type long,
+ * use that instead, since it represents the kernel.
+ */
+ pevent_set_long_size(pevent, pevent->header_page_size_size);
+ }
+ free(header_page);

if (do_read(buf, 13) < 0)
return -1;

Subject: [tip:perf/core] perf util: Get rid of unused header_page_* variables

Commit-ID: 9515b2eb7670a98fb9bdd8ceeefeea6ffb9f53fc
Gitweb: http://git.kernel.org/tip/9515b2eb7670a98fb9bdd8ceeefeea6ffb9f53fc
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:27 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:26 -0300

perf util: Get rid of unused header_page_* variables

They're not used anywhere and same information is kept in a pevent
already. So let's get rid of them.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-parse.c | 4 ----
tools/perf/util/trace-event.h | 4 ----
2 files changed, 8 deletions(-)

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 4454835..0deae88 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -28,10 +28,6 @@
#include "util.h"
#include "trace-event.h"

-int header_page_size_size;
-int header_page_ts_size;
-int header_page_data_offset;
-
bool latency_format;

struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 11eb7fd..761c484 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -10,10 +10,6 @@ struct perf_sample;
union perf_event;
struct perf_tool;

-extern int header_page_size_size;
-extern int header_page_ts_size;
-extern int header_page_data_offset;
-
extern bool latency_format;
extern struct pevent *perf_pevent;

Subject: [tip:perf/core] perf script: Adopt latency_format variable

Commit-ID: 47390ae2afb6695c56810a9fc74fb930266addd0
Gitweb: http://git.kernel.org/tip/47390ae2afb6695c56810a9fc74fb930266addd0
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:28 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:28 -0300

perf script: Adopt latency_format variable

It's the only user of the variable, so move it.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-script.c | 1 +
tools/perf/util/trace-event-parse.c | 2 --
tools/perf/util/trace-event.h | 1 -
3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 92d4658..3de8979 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -24,6 +24,7 @@ static u64 last_timestamp;
static u64 nr_unordered;
extern const struct option record_options[];
static bool no_callchain;
+static bool latency_format;
static bool system_wide;
static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 0deae88..fe7a27d 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -28,8 +28,6 @@
#include "util.h"
#include "trace-event.h"

-bool latency_format;
-
struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
{
struct pevent *pevent = pevent_alloc();
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 761c484..ed30c9c 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -10,7 +10,6 @@ struct perf_sample;
union perf_event;
struct perf_tool;

-extern bool latency_format;
extern struct pevent *perf_pevent;

enum {

Subject: [tip:perf/core] perf util: Rename read_*() functions in trace-event-info.c

Commit-ID: 077f159d0402ac90a3ea9975f4089a042e0be065
Gitweb: http://git.kernel.org/tip/077f159d0402ac90a3ea9975f4089a042e0be065
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:29 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:30 -0300

perf util: Rename read_*() functions in trace-event-info.c

It's confusing to have same name for two difference functions which does
something opposite way. Since what they do in this file is read *AND*
writing some of tracing metadata files, rename them to record_*() looks
better to me.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-info.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index a42624a..a800f2b 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -101,7 +101,7 @@ out:
return err;
}

-static int read_header_files(void)
+static int record_header_files(void)
{
char *path;
struct stat st;
@@ -240,7 +240,7 @@ out:
return err;
}

-static int read_ftrace_files(struct tracepoint_path *tps)
+static int record_ftrace_files(struct tracepoint_path *tps)
{
char *path;
int ret;
@@ -269,7 +269,7 @@ static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
return false;
}

-static int read_event_files(struct tracepoint_path *tps)
+static int record_event_files(struct tracepoint_path *tps)
{
struct dirent *dent;
struct stat st;
@@ -344,7 +344,7 @@ out:
return err;
}

-static int read_proc_kallsyms(void)
+static int record_proc_kallsyms(void)
{
unsigned int size;
const char *path = "/proc/kallsyms";
@@ -362,7 +362,7 @@ static int read_proc_kallsyms(void)
return record_file(path, 4);
}

-static int read_ftrace_printk(void)
+static int record_ftrace_printk(void)
{
unsigned int size;
char *path;
@@ -539,19 +539,19 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
err = tracing_data_header();
if (err)
goto out;
- err = read_header_files();
+ err = record_header_files();
if (err)
goto out;
- err = read_ftrace_files(tps);
+ err = record_ftrace_files(tps);
if (err)
goto out;
- err = read_event_files(tps);
+ err = record_event_files(tps);
if (err)
goto out;
- err = read_proc_kallsyms();
+ err = record_proc_kallsyms();
if (err)
goto out;
- err = read_ftrace_printk();
+ err = record_ftrace_printk();

out:
/*

Subject: [tip:perf/core] perf util: No need to call read_trace_init() in tracing_data_header()

Commit-ID: cfd0e8cf7fe7ad6f6c08e23ca4410bd718eeaf0b
Gitweb: http://git.kernel.org/tip/cfd0e8cf7fe7ad6f6c08e23ca4410bd718eeaf0b
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:30 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:31 -0300

perf util: No need to call read_trace_init() in tracing_data_header()

It's useless to call the read_trace_init() function at this time as we
don't need a returned pevent and it makes me confusing. :)

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event-info.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index a800f2b..f3c9e55 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -476,8 +476,6 @@ static int tracing_data_header(void)
else
buf[0] = 0;

- read_trace_init(buf[0], buf[0]);
-
if (write(output_fd, buf, 1) != 1)
return -1;

Subject: [tip:perf/core] perf util: Remove unused enum and macro in trace-event.h

Commit-ID: 45a9ee1b3fa2d8c3fb7a0c7e5a7b77281a4239a6
Gitweb: http://git.kernel.org/tip/45a9ee1b3fa2d8c3fb7a0c7e5a7b77281a4239a6
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:31 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:33 -0300

perf util: Remove unused enum and macro in trace-event.h

They're internals of ftrace ring-buffer and not used in perf code
directly. As it now resides on libtraceevent/kbuffer.h, just get rid of
them.

Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/trace-event.h | 10 ----------
1 file changed, 10 deletions(-)

diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index ed30c9c..669a64a 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -12,16 +12,6 @@ struct perf_tool;

extern struct pevent *perf_pevent;

-enum {
- RINGBUF_TYPE_PADDING = 29,
- RINGBUF_TYPE_TIME_EXTEND = 30,
- RINGBUF_TYPE_TIME_STAMP = 31,
-};
-
-#ifndef TS_SHIFT
-#define TS_SHIFT 27
-#endif
-
int bigendian(void);

struct pevent *read_trace_init(int file_bigendian, int host_bigendian);

Subject: [tip:perf/core] tools lib traceevent: Port kbuffer parser routines

Commit-ID: d6c25223f6067c6889d8fc3f9576d34bbac161b0
Gitweb: http://git.kernel.org/tip/d6c25223f6067c6889d8fc3f9576d34bbac161b0
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:21 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:16 -0300

tools lib traceevent: Port kbuffer parser routines

kbuffer code is for parsing ftrace ring-buffer binary data and used
for trace-cmd. Move the code here in order to be used more widely.

Signed-off-by: Namhyung Kim <[email protected]>
Original-patch-by: Steven Rostedt <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/Makefile | 1 +
tools/lib/traceevent/kbuffer-parse.c | 732 +++++++++++++++++++++++++++++++++++
tools/lib/traceevent/kbuffer.h | 67 ++++
3 files changed, 800 insertions(+)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 4505de8..0794acc 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -181,6 +181,7 @@ $(obj)/%.o: $(src)/%.c
$(Q)$(call do_compile)

PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o
+PEVENT_LIB_OBJS += kbuffer-parse.o

ALL_OBJS = $(PEVENT_LIB_OBJS)

diff --git a/tools/lib/traceevent/kbuffer-parse.c b/tools/lib/traceevent/kbuffer-parse.c
new file mode 100644
index 0000000..dcc6652
--- /dev/null
+++ b/tools/lib/traceevent/kbuffer-parse.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "kbuffer.h"
+
+#define MISSING_EVENTS (1 << 31)
+#define MISSING_STORED (1 << 30)
+
+#define COMMIT_MASK ((1 << 27) - 1)
+
+enum {
+ KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0),
+ KBUFFER_FL_BIG_ENDIAN = (1<<1),
+ KBUFFER_FL_LONG_8 = (1<<2),
+ KBUFFER_FL_OLD_FORMAT = (1<<3),
+};
+
+#define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN)
+
+/** kbuffer
+ * @timestamp - timestamp of current event
+ * @lost_events - # of lost events between this subbuffer and previous
+ * @flags - special flags of the kbuffer
+ * @subbuffer - pointer to the sub-buffer page
+ * @data - pointer to the start of data on the sub-buffer page
+ * @index - index from @data to the @curr event data
+ * @curr - offset from @data to the start of current event
+ * (includes metadata)
+ * @next - offset from @data to the start of next event
+ * @size - The size of data on @data
+ * @start - The offset from @subbuffer where @data lives
+ *
+ * @read_4 - Function to read 4 raw bytes (may swap)
+ * @read_8 - Function to read 8 raw bytes (may swap)
+ * @read_long - Function to read a long word (4 or 8 bytes with needed swap)
+ */
+struct kbuffer {
+ unsigned long long timestamp;
+ long long lost_events;
+ unsigned long flags;
+ void *subbuffer;
+ void *data;
+ unsigned int index;
+ unsigned int curr;
+ unsigned int next;
+ unsigned int size;
+ unsigned int start;
+
+ unsigned int (*read_4)(void *ptr);
+ unsigned long long (*read_8)(void *ptr);
+ unsigned long long (*read_long)(struct kbuffer *kbuf, void *ptr);
+ int (*next_event)(struct kbuffer *kbuf);
+};
+
+static void *zmalloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+static int host_is_bigendian(void)
+{
+ unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
+ unsigned int *ptr;
+
+ ptr = (unsigned int *)str;
+ return *ptr == 0x01020304;
+}
+
+static int do_swap(struct kbuffer *kbuf)
+{
+ return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) &
+ ENDIAN_MASK;
+}
+
+static unsigned long long __read_8(void *ptr)
+{
+ unsigned long long data = *(unsigned long long *)ptr;
+
+ return data;
+}
+
+static unsigned long long __read_8_sw(void *ptr)
+{
+ unsigned long long data = *(unsigned long long *)ptr;
+ unsigned long long swap;
+
+ swap = ((data & 0xffULL) << 56) |
+ ((data & (0xffULL << 8)) << 40) |
+ ((data & (0xffULL << 16)) << 24) |
+ ((data & (0xffULL << 24)) << 8) |
+ ((data & (0xffULL << 32)) >> 8) |
+ ((data & (0xffULL << 40)) >> 24) |
+ ((data & (0xffULL << 48)) >> 40) |
+ ((data & (0xffULL << 56)) >> 56);
+
+ return swap;
+}
+
+static unsigned int __read_4(void *ptr)
+{
+ unsigned int data = *(unsigned int *)ptr;
+
+ return data;
+}
+
+static unsigned int __read_4_sw(void *ptr)
+{
+ unsigned int data = *(unsigned int *)ptr;
+ unsigned int swap;
+
+ swap = ((data & 0xffULL) << 24) |
+ ((data & (0xffULL << 8)) << 8) |
+ ((data & (0xffULL << 16)) >> 8) |
+ ((data & (0xffULL << 24)) >> 24);
+
+ return swap;
+}
+
+static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_8(ptr);
+}
+
+static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_4(ptr);
+}
+
+static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_8(ptr);
+}
+
+static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_4(ptr);
+}
+
+static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
+{
+ return kbuf->read_long(kbuf, ptr);
+}
+
+static int calc_index(struct kbuffer *kbuf, void *ptr)
+{
+ return (unsigned long)ptr - (unsigned long)kbuf->data;
+}
+
+static int __next_event(struct kbuffer *kbuf);
+
+/**
+ * kbuffer_alloc - allocat a new kbuffer
+ * @size; enum to denote size of word
+ * @endian: enum to denote endianness
+ *
+ * Allocates and returns a new kbuffer.
+ */
+struct kbuffer *
+kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
+{
+ struct kbuffer *kbuf;
+ int flags = 0;
+
+ switch (size) {
+ case KBUFFER_LSIZE_4:
+ break;
+ case KBUFFER_LSIZE_8:
+ flags |= KBUFFER_FL_LONG_8;
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (endian) {
+ case KBUFFER_ENDIAN_LITTLE:
+ break;
+ case KBUFFER_ENDIAN_BIG:
+ flags |= KBUFFER_FL_BIG_ENDIAN;
+ break;
+ default:
+ return NULL;
+ }
+
+ kbuf = zmalloc(sizeof(*kbuf));
+ if (!kbuf)
+ return NULL;
+
+ kbuf->flags = flags;
+
+ if (host_is_bigendian())
+ kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
+
+ if (do_swap(kbuf)) {
+ kbuf->read_8 = __read_8_sw;
+ kbuf->read_4 = __read_4_sw;
+ } else {
+ kbuf->read_8 = __read_8;
+ kbuf->read_4 = __read_4;
+ }
+
+ if (kbuf->flags & KBUFFER_FL_LONG_8)
+ kbuf->read_long = __read_long_8;
+ else
+ kbuf->read_long = __read_long_4;
+
+ /* May be changed by kbuffer_set_old_format() */
+ kbuf->next_event = __next_event;
+
+ return kbuf;
+}
+
+/** kbuffer_free - free an allocated kbuffer
+ * @kbuf: The kbuffer to free
+ *
+ * Can take NULL as a parameter.
+ */
+void kbuffer_free(struct kbuffer *kbuf)
+{
+ free(kbuf);
+}
+
+static unsigned int type4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 29) & 3;
+ else
+ return type_len_ts & 3;
+}
+
+static unsigned int len4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 27) & 7;
+ else
+ return (type_len_ts >> 2) & 7;
+}
+
+static unsigned int type_len4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return (type_len_ts >> 27) & ((1 << 5) - 1);
+ else
+ return type_len_ts & ((1 << 5) - 1);
+}
+
+static unsigned int ts4host(struct kbuffer *kbuf,
+ unsigned int type_len_ts)
+{
+ if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
+ return type_len_ts & ((1 << 27) - 1);
+ else
+ return type_len_ts >> 5;
+}
+
+/*
+ * Linux 2.6.30 and earlier (not much ealier) had a different
+ * ring buffer format. It should be obsolete, but we handle it anyway.
+ */
+enum old_ring_buffer_type {
+ OLD_RINGBUF_TYPE_PADDING,
+ OLD_RINGBUF_TYPE_TIME_EXTEND,
+ OLD_RINGBUF_TYPE_TIME_STAMP,
+ OLD_RINGBUF_TYPE_DATA,
+};
+
+static unsigned int old_update_pointers(struct kbuffer *kbuf)
+{
+ unsigned long long extend;
+ unsigned int type_len_ts;
+ unsigned int type;
+ unsigned int len;
+ unsigned int delta;
+ unsigned int length;
+ void *ptr = kbuf->data + kbuf->curr;
+
+ type_len_ts = read_4(kbuf, ptr);
+ ptr += 4;
+
+ type = type4host(kbuf, type_len_ts);
+ len = len4host(kbuf, type_len_ts);
+ delta = ts4host(kbuf, type_len_ts);
+
+ switch (type) {
+ case OLD_RINGBUF_TYPE_PADDING:
+ kbuf->next = kbuf->size;
+ return 0;
+
+ case OLD_RINGBUF_TYPE_TIME_EXTEND:
+ extend = read_4(kbuf, ptr);
+ extend <<= TS_SHIFT;
+ extend += delta;
+ delta = extend;
+ ptr += 4;
+ break;
+
+ case OLD_RINGBUF_TYPE_TIME_STAMP:
+ /* should never happen! */
+ kbuf->curr = kbuf->size;
+ kbuf->next = kbuf->size;
+ kbuf->index = kbuf->size;
+ return -1;
+ default:
+ if (len)
+ length = len * 4;
+ else {
+ length = read_4(kbuf, ptr);
+ length -= 4;
+ ptr += 4;
+ }
+ break;
+ }
+
+ kbuf->timestamp += delta;
+ kbuf->index = calc_index(kbuf, ptr);
+ kbuf->next = kbuf->index + length;
+
+ return type;
+}
+
+static int __old_next_event(struct kbuffer *kbuf)
+{
+ int type;
+
+ do {
+ kbuf->curr = kbuf->next;
+ if (kbuf->next >= kbuf->size)
+ return -1;
+ type = old_update_pointers(kbuf);
+ } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
+
+ return 0;
+}
+
+static unsigned int
+translate_data(struct kbuffer *kbuf, void *data, void **rptr,
+ unsigned long long *delta, int *length)
+{
+ unsigned long long extend;
+ unsigned int type_len_ts;
+ unsigned int type_len;
+
+ type_len_ts = read_4(kbuf, data);
+ data += 4;
+
+ type_len = type_len4host(kbuf, type_len_ts);
+ *delta = ts4host(kbuf, type_len_ts);
+
+ switch (type_len) {
+ case KBUFFER_TYPE_PADDING:
+ *length = read_4(kbuf, data);
+ data += *length;
+ break;
+
+ case KBUFFER_TYPE_TIME_EXTEND:
+ extend = read_4(kbuf, data);
+ data += 4;
+ extend <<= TS_SHIFT;
+ extend += *delta;
+ *delta = extend;
+ *length = 0;
+ break;
+
+ case KBUFFER_TYPE_TIME_STAMP:
+ data += 12;
+ *length = 0;
+ break;
+ case 0:
+ *length = read_4(kbuf, data) - 4;
+ *length = (*length + 3) & ~3;
+ data += 4;
+ break;
+ default:
+ *length = type_len * 4;
+ break;
+ }
+
+ *rptr = data;
+
+ return type_len;
+}
+
+static unsigned int update_pointers(struct kbuffer *kbuf)
+{
+ unsigned long long delta;
+ unsigned int type_len;
+ int length;
+ void *ptr = kbuf->data + kbuf->curr;
+
+ type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
+
+ kbuf->timestamp += delta;
+ kbuf->index = calc_index(kbuf, ptr);
+ kbuf->next = kbuf->index + length;
+
+ return type_len;
+}
+
+/**
+ * kbuffer_translate_data - read raw data to get a record
+ * @swap: Set to 1 if bytes in words need to be swapped when read
+ * @data: The raw data to read
+ * @size: Address to store the size of the event data.
+ *
+ * Returns a pointer to the event data. To determine the entire
+ * record size (record metadata + data) just add the difference between
+ * @data and the returned value to @size.
+ */
+void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
+{
+ unsigned long long delta;
+ struct kbuffer kbuf;
+ int type_len;
+ int length;
+ void *ptr;
+
+ if (swap) {
+ kbuf.read_8 = __read_8_sw;
+ kbuf.read_4 = __read_4_sw;
+ kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
+ } else {
+ kbuf.read_8 = __read_8;
+ kbuf.read_4 = __read_4;
+ kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
+ }
+
+ type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
+ switch (type_len) {
+ case KBUFFER_TYPE_PADDING:
+ case KBUFFER_TYPE_TIME_EXTEND:
+ case KBUFFER_TYPE_TIME_STAMP:
+ return NULL;
+ };
+
+ *size = length;
+
+ return ptr;
+}
+
+static int __next_event(struct kbuffer *kbuf)
+{
+ int type;
+
+ do {
+ kbuf->curr = kbuf->next;
+ if (kbuf->next >= kbuf->size)
+ return -1;
+ type = update_pointers(kbuf);
+ } while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING);
+
+ return 0;
+}
+
+static int next_event(struct kbuffer *kbuf)
+{
+ return kbuf->next_event(kbuf);
+}
+
+/**
+ * kbuffer_next_event - increment the current pointer
+ * @kbuf: The kbuffer to read
+ * @ts: Address to store the next record's timestamp (may be NULL to ignore)
+ *
+ * Increments the pointers into the subbuffer of the kbuffer to point to the
+ * next event so that the next kbuffer_read_event() will return a
+ * new event.
+ *
+ * Returns the data of the next event if a new event exists on the subbuffer,
+ * NULL otherwise.
+ */
+void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
+{
+ int ret;
+
+ if (!kbuf || !kbuf->subbuffer)
+ return NULL;
+
+ ret = next_event(kbuf);
+ if (ret < 0)
+ return NULL;
+
+ if (ts)
+ *ts = kbuf->timestamp;
+
+ return kbuf->data + kbuf->index;
+}
+
+/**
+ * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
+ * @kbuf: The kbuffer to load
+ * @subbuffer: The subbuffer to load into @kbuf.
+ *
+ * Load a new subbuffer (page) into @kbuf. This will reset all
+ * the pointers and update the @kbuf timestamp. The next read will
+ * return the first event on @subbuffer.
+ *
+ * Returns 0 on succes, -1 otherwise.
+ */
+int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
+{
+ unsigned long long flags;
+ void *ptr = subbuffer;
+
+ if (!kbuf || !subbuffer)
+ return -1;
+
+ kbuf->subbuffer = subbuffer;
+
+ kbuf->timestamp = read_8(kbuf, ptr);
+ ptr += 8;
+
+ kbuf->curr = 0;
+
+ if (kbuf->flags & KBUFFER_FL_LONG_8)
+ kbuf->start = 16;
+ else
+ kbuf->start = 12;
+
+ kbuf->data = subbuffer + kbuf->start;
+
+ flags = read_long(kbuf, ptr);
+ kbuf->size = (unsigned int)flags & COMMIT_MASK;
+
+ if (flags & MISSING_EVENTS) {
+ if (flags & MISSING_STORED) {
+ ptr = kbuf->data + kbuf->size;
+ kbuf->lost_events = read_long(kbuf, ptr);
+ } else
+ kbuf->lost_events = -1;
+ } else
+ kbuf->lost_events = 0;
+
+ kbuf->index = 0;
+ kbuf->next = 0;
+
+ next_event(kbuf);
+
+ return 0;
+}
+
+/**
+ * kbuffer_read_event - read the next event in the kbuffer subbuffer
+ * @kbuf: The kbuffer to read from
+ * @ts: The address to store the timestamp of the event (may be NULL to ignore)
+ *
+ * Returns a pointer to the data part of the current event.
+ * NULL if no event is left on the subbuffer.
+ */
+void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
+{
+ if (!kbuf || !kbuf->subbuffer)
+ return NULL;
+
+ if (kbuf->curr >= kbuf->size)
+ return NULL;
+
+ if (ts)
+ *ts = kbuf->timestamp;
+ return kbuf->data + kbuf->index;
+}
+
+/**
+ * kbuffer_timestamp - Return the timestamp of the current event
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the timestamp of the current (next) event.
+ */
+unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
+{
+ return kbuf->timestamp;
+}
+
+/**
+ * kbuffer_read_at_offset - read the event that is at offset
+ * @kbuf: The kbuffer to read from
+ * @offset: The offset into the subbuffer
+ * @ts: The address to store the timestamp of the event (may be NULL to ignore)
+ *
+ * The @offset must be an index from the @kbuf subbuffer beginning.
+ * If @offset is bigger than the stored subbuffer, NULL will be returned.
+ *
+ * Returns the data of the record that is at @offset. Note, @offset does
+ * not need to be the start of the record, the offset just needs to be
+ * in the record (or beginning of it).
+ *
+ * Note, the kbuf timestamp and pointers are updated to the
+ * returned record. That is, kbuffer_read_event() will return the same
+ * data and timestamp, and kbuffer_next_event() will increment from
+ * this record.
+ */
+void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
+ unsigned long long *ts)
+{
+ void *data;
+
+ if (offset < kbuf->start)
+ offset = 0;
+ else
+ offset -= kbuf->start;
+
+ /* Reset the buffer */
+ kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
+
+ while (kbuf->curr < offset) {
+ data = kbuffer_next_event(kbuf, ts);
+ if (!data)
+ break;
+ }
+
+ return data;
+}
+
+/**
+ * kbuffer_subbuffer_size - the size of the loaded subbuffer
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the size of the subbuffer. Note, this size is
+ * where the last event resides. The stored subbuffer may actually be
+ * bigger due to padding and such.
+ */
+int kbuffer_subbuffer_size(struct kbuffer *kbuf)
+{
+ return kbuf->size;
+}
+
+/**
+ * kbuffer_curr_index - Return the index of the record
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the index from the start of the data part of
+ * the subbuffer to the current location. Note this is not
+ * from the start of the subbuffer. An index of zero will
+ * point to the first record. Use kbuffer_curr_offset() for
+ * the actually offset (that can be used by kbuffer_read_at_offset())
+ */
+int kbuffer_curr_index(struct kbuffer *kbuf)
+{
+ return kbuf->curr;
+}
+
+/**
+ * kbuffer_curr_offset - Return the offset of the record
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the offset from the start of the subbuffer to the
+ * current location.
+ */
+int kbuffer_curr_offset(struct kbuffer *kbuf)
+{
+ return kbuf->curr + kbuf->start;
+}
+
+/**
+ * kbuffer_event_size - return the size of the event data
+ * @kbuf: The kbuffer to read
+ *
+ * Returns the size of the event data (the payload not counting
+ * the meta data of the record) of the current event.
+ */
+int kbuffer_event_size(struct kbuffer *kbuf)
+{
+ return kbuf->next - kbuf->index;
+}
+
+/**
+ * kbuffer_curr_size - return the size of the entire record
+ * @kbuf: The kbuffer to read
+ *
+ * Returns the size of the entire record (meta data and payload)
+ * of the current event.
+ */
+int kbuffer_curr_size(struct kbuffer *kbuf)
+{
+ return kbuf->next - kbuf->curr;
+}
+
+/**
+ * kbuffer_missed_events - return the # of missed events from last event.
+ * @kbuf: The kbuffer to read from
+ *
+ * Returns the # of missed events (if recorded) before the current
+ * event. Note, only events on the beginning of a subbuffer can
+ * have missed events, all other events within the buffer will be
+ * zero.
+ */
+int kbuffer_missed_events(struct kbuffer *kbuf)
+{
+ /* Only the first event can have missed events */
+ if (kbuf->curr)
+ return 0;
+
+ return kbuf->lost_events;
+}
+
+/**
+ * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
+ * @kbuf: The kbuffer to set
+ *
+ * This is obsolete (or should be). The first kernels to use the
+ * new ring buffer had a slightly different ring buffer format
+ * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
+ * but should not be counted on in the future.
+ */
+void kbuffer_set_old_format(struct kbuffer *kbuf)
+{
+ kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
+
+ kbuf->next_event = __old_next_event;
+}
diff --git a/tools/lib/traceevent/kbuffer.h b/tools/lib/traceevent/kbuffer.h
new file mode 100644
index 0000000..c831f64
--- /dev/null
+++ b/tools/lib/traceevent/kbuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#ifndef _KBUFFER_H
+#define _KBUFFER_H
+
+#ifndef TS_SHIFT
+#define TS_SHIFT 27
+#endif
+
+enum kbuffer_endian {
+ KBUFFER_ENDIAN_BIG,
+ KBUFFER_ENDIAN_LITTLE,
+};
+
+enum kbuffer_long_size {
+ KBUFFER_LSIZE_4,
+ KBUFFER_LSIZE_8,
+};
+
+enum {
+ KBUFFER_TYPE_PADDING = 29,
+ KBUFFER_TYPE_TIME_EXTEND = 30,
+ KBUFFER_TYPE_TIME_STAMP = 31,
+};
+
+struct kbuffer;
+
+struct kbuffer *kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian);
+void kbuffer_free(struct kbuffer *kbuf);
+int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer);
+void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts);
+void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts);
+unsigned long long kbuffer_timestamp(struct kbuffer *kbuf);
+
+void *kbuffer_translate_data(int swap, void *data, unsigned int *size);
+
+void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset, unsigned long long *ts);
+
+int kbuffer_curr_index(struct kbuffer *kbuf);
+
+int kbuffer_curr_offset(struct kbuffer *kbuf);
+int kbuffer_curr_size(struct kbuffer *kbuf);
+int kbuffer_event_size(struct kbuffer *kbuf);
+int kbuffer_missed_events(struct kbuffer *kbuf);
+int kbuffer_subbuffer_size(struct kbuffer *kbuf);
+
+void kbuffer_set_old_format(struct kbuffer *kbuf);
+
+#endif /* _K_BUFFER_H */

Subject: [tip:perf/core] tools lib traceevent: Add const qualifier to string arguments

Commit-ID: 79d5adf06dd530fe6a9ab3d086b2d23eb7560491
Gitweb: http://git.kernel.org/tip/79d5adf06dd530fe6a9ab3d086b2d23eb7560491
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 4 Jun 2013 14:20:18 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 12 Jul 2013 13:52:11 -0300

tools lib traceevent: Add const qualifier to string arguments

If pevent_register_event_handler() received a string literal as
@sys_name or @event_name parameter, it emitted a warning about const
qualifier removal. Since they're not modified in the function we can
make it have const qualifier.

Signed-off-by: Namhyung Kim <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/lib/traceevent/event-parse.c | 7 +++----
tools/lib/traceevent/event-parse.h | 3 ++-
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 82b0606..d1c2a6a 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5450,10 +5450,9 @@ int pevent_register_print_function(struct pevent *pevent,
* If @id is >= 0, then it is used to find the event.
* else @sys_name and @event_name are used.
*/
-int pevent_register_event_handler(struct pevent *pevent,
- int id, char *sys_name, char *event_name,
- pevent_event_handler_func func,
- void *context)
+int pevent_register_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
+ pevent_event_handler_func func, void *context)
{
struct event_format *event;
struct event_handler *handle;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 7be7e89..bfceab9 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -561,7 +561,8 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
struct pevent_record *record, int err);

-int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
+int pevent_register_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
pevent_event_handler_func func, void *context);
int pevent_register_print_function(struct pevent *pevent,
pevent_func_handler func,