public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/24] perf tools: Add traceevent plugins support
@ 2013-09-01 10:48 Jiri Olsa
  2013-09-01 10:48 ` [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule Jiri Olsa
                   ` (24 more replies)
  0 siblings, 25 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

hi,
backporting traceevent plugin support from trace-cmd.

Having plugins allow traceevent to properly parse
'print fmt' line of tracepoint format and display
proper/additional data in perf script command, like:

- displaying call_site details in kmem:* tracepoints:
  $ sudo perf record -e kmem:kmalloc ls

  before:
  ls 31708 [003] 15123.850504: kmem:kmalloc: call_site=ffffffff812030eb ptr=0xffff8801cbb91840 bytes_req=40 bytes_alloc=64 gfp_
  ls 31708 [003] 15123.850506: kmem:kmalloc: call_site=ffffffff811be761 ptr=0xffff8801cbbddd20 bytes_req=32 bytes_alloc=32 gfp_
  ls 31708 [003] 15123.850507: kmem:kmalloc: call_site=ffffffff811be6ab ptr=0xffff880163bf1800 bytes_req=112 bytes_alloc=128 gf
  ls 31708 [003] 15123.850535: kmem:kmalloc: call_site=ffffffff811bed5e ptr=0xffff88017d41b000 bytes_req=4096 bytes_alloc=4096 
  ls 31708 [003] 15123.850691: kmem:kmalloc: call_site=ffffffff81128333 ptr=0xffff88020eedc000 bytes_req=4104 bytes_alloc=8192 
  ls 31708 [003] 15123.850838: kmem:kmalloc: call_site=ffffffff8121c28e ptr=0xffff8801cb981940 bytes_req=48 bytes_alloc=64 gfp_
  ls 31708 [003] 15123.850848: kmem:kmalloc: call_site=ffffffff8121c418 ptr=0xffff8801cb916bc0 bytes_req=50 bytes_alloc=64 gfp_
  ls 31708 [003] 15123.850850: kmem:kmalloc: call_site=ffffffff8121c418 ptr=0xffff8801cb916b40 bytes_req=51 bytes_alloc=64 gfp_

  now:
  $ sudo perf script
  ...
  ls 30512 [001] 14717.425867: kmem:kmalloc: (perf_event_mmap+0xf3) call_site=ffffffff81128333 ptr=0xffff880211cea000 bytes_req
  ls 30512 [001] 14717.425981: kmem:kmalloc: (proc_reg_open+0x4b) call_site=ffffffff812030eb ptr=0xffff88017de85a40 bytes_req=4
  ls 30512 [001] 14717.425982: kmem:kmalloc: (single_open+0x41) call_site=ffffffff811be761 ptr=0xffff8801958e1e00 bytes_req=32 
  ls 30512 [001] 14717.425982: kmem:kmalloc: (seq_open+0xfb) call_site=ffffffff811be6ab ptr=0xffff880211d88f00 bytes_req=112 by
  ls 30512 [001] 14717.425989: kmem:kmalloc: (seq_read+0x2ee) call_site=ffffffff811bed5e ptr=0xffff88017be8c000 bytes_req=4096 
  ls 30512 [001] 14717.426034: kmem:kmalloc: (perf_event_mmap+0xf3) call_site=ffffffff81128333 ptr=0xffff880211cea000 bytes_req
  ls 30512 [001] 14717.426079: kmem:kmalloc: (ext4_readdir+0x6fe) call_site=ffffffff8121c28e ptr=0xffff88017de85f00 bytes_req=4
  ls 30512 [001] 14717.426081: kmem:kmalloc: (ext4_htree_store_dirent+0x38) call_site=ffffffff8121c418 ptr=0xffff88017de85080 b
  ...

- displaying details for timer_expire_entry and hrtimer_start tracepoints:

  $ sudo perf record -e timer:* ls

  before:
  ls 31727 [001] 15171.487282: timer:hrtimer_cancel: hrtimer=0xffff88021e24e4c0
  ls 31727 [001] 15171.487284: timer:hrtimer_expire_entry: [FAILED TO PARSE] hrtimer=0xffff88021e24e4c0 now=15167505000662 func
  ls 31727 [001] 15171.487290: timer:hrtimer_expire_exit: hrtimer=0xffff88021e24e4c0
  ls 31727 [001] 15171.487290: timer:hrtimer_start: [FAILED TO PARSE] hrtimer=0xffff88021e24e4c0 function=0xffffffff810b6460 ex

  now:
  $ sudo perf script
  ..
  ls 30557 [001] 14855.443889: timer:hrtimer_cancel: hrtimer=0xffff88021e24e4c0
  ls 30557 [001] 14855.443891: timer:hrtimer_expire_entry: hrtimer=0xffff88021e24e4c0 now=14851544000735 function=tick_sched_timer/0x0
  ls 30557 [001] 14855.443897: timer:hrtimer_expire_exit: hrtimer=0xffff88021e24e4c0
  ls 30557 [001] 14855.443897: timer:hrtimer_start: hrtimer=0xffff88021e24e4c0 function=tick_sched_timer expires=14851545000000 softexpires=14851545000000
  ls 30557 [001] 14855.443899: timer:timer_cancel: timer=0xffff88021e250b68
  ls 30557 [001] 14855.443900: timer:timer_expire_entry: timer=0xffff88021e250b68 function=delayed_work_timer_fn now=4309518840
  ls 30557 [001] 14855.443903: timer:timer_expire_exit: timer=0xffff88021e250b68
  ls 30557 [001] 14855.444888: timer:hrtimer_cancel: hrtimer=0xffff88021e24e4c0
  ls 30557 [001] 14855.444889: timer:hrtimer_expire_entry: hrtimer=0xffff88021e24e4c0 now=14851545000598 function=tick_sched_timer/0x0
  ...


All plugins present in trace-cmd are backported plus
added new scsi and xen. The 'xen' plugin still cannot
handle all the 'print fmt' functions, since I dont follow
xen code ;-) Also xen tracepoints use 'sizeof' in the
format string and it's not clear yet how to handle that.

Plugins get installed to following locations:
  '$(HOME)/.traceevent/plugins'
   - if no prefix is provided
  '$(perfexecdir)/traceevent/plugins'
   - if prefix is provided

thanks for comments,
jirka


Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
Jiri Olsa (24):
      perf tools: Fix 'make install prefix=...' build rule
      perf tools: Remove unused trace-event-* code
      perf tools: Unify page_size usage
      tools list traceevent: Add plugin support
      tools list traceevent: Add options support
      tools list traceevent: Add plugin build support
      tools list traceevent: Add traceevent_host_bigendian function
      tools list traceevent: Add pevent_print_func_field function
      tools list traceevent: Add jbd2 plugin
      tools list traceevent: Add blk plugin
      tools list traceevent: Add hrtimer plugin
      tools list traceevent: Add kmem plugin
      tools list traceevent: Add kvm plugin
      tools list traceevent: Add mac80211 plugin
      tools list traceevent: Add sched_switch plugin
      tools list traceevent: Add function plugin
      tools list traceevent: Update kvm plugin with is_writable_pte helper
      tools list traceevent: Add xen plugin
      tools list traceevent: Add scsi plugin
      tools list traceevent: Change pevent_parse_event to return event format
      perf tools: Add traceevents Makefile install rule
      perf tools: Add trace-event object
      perf tools: Add traceevent object to interface traceevent lib
      perf tools: Overload pr_stat traceevent print function

 tools/lib/traceevent/Makefile              |  57 +++++++++--
 tools/lib/traceevent/event-option.c        | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/event-parse.c         |  70 +++++++++----
 tools/lib/traceevent/event-parse.h         |  29 +++++-
 tools/lib/traceevent/event-plugin.c        | 202 +++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_blk.c          | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_function.c     | 182 +++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_hrtimer.c      |  94 ++++++++++++++++++
 tools/lib/traceevent/plugin_jbd2.c         |  68 +++++++++++++
 tools/lib/traceevent/plugin_kmem.c         |  76 ++++++++++++++
 tools/lib/traceevent/plugin_kvm.c          | 480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_mac80211.c     | 204 +++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_sched_switch.c | 147 +++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_scsi.c         | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/plugin_xen.c          | 132 ++++++++++++++++++++++++
 tools/perf/Makefile                        |  13 ++-
 tools/perf/builtin-record.c                |   5 +-
 tools/perf/builtin-script.c                |   2 +-
 tools/perf/builtin-trace.c                 |   5 +-
 tools/perf/config/Makefile                 |   4 +-
 tools/perf/perf.c                          |   1 +
 tools/perf/util/debug.c                    |  16 +++
 tools/perf/util/debug.h                    |   2 +
 tools/perf/util/evsel.c                    |  44 +-------
 tools/perf/util/header.c                   |   8 +-
 tools/perf/util/python-ext-sources         |   1 +
 tools/perf/util/python.c                   |   1 +
 tools/perf/util/session.c                  |   2 +-
 tools/perf/util/session.h                  |   3 +-
 tools/perf/util/trace-event-parse.c        |  53 +---------
 tools/perf/util/trace-event-read.c         |  20 ++--
 tools/perf/util/trace-event.c              | 121 ++++++++++++++++++++++
 tools/perf/util/trace-event.h              |  22 ++--
 33 files changed, 3002 insertions(+), 160 deletions(-)
 create mode 100644 tools/lib/traceevent/event-option.c
 create mode 100644 tools/lib/traceevent/event-plugin.c
 create mode 100644 tools/lib/traceevent/plugin_blk.c
 create mode 100644 tools/lib/traceevent/plugin_function.c
 create mode 100644 tools/lib/traceevent/plugin_hrtimer.c
 create mode 100644 tools/lib/traceevent/plugin_jbd2.c
 create mode 100644 tools/lib/traceevent/plugin_kmem.c
 create mode 100644 tools/lib/traceevent/plugin_kvm.c
 create mode 100644 tools/lib/traceevent/plugin_mac80211.c
 create mode 100644 tools/lib/traceevent/plugin_sched_switch.c
 create mode 100644 tools/lib/traceevent/plugin_scsi.c
 create mode 100644 tools/lib/traceevent/plugin_xen.c
 create mode 100644 tools/perf/util/trace-event.c

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-04  8:35   ` Namhyung Kim
  2013-09-01 10:48 ` [PATCH 02/24] perf tools: Remove unused trace-event-* code Jiri Olsa
                   ` (23 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Currently we fail for following make command:

  $ sudo make install prefix=/opt/perf
  ...
      GEN python/perf.so
  install -d -m 755 '/opt/perf/bin'
  install perf '/opt/perf/bin'
  install perf-archive -t '/opt/perf/libexec/perf-core'
  install: accessing `/opt/perf/libexec/perf-core': No such file or directory
  make: *** [install-bin] Error 1

Fixing this by properly creating '/opt/perf/libexec/perf-core'
directory.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index ecebfd0..f5998da 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -768,6 +768,7 @@ check: $(OUTPUT)common-cmds.h
 install-bin: all
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
 	$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
+	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 ifndef NO_LIBPERL
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/24] perf tools: Remove unused trace-event-* code
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
  2013-09-01 10:48 ` [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-04  8:36   ` Namhyung Kim
  2013-09-01 10:48 ` [PATCH 03/24] perf tools: Unify page_size usage Jiri Olsa
                   ` (22 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Removing unused trace-event-* code.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/trace-event-parse.c | 36 ------------------------------------
 tools/perf/util/trace-event.h       |  9 ---------
 2 files changed, 45 deletions(-)

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index fe7a27d..da28065 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -120,42 +120,6 @@ raw_field_value(struct event_format *event, const char *name, void *data)
 	return val;
 }
 
-void *raw_field_ptr(struct event_format *event, const char *name, void *data)
-{
-	struct format_field *field;
-
-	field = pevent_find_any_field(event, name);
-	if (!field)
-		return NULL;
-
-	if (field->flags & FIELD_IS_DYNAMIC) {
-		int offset;
-
-		offset = *(int *)(data + field->offset);
-		offset &= 0xffff;
-
-		return data + offset;
-	}
-
-	return data + field->offset;
-}
-
-int trace_parse_common_type(struct pevent *pevent, void *data)
-{
-	struct pevent_record record;
-
-	record.data = data;
-	return pevent_data_type(pevent, &record);
-}
-
-int trace_parse_common_pid(struct pevent *pevent, void *data)
-{
-	struct pevent_record record;
-
-	record.data = data;
-	return pevent_data_pid(pevent, &record);
-}
-
 unsigned long long read_size(struct event_format *event, void *ptr, int size)
 {
 	return pevent_read_number(event->pevent, ptr, size);
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index fafe1a4..04df631 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -11,8 +11,6 @@ union perf_event;
 struct perf_tool;
 struct thread;
 
-extern struct pevent *perf_pevent;
-
 int bigendian(void);
 
 struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
@@ -23,26 +21,19 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
 int parse_event_file(struct pevent *pevent,
 		     char *buf, unsigned long size, char *sys);
 
-struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu);
-
 unsigned long long
 raw_field_value(struct event_format *event, const char *name, void *data);
-void *raw_field_ptr(struct event_format *event, const char *name, void *data);
 
 void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
 void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
 
 ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
 
-int trace_parse_common_type(struct pevent *pevent, void *data);
-int trace_parse_common_pid(struct pevent *pevent, void *data);
-
 struct event_format *trace_find_next_event(struct pevent *pevent,
 					   struct event_format *event);
 unsigned long long read_size(struct event_format *event, void *ptr, int size);
 unsigned long long eval_flag(const char *flag);
 
-struct pevent_record *trace_read_data(struct pevent *pevent, int cpu);
 int read_tracing_data(int fd, struct list_head *pattrs);
 
 struct tracing_data {
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/24] perf tools: Unify page_size usage
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
  2013-09-01 10:48 ` [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule Jiri Olsa
  2013-09-01 10:48 ` [PATCH 02/24] perf tools: Remove unused trace-event-* code Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-04  8:37   ` Namhyung Kim
  2013-09-01 10:48 ` [PATCH 04/24] tools list traceevent: Add plugin support Jiri Olsa
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Making page_size global from the util object.
Removing the not needed one.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/builtin-record.c | 5 +----
 tools/perf/perf.c           | 1 +
 tools/perf/util/python.c    | 1 +
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a41ac415..ceea545 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -70,7 +70,6 @@ struct perf_record {
 	struct perf_session	*session;
 	const char		*progname;
 	int			output;
-	unsigned int		page_size;
 	int			realtime_prio;
 	bool			no_buildid;
 	bool			no_buildid_cache;
@@ -119,7 +118,7 @@ static int perf_record__mmap_read(struct perf_record *rec,
 {
 	unsigned int head = perf_mmap__read_head(md);
 	unsigned int old = md->prev;
-	unsigned char *data = md->base + rec->page_size;
+	unsigned char *data = md->base + page_size;
 	unsigned long size;
 	void *buf;
 	int rc = 0;
@@ -360,8 +359,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 
 	rec->progname = argv[0];
 
-	rec->page_size = sysconf(_SC_PAGE_SIZE);
-
 	on_exit(perf_record__sig_exit, rec);
 	signal(SIGCHLD, sig_handler);
 	signal(SIGINT, sig_handler);
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 85e1aed..6f0a209 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -456,6 +456,7 @@ int main(int argc, const char **argv)
 {
 	const char *cmd;
 
+	/* The page_size is placed in util object. */
 	page_size = sysconf(_SC_PAGE_SIZE);
 
 	cmd = perf_extract_argv0_path(argv[0]);
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 381f4fd..c00d83b 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1035,6 +1035,7 @@ PyMODINIT_FUNC initperf(void)
 	    pyrf_cpu_map__setup_types() < 0)
 		return;
 
+	/* The page_size is placed in util object. */
 	page_size = sysconf(_SC_PAGE_SIZE);
 
 	Py_INCREF(&pyrf_evlist__type);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/24] tools list traceevent: Add plugin support
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (2 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 03/24] perf tools: Unify page_size usage Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-16  3:37   ` David Ahern
  2013-09-01 10:48 ` [PATCH 05/24] tools list traceevent: Add options support Jiri Olsa
                   ` (20 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting plugin support for traceevent lib.

It's now possible to use following interface
to load plugins for 'struct pevent' object:

struct plugin_list*
traceevent_load_plugins(struct pevent *pevent)
  - loads plusing for 'struct pevent' object and returns
    loaded plugins list

void traceevent_unload_plugins(struct plugin_list *plugin_list);
  - unload plugin list

Adding -ldl dependency for perf which is needed
due to plugins support.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile       |   2 +-
 tools/lib/traceevent/event-parse.h  |   5 +
 tools/lib/traceevent/event-plugin.c | 202 ++++++++++++++++++++++++++++++++++++
 tools/perf/config/Makefile          |   2 +-
 4 files changed, 209 insertions(+), 2 deletions(-)
 create mode 100644 tools/lib/traceevent/event-plugin.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index ca6cb77..539f3e5 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -180,7 +180,7 @@ $(obj)/%.o: $(src)/%.c
 %.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 = event-parse.o event-plugin.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/event-parse.h b/tools/lib/traceevent/event-parse.h
index c37b202..8273c6e 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -374,6 +374,11 @@ enum pevent_errno {
 };
 #undef _PE
 
+struct plugin_list;
+
+struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
+void traceevent_unload_plugins(struct plugin_list *plugin_list);
+
 struct cmdline;
 struct cmdline_list;
 struct func_map;
diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
new file mode 100644
index 0000000..d272d87
--- /dev/null
+++ b/tools/lib/traceevent/event-plugin.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <string.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include "event-parse.h"
+#include "event-utils.h"
+
+#define LOCAL_PLUGIN_DIR ".traceevent/plugins"
+
+struct plugin_list {
+	struct plugin_list	*next;
+	char			*name;
+	void			*handle;
+};
+
+static void
+load_plugin(struct pevent *pevent, const char *path,
+	    const char *file, void *data)
+{
+	struct plugin_list **plugin_list = data;
+	pevent_plugin_load_func func;
+	struct plugin_list *list;
+	const char *alias;
+	char *plugin;
+	void *handle;
+
+	plugin = malloc_or_die(strlen(path) + strlen(file) + 2);
+
+	strcpy(plugin, path);
+	strcat(plugin, "/");
+	strcat(plugin, file);
+
+	handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
+	if (!handle) {
+		warning("could not load plugin '%s'\n%s\n",
+			plugin, dlerror());
+		goto out_free;
+	}
+
+	alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
+	if (!alias)
+		alias = file;
+
+	func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
+	if (!func) {
+		warning("could not find func '%s' in plugin '%s'\n%s\n",
+			PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
+		goto out_free;
+	}
+
+	list = malloc_or_die(sizeof(*list));
+	list->next = *plugin_list;
+	list->handle = handle;
+	list->name = plugin;
+	*plugin_list = list;
+
+	pr_stat("registering plugin: %s", plugin);
+	func(pevent);
+	return;
+
+ out_free:
+	free(plugin);
+}
+
+static void
+load_plugins_dir(struct pevent *pevent, const char *suffix,
+		 const char *path,
+		 void (*load_plugin)(struct pevent *pevent,
+				     const char *path,
+				     const char *name,
+				     void *data),
+		 void *data)
+{
+	struct dirent *dent;
+	struct stat st;
+	DIR *dir;
+	int ret;
+
+	ret = stat(path, &st);
+	if (ret < 0)
+		return;
+
+	if (!S_ISDIR(st.st_mode))
+		return;
+
+	dir = opendir(path);
+	if (!dir)
+		return;
+
+	while ((dent = readdir(dir))) {
+		const char *name = dent->d_name;
+
+		if (strcmp(name, ".") == 0 ||
+		    strcmp(name, "..") == 0)
+			continue;
+
+		/* Only load plugins that end in suffix */
+		if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0)
+			continue;
+
+		load_plugin(pevent, path, name, data);
+	}
+
+	closedir(dir);
+}
+
+static void
+load_plugins(struct pevent *pevent, const char *suffix,
+	     void (*load_plugin)(struct pevent *pevent,
+				 const char *path,
+				 const char *name,
+				 void *data),
+	     void *data)
+{
+	char *home;
+	char *path;
+	char *envdir;
+
+	/*
+	 * If a system plugin directory was defined,
+	 * check that first.
+	 */
+#ifdef PLUGIN_DIR
+	load_plugins_dir(pevent, suffix, PLUGIN_DIR, load_plugin, data);
+#endif
+
+	/*
+	 * Next let the environment-set plugin directory
+	 * override the system defaults.
+	 */
+	envdir = getenv("TRACEEVENT_PLUGIN_DIR");
+	if (envdir)
+		load_plugins_dir(pevent, suffix, envdir, load_plugin, data);
+
+	/*
+	 * Now let the home directory override the environment
+	 * or system defaults.
+	 */
+	home = getenv("HOME");
+	if (!home)
+		return;
+
+	path = malloc_or_die(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2);
+
+	strcpy(path, home);
+	strcat(path, "/");
+	strcat(path, LOCAL_PLUGIN_DIR);
+
+	load_plugins_dir(pevent, suffix, path, load_plugin, data);
+
+	free(path);
+}
+
+struct plugin_list*
+traceevent_load_plugins(struct pevent *pevent)
+{
+	struct plugin_list *list = NULL;
+
+	load_plugins(pevent, ".so", load_plugin, &list);
+	return list;
+}
+
+void
+traceevent_unload_plugins(struct plugin_list *plugin_list)
+{
+	pevent_plugin_unload_func func;
+	struct plugin_list *list;
+
+	while (plugin_list) {
+		list = plugin_list;
+		plugin_list = list->next;
+		func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
+		if (func)
+			func();
+		dlclose(list->handle);
+		free(list->name);
+		free(list);
+	}
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 214e17e..f6d720d 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -87,7 +87,7 @@ CFLAGS += -Wall
 CFLAGS += -Wextra
 CFLAGS += -std=gnu99
 
-EXTLIBS = -lelf -lpthread -lrt -lm
+EXTLIBS = -lelf -lpthread -lrt -lm -ldl
 
 ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
   CFLAGS += -fstack-protector-all
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/24] tools list traceevent: Add options support
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (3 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 04/24] tools list traceevent: Add plugin support Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-16  3:40   ` David Ahern
  2013-09-01 10:48 ` [PATCH 06/24] tools list traceevent: Add plugin build support Jiri Olsa
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting options support for traceevent lib.

It's now possible to use following interface
to load options for 'struct pevent' object:

void traceevent_add_options(const char *name, struct plugin_option *options);
  - adds a set of options by a plugin

void traceevent_remove_options(struct plugin_option *options);
  - removes plugin options that were registered

void traceevent_add_option(const char *name, const char *val);
  - modifies plugin option

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile       |   2 +-
 tools/lib/traceevent/event-option.c | 278 ++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/event-parse.h  |   4 +
 3 files changed, 283 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/event-option.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 539f3e5..99da843 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -180,7 +180,7 @@ $(obj)/%.o: $(src)/%.c
 %.o: $(src)/%.c
 	$(Q)$(call do_compile)
 
-PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o
+PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
 ALL_OBJS = $(PEVENT_LIB_OBJS)
diff --git a/tools/lib/traceevent/event-option.c b/tools/lib/traceevent/event-option.c
new file mode 100644
index 0000000..61181be
--- /dev/null
+++ b/tools/lib/traceevent/event-option.c
@@ -0,0 +1,278 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include "event-parse.h"
+#include "event-utils.h"
+
+static struct trace_plugin_options {
+	struct trace_plugin_options	*next;
+	char				*plugin;
+	char				*option;
+	char				*value;
+} *trace_plugin_options;
+
+static struct registered_plugin_options {
+	struct registered_plugin_options	*next;
+	struct plugin_option			*options;
+} *registered_options;
+
+static void update_option(const char *file, struct plugin_option *option)
+{
+	struct trace_plugin_options *op;
+	char *plugin;
+
+	if (option->plugin_alias) {
+		plugin = strdup(option->plugin_alias);
+		if (!plugin)
+			die("malloc");
+	} else {
+		char *p;
+		plugin = strdup(file);
+		if (!plugin)
+			die("malloc");
+		p = strstr(plugin, ".");
+		if (p)
+			*p = '\0';
+	}
+
+	/* first look for named options */
+	for (op = trace_plugin_options; op; op = op->next) {
+		if (!op->plugin)
+			continue;
+		if (strcmp(op->plugin, plugin) != 0)
+			continue;
+		if (strcmp(op->option, option->name) != 0)
+			continue;
+
+		option->value = op->value;
+		option->set ^= 1;
+		goto out;
+	}
+
+	/* first look for unnamed options */
+	for (op = trace_plugin_options; op; op = op->next) {
+		if (op->plugin)
+			continue;
+		if (strcmp(op->option, option->name) != 0)
+			continue;
+
+		option->value = op->value;
+		option->set ^= 1;
+		break;
+	}
+
+ out:
+	free(plugin);
+}
+
+/**
+ * trace_util_add_options - Add a set of options by a plugin
+ * @name: The name of the plugin adding the options
+ * @options: The set of options being loaded
+ *
+ * Sets the options with the values that have been added by user.
+ */
+void traceevent_add_options(const char *name, struct plugin_option *options)
+{
+	struct registered_plugin_options *reg;
+
+	reg = malloc_or_die(sizeof(*reg));
+	reg->next = registered_options;
+	reg->options = options;
+	registered_options = reg;
+
+	while (options->name) {
+		update_option("ftrace", options);
+		options++;
+	}
+}
+
+/**
+ * trace_util_remove_options - remove plugin options that were registered
+ * @options: Options to removed that were registered with trace_util_add_options
+ */
+void traceevent_remove_options(struct plugin_option *options)
+{
+	struct registered_plugin_options **last;
+	struct registered_plugin_options *reg;
+
+	for (last = &registered_options; *last; last = &(*last)->next) {
+		if ((*last)->options == options) {
+			reg = *last;
+			*last = reg->next;
+			free(reg);
+			return;
+		}
+	}
+}
+
+static struct plugin_option *
+find_registered_option(const char *plugin, const char *option)
+{
+	struct registered_plugin_options *reg;
+	struct plugin_option *op;
+	const char *op_plugin;
+
+	for (reg = registered_options; reg; reg = reg->next) {
+		for (op = reg->options; op->name; op++) {
+			if (op->plugin_alias)
+				op_plugin = op->plugin_alias;
+			else
+				op_plugin = op->file;
+
+			if (plugin && strcmp(plugin, op_plugin) != 0)
+				continue;
+			if (strcmp(option, op->name) != 0)
+				continue;
+
+			return op;
+		}
+	}
+
+	return NULL;
+}
+
+static void lower_case(char *str)
+{
+	if (!str)
+		return;
+	for (; *str; str++)
+		*str = tolower(*str);
+}
+
+static int update_option_value(struct plugin_option *op, const char *val)
+{
+	char *op_val;
+	int ret = 1;
+
+	if (!val) {
+		/* toggle, only if option is boolean */
+		if (op->value)
+			/* Warn? */
+			return 0;
+		op->set ^= 1;
+		return 1;
+	}
+
+	/*
+	 * If the option has a value then it takes a string
+	 * otherwise the option is a boolean.
+	 */
+	if (op->value) {
+		op->value = (char *) val;
+		return 1;
+	}
+
+	/* Option is boolean, must be either "1", "0", "true" or "false" */
+
+	op_val = strdup(val);
+	if (!op_val)
+		die("malloc");
+	lower_case(op_val);
+
+	if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0)
+		op->set = 1;
+	else if (strcmp(val, "0") == 0 || strcmp(val, "false") == 0)
+		op->set = 0;
+	else
+		/* Warn on else? */
+		ret = 0;
+	free(op_val);
+
+	return ret;
+}
+
+static int process_option(const char *plugin, const char *option, const char *val)
+{
+	struct plugin_option *op;
+
+	op = find_registered_option(plugin, option);
+	if (!op)
+		return 0;
+
+	return update_option_value(op, val);
+}
+
+static void parse_option_name(char **option, char **plugin)
+{
+	char *p;
+
+	*plugin = NULL;
+
+	if ((p = strstr(*option, ":"))) {
+		*plugin = *option;
+		*p = '\0';
+		*option = strdup(p + 1);
+		if (!*option)
+			die("malloc");
+	}
+}
+
+/**
+ * trace_util_add_option - add an option/val pair to set plugin options
+ * @name: The name of the option (format: <plugin>:<option> or just <option>)
+ * @val: (optiona) the value for the option
+ *
+ * Modify a plugin option. If @val is given than the value of the option
+ * is set (note, some options just take a boolean, so @val must be either
+ * "1" or "0" or "true" or "false").
+ */
+void traceevent_add_option(const char *name, const char *val)
+{
+	struct trace_plugin_options *op;
+	char *option_str;
+	char *plugin;
+
+	option_str = strdup(name);
+	if (!option_str)
+		die("malloc");
+
+	parse_option_name(&option_str, &plugin);
+
+	/* If the option exists, update the val */
+	for (op = trace_plugin_options; op; op = op->next) {
+		/* Both must be NULL or not NULL */
+		if ((!plugin || !op->plugin) && plugin != op->plugin)
+			continue;
+		if (plugin && strcmp(plugin, op->plugin) != 0)
+			continue;
+		if (strcmp(op->option, option_str) != 0)
+			continue;
+
+		/* update option */
+		free(op->value);
+		if (val) {
+			op->value = strdup(val);
+			if (!op->value)
+				die("malloc");
+		} else
+			op->value = NULL;
+
+		/* plugin and option_str don't get freed at the end */
+		free(plugin);
+		free(option_str);
+
+		plugin = op->plugin;
+		option_str = op->option;
+		break;
+	}
+
+	/* If not found, create */
+	if (!op) {
+		op = malloc_or_die(sizeof(*op));
+		memset(op, 0, sizeof(*op));
+		op->next = trace_plugin_options;
+		trace_plugin_options = op;
+
+		op->plugin = plugin;
+		op->option = option_str;
+
+		if (val) {
+			op->value = strdup(val);
+			if (!op->value)
+				die("malloc");
+		}
+	}
+
+	process_option(plugin, option_str, val);
+}
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 8273c6e..3aaf668 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -110,6 +110,10 @@ struct plugin_option {
 	int				set;
 };
 
+void traceevent_add_options(const char *name, struct plugin_option *options);
+void traceevent_remove_options(struct plugin_option *options);
+void traceevent_add_option(const char *name, const char *val);
+
 /*
  * Plugin hooks that can be called:
  *
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/24] tools list traceevent: Add plugin build support
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (4 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 05/24] tools list traceevent: Add options support Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 07/24] tools list traceevent: Add traceevent_host_bigendian function Jiri Olsa
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting missing pieces of plugin building infrastructure.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 99da843..19bde02 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -43,6 +43,17 @@ man_dir_SQ = '$(subst ','\'',$(man_dir))'
 export man_dir man_dir_SQ INSTALL
 export DESTDIR DESTDIR_SQ
 
+# Set plugin_dir to preffered global plugin location
+# If we install under $HOME directory we go under
+# $(HOME)/.traceevent/plugins
+ifeq ($(prefix),$(HOME))
+override plugin_dir = $(HOME)/.traceevent/plugins
+else
+override plugin_dir ?= $(prefix)/lib/traceevent/plugins
+PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
+PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
+endif
+
 # copy a bit from Linux kbuild
 
 ifeq ("$(origin V)", "command line")
@@ -96,6 +107,7 @@ export prefix bindir src obj
 # Shell quotes
 bindir_SQ = $(subst ','\'',$(bindir))
 bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
+plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
 
 LIB_FILE = libtraceevent.a libtraceevent.so
 
@@ -139,7 +151,7 @@ else
   print_fpic_compile =		echo '  CC FPIC            '$(OBJ);
   print_shared_lib_compile =	echo '  BUILD SHARED LIB   '$(OBJ);
   print_plugin_obj_compile =	echo '  CC PLUGIN OBJ      '$(OBJ);
-  print_plugin_build =		echo '  CC PLUGI           '$(OBJ);
+  print_plugin_build =		echo '  BUILD PLUGIN       '$(OBJ);
   print_static_lib_build =	echo '  BUILD STATIC LIB   '$(OBJ);
   print_install =		echo '  INSTALL     '$1'	to	$(DESTDIR_SQ)$2';
 endif
@@ -183,9 +195,11 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-ALL_OBJS = $(PEVENT_LIB_OBJS)
+PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
-CMD_TARGETS = $(LIB_FILE)
+ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS)
+
+CMD_TARGETS = $(LIB_FILE) $(PLUGINS)
 
 TARGETS = $(CMD_TARGETS)
 
@@ -200,9 +214,17 @@ libtraceevent.so: $(PEVENT_LIB_OBJS)
 libtraceevent.a: $(PEVENT_LIB_OBJS)
 	$(Q)$(do_build_static_lib)
 
+plugins: $(PLUGINS)
+
 $(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS
 	$(Q)$(do_fpic_compile)
 
+$(PLUGIN_OBJS): %.o : $(src)/%.c
+	$(Q)$(do_compile_plugin_obj)
+
+$(PLUGINS): %.so: %.o
+	$(Q)$(do_plugin_build)
+
 define make_version.h
 	(echo '/* This file is automatically generated. Do not modify. */';		\
 	echo \#define VERSION_CODE $(shell						\
@@ -290,9 +312,16 @@ define do_install
 	$(INSTALL) $1 '$(DESTDIR_SQ)$2'
 endef
 
-install_lib: all_cmd
+install_lib: all_cmd install_plugins
 	$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))
 
+PLUGINS_INSTALL = $(subst .so,.install,$(PLUGINS))
+
+$(PLUGINS_INSTALL): %.install : %.so force
+	$(Q)$(call do_install,$<,$(plugin_dir_SQ))
+
+install_plugins: $(PLUGINS_INSTALL)
+
 install: install_lib
 
 clean:
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/24] tools list traceevent: Add traceevent_host_bigendian function
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (5 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 06/24] tools list traceevent: Add plugin build support Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 08/24] tools list traceevent: Add pevent_print_func_field function Jiri Olsa
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding traceevent_host_bigendian function to get host
endianity. It's used in following patches.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 3aaf668..1199934 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -526,6 +526,15 @@ __data2host8(struct pevent *pevent, unsigned long long data)
 	__data2host8(pevent, __val);				\
 })
 
+static inline int traceevent_host_bigendian(void)
+{
+	unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
+	unsigned int *ptr;
+
+	ptr = (unsigned int *)str;
+	return *ptr == 0x01020304;
+}
+
 /* taken from kernel/trace/trace.h */
 enum trace_flag_type {
 	TRACE_FLAG_IRQS_OFF		= 0x01,
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/24] tools list traceevent: Add pevent_print_func_field function
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (6 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 07/24] tools list traceevent: Add traceevent_host_bigendian function Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 09/24] tools list traceevent: Add jbd2 plugin Jiri Olsa
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding pevent_print_func_field function to print a field
and a format for function pointers. It's used in following
patches.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.c | 42 ++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/event-parse.h |  4 ++++
 2 files changed, 46 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index d1c2a6a..7bc75d6 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5326,6 +5326,48 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
 	return -1;
 }
 
+/**
+ * pevent_print_func_field - print a field and a format for function pointers
+ * @s: The seq to print to
+ * @fmt: The printf format to print the field with.
+ * @event: the event that the field is for
+ * @name: The name of the field
+ * @record: The record with the field name.
+ * @err: print default error if failed.
+ *
+ * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
+ */
+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+			    struct event_format *event, const char *name,
+			    struct pevent_record *record, int err)
+{
+	struct format_field *field = pevent_find_field(event, name);
+	struct pevent *pevent = event->pevent;
+	unsigned long long val;
+	struct func_map *func;
+	char tmp[128];
+
+	if (!field)
+		goto failed;
+
+	if (pevent_read_number_field(field, record->data, &val))
+		goto failed;
+
+	func = find_func(pevent, val);
+
+	if (func)
+		snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
+	else
+		sprintf(tmp, "0x%08llx", val);
+
+	return trace_seq_printf(s, fmt, tmp);
+
+ failed:
+	if (err)
+		trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
+	return -1;
+}
+
 static void free_func_handle(struct pevent_function_handler *func)
 {
 	struct pevent_func_params *params;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 1199934..a2d6306 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -581,6 +581,10 @@ 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_print_func_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,
 				  const char *sys_name, const char *event_name,
 				  pevent_event_handler_func func, void *context);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/24] tools list traceevent: Add jbd2 plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (7 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 08/24] tools list traceevent: Add pevent_print_func_field function Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 10/24] tools list traceevent: Add blk plugin Jiri Olsa
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting jbd2 plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile      |  2 ++
 tools/lib/traceevent/plugin_jbd2.c | 68 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 tools/lib/traceevent/plugin_jbd2.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 19bde02..8ac2b34 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -195,6 +195,8 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
+PLUGIN_OBJS = plugin_jbd2.o
+
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
 ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS)
diff --git a/tools/lib/traceevent/plugin_jbd2.c b/tools/lib/traceevent/plugin_jbd2.c
new file mode 100644
index 0000000..047a6f5
--- /dev/null
+++ b/tools/lib/traceevent/plugin_jbd2.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+
+#define MINORBITS	20
+#define MINORMASK	((1U << MINORBITS) - 1)
+
+#define MAJOR(dev)	((unsigned int) ((dev) >> MINORBITS))
+#define MINOR(dev)	((unsigned int) ((dev) & MINORMASK))
+
+unsigned long long process_jbd2_dev_to_name(struct trace_seq *s,
+					    unsigned long long *args)
+{
+	unsigned int dev = args[0];
+
+	trace_seq_printf(s, "%d:%d", MAJOR(dev), MINOR(dev));
+
+	return 0;
+}
+
+unsigned long long process_jiffies_to_msecs(struct trace_seq *s,
+					    unsigned long long *args)
+{
+	unsigned long long jiffies = args[0];
+
+	trace_seq_printf(s, "%lld", jiffies);
+
+	return jiffies;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_print_function(pevent,
+				       process_jbd2_dev_to_name,
+				       PEVENT_FUNC_ARG_STRING,
+				       "jbd2_dev_to_name",
+				       PEVENT_FUNC_ARG_INT,
+				       PEVENT_FUNC_ARG_VOID);
+
+	pevent_register_print_function(pevent,
+				       process_jiffies_to_msecs,
+				       PEVENT_FUNC_ARG_LONG,
+				       "jiffies_to_msecs",
+				       PEVENT_FUNC_ARG_LONG,
+				       PEVENT_FUNC_ARG_VOID);
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/24] tools list traceevent: Add blk plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (8 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 09/24] tools list traceevent: Add jbd2 plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 11/24] tools list traceevent: Add hrtimer plugin Jiri Olsa
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting blk plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile     |  17 +-
 tools/lib/traceevent/plugin_blk.c | 389 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 404 insertions(+), 2 deletions(-)
 create mode 100644 tools/lib/traceevent/plugin_blk.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 8ac2b34..178cfa1 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -63,6 +63,19 @@ ifndef VERBOSE
   VERBOSE = 0
 endif
 
+# $(call test-build, snippet, ret) -> ret if snippet compiles
+#                                  -> empty otherwise
+test-build = $(if $(shell sh -c 'echo "$(1)" | \
+        $(CC) -o /dev/null -c -x c - > /dev/null 2>&1 && echo y'), $2)
+
+define BLK_TC_FLUSH_SOURCE
+#include <linux/blktrace_api.h>
+int main(void) { return BLK_TC_FLUSH; }
+endef
+
+# have flush/fua block layer instead of barriers?
+blk-flags := $(call test-build,$(BLK_TC_FLUSH_SOURCE),-DHAVE_BLK_TC_FLUSH)
+
 ifeq ("$(origin O)", "command line")
   BUILD_OUTPUT := $(O)
 endif
@@ -133,7 +146,7 @@ CFLAGS ?= -g -Wall
 
 # Append required CFLAGS
 override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
-override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
+override CFLAGS += $(blk-flags) -D_GNU_SOURCE
 
 ifeq ($(VERBOSE),1)
   Q =
@@ -195,7 +208,7 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-PLUGIN_OBJS = plugin_jbd2.o
+PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_blk.c b/tools/lib/traceevent/plugin_blk.c
new file mode 100644
index 0000000..3b6f226
--- /dev/null
+++ b/tools/lib/traceevent/plugin_blk.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/blktrace_api.h>
+
+#include "event-parse.h"
+
+#define MINORBITS	20
+#define MINORMASK	((1U << MINORBITS) - 1)
+#define MAJOR(dev)	((unsigned int) ((dev) >> MINORBITS))
+#define MINOR(dev)	((unsigned int) ((dev) & MINORMASK))
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+struct blk_data {
+	unsigned long long	sector;
+	struct event_format	*event;
+	unsigned int		action;
+	unsigned int		pid;
+	unsigned int		device;
+	unsigned int		bytes;
+	unsigned int		error;
+	void			*pdu_data;
+	unsigned short		pdu_len;
+};
+
+static void fill_rwbs(char *rwbs, int action, unsigned int bytes)
+{
+	int i = 0;
+	int tc = action >> BLK_TC_SHIFT;
+
+	if (action == BLK_TN_MESSAGE) {
+		rwbs[i++] = 'N';
+		goto out;
+	}
+
+#if defined(HAVE_BLK_TC_FLUSH)
+	if (tc & BLK_TC_FLUSH)
+		rwbs[i++] = 'F';
+#endif
+
+	if (tc & BLK_TC_DISCARD)
+		rwbs[i++] = 'D';
+	else if (tc & BLK_TC_WRITE)
+		rwbs[i++] = 'W';
+	else if (bytes)
+		rwbs[i++] = 'R';
+	else
+		rwbs[i++] = 'N';
+
+#if defined(HAVE_BLK_TC_FLUSH)
+	if (tc & BLK_TC_FUA)
+		rwbs[i++] = 'F';
+#endif
+	if (tc & BLK_TC_AHEAD)
+		rwbs[i++] = 'A';
+#if !defined(HAVE_BLK_TC_FLUSH)
+	if (tc & BLK_TC_BARRIER)
+		rwbs[i++] = 'B';
+#endif
+	if (tc & BLK_TC_SYNC)
+		rwbs[i++] = 'S';
+	if (tc & BLK_TC_META)
+		rwbs[i++] = 'M';
+out:
+	rwbs[i] = '\0';
+}
+
+static int log_action(struct trace_seq *s, struct blk_data *data,
+		      const char *act)
+{
+	char rwbs[6];
+
+	fill_rwbs(rwbs, data->action, data->bytes);
+	return trace_seq_printf(s, "%3d,%-3d %2s %3s ",
+				MAJOR(data->device),
+				MINOR(data->device), act, rwbs);
+}
+
+static void blk_log_msg(struct trace_seq *s, void *data, int len)
+{
+	trace_seq_printf(s, "%.*s", len, (char *)data);
+}
+
+static int blk_log_dump_pdu(struct trace_seq *s, const unsigned char *pdu_buf,
+			    int pdu_len)
+{
+	int i, end, ret;
+
+	if (!pdu_len)
+		return 1;
+
+	/* find the last zero that needs to be printed */
+	for (end = pdu_len - 1; end >= 0; end--)
+		if (pdu_buf[end])
+			break;
+	end++;
+
+	if (!trace_seq_putc(s, '('))
+		return 0;
+
+	for (i = 0; i < pdu_len; i++) {
+
+		ret = trace_seq_printf(s, "%s%02x",
+				       i == 0 ? "" : " ", pdu_buf[i]);
+		if (!ret)
+			return ret;
+
+		/*
+		 * stop when the rest is just zeroes and indicate so
+		 * with a ".." appended
+		 */
+		if (i == end && end != pdu_len - 1)
+			return trace_seq_puts(s, " ..) ");
+	}
+
+	return trace_seq_puts(s, ") ");
+}
+
+static unsigned int t_sec(int bytes)
+{
+	return bytes >> 9;
+}
+
+static unsigned int be32_to_cpu(unsigned int val)
+{
+	unsigned int swap;
+
+	if (traceevent_host_bigendian())
+		return val;
+
+	swap = ((val & 0xffULL) << 24) |
+		((val & (0xffULL << 8)) << 8) |
+		((val & (0xffULL << 16)) >> 8) |
+		((val & (0xffULL << 24)) >> 24);
+
+	return swap;
+}
+
+static unsigned long long be64_to_cpu(unsigned long long val)
+{
+	unsigned long long swap;
+
+	if (traceevent_host_bigendian())
+		return val;
+
+	swap = ((val & 0xffULL) << 56) |
+		((val & (0xffULL << 8)) << 40) |
+		((val & (0xffULL << 16)) << 24) |
+		((val & (0xffULL << 24)) << 8) |
+		((val & (0xffULL << 32)) >> 8) |
+		((val & (0xffULL << 40)) >> 24) |
+		((val & (0xffULL << 48)) >> 40) |
+		((val & (0xffULL << 56)) >> 56);
+
+	return swap;
+}
+
+static unsigned long long get_pdu_int(void *data)
+{
+	const unsigned long long *val = data;
+	return be64_to_cpu(*val);
+}
+
+static void get_pdu_remap(void *pdu_data,
+			  struct blk_io_trace_remap *r)
+{
+	const struct blk_io_trace_remap *__r = pdu_data;
+	unsigned long long sector_from = __r->sector_from;
+
+	r->device_from = be32_to_cpu(__r->device_from);
+	r->device_to   = be32_to_cpu(__r->device_to);
+	r->sector_from = be64_to_cpu(sector_from);
+}
+
+static int blk_log_remap(struct trace_seq *s, struct blk_data *data)
+{
+	struct blk_io_trace_remap r = { .device_from = 0, };
+
+	get_pdu_remap(data->pdu_data, &r);
+	return trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n",
+				data->sector, t_sec(data->bytes),
+				MAJOR(r.device_from), MINOR(r.device_from),
+				(unsigned long long)r.sector_from);
+}
+
+static int blk_log_split(struct trace_seq *s, struct blk_data *data)
+{
+	const char *cmd;
+
+	cmd = pevent_data_comm_from_pid(data->event->pevent, data->pid);
+
+	return trace_seq_printf(s, "%llu / %llu [%s]\n", data->sector,
+				get_pdu_int(data->pdu_data), cmd);
+}
+
+static int blk_log_plug(struct trace_seq *s, struct blk_data *data)
+{
+	const char *cmd;
+
+	cmd = pevent_data_comm_from_pid(data->event->pevent, data->pid);
+
+	return trace_seq_printf(s, "[%s]\n", cmd);
+}
+
+static int blk_log_unplug(struct trace_seq *s, struct blk_data *data)
+{
+	const char *cmd;
+
+	cmd = pevent_data_comm_from_pid(data->event->pevent, data->pid);
+
+	return trace_seq_printf(s, "[%s] %llu\n", cmd,
+				get_pdu_int(data->pdu_data));
+}
+
+static int blk_log_with_error(struct trace_seq *s, struct blk_data *data)
+{
+	if (data->action & BLK_TC_ACT(BLK_TC_PC)) {
+		blk_log_dump_pdu(s, data->pdu_data, data->pdu_len);
+		trace_seq_printf(s, "[%d]\n", data->error);
+		return 0;
+	} else {
+		if (t_sec(data->bytes))
+			return trace_seq_printf(s, "%llu + %u [%d]\n",
+						data->sector,
+						t_sec(data->bytes),
+						data->error);
+		return trace_seq_printf(s, "%llu [%d]\n",
+					data->sector, data->error);
+	}
+}
+
+static int blk_log_generic(struct trace_seq *s, struct blk_data *data)
+{
+	const char *cmd;
+
+	cmd = pevent_data_comm_from_pid(data->event->pevent, data->pid);
+
+	if (data->action & BLK_TC_ACT(BLK_TC_PC)) {
+		int ret;
+
+		ret = trace_seq_printf(s, "%u ", data->bytes);
+		if (!ret)
+			return 0;
+		ret = blk_log_dump_pdu(s, data->pdu_data, data->pdu_len);
+		if (!ret)
+			return 0;
+		return trace_seq_printf(s, "[%s]\n", cmd);
+	} else {
+		if (t_sec(data->bytes))
+			return trace_seq_printf(s, "%llu + %u [%s]\n",
+						data->sector,
+						t_sec(data->bytes), cmd);
+		return trace_seq_printf(s, "[%s]\n", cmd);
+	}
+}
+
+static const struct {
+	const char *act[2];
+	int	   (*print)(struct trace_seq *s, struct blk_data *data);
+} what2act[] = {
+	[__BLK_TA_QUEUE]	= {{  "Q", "queue" },	   blk_log_generic },
+	[__BLK_TA_BACKMERGE]	= {{  "M", "backmerge" },  blk_log_generic },
+	[__BLK_TA_FRONTMERGE]	= {{  "F", "frontmerge" }, blk_log_generic },
+	[__BLK_TA_GETRQ]	= {{  "G", "getrq" },	   blk_log_generic },
+	[__BLK_TA_SLEEPRQ]	= {{  "S", "sleeprq" },	   blk_log_generic },
+	[__BLK_TA_REQUEUE]	= {{  "R", "requeue" },	   blk_log_with_error },
+	[__BLK_TA_ISSUE]	= {{  "D", "issue" },	   blk_log_generic },
+	[__BLK_TA_COMPLETE]	= {{  "C", "complete" },   blk_log_with_error },
+	[__BLK_TA_PLUG]		= {{  "P", "plug" },	   blk_log_plug },
+	[__BLK_TA_UNPLUG_IO]	= {{  "U", "unplug_io" },  blk_log_unplug },
+	[__BLK_TA_UNPLUG_TIMER]	= {{ "UT", "unplug_timer" }, blk_log_unplug },
+	[__BLK_TA_INSERT]	= {{  "I", "insert" },	   blk_log_generic },
+	[__BLK_TA_SPLIT]	= {{  "X", "split" },	   blk_log_split },
+	[__BLK_TA_BOUNCE]	= {{  "B", "bounce" },	   blk_log_generic },
+	[__BLK_TA_REMAP]	= {{  "A", "remap" },	   blk_log_remap },
+};
+
+static int blktrace_handler(struct trace_seq *s, struct pevent_record *record,
+			    struct event_format *event, void *context)
+{
+	struct format_field *field;
+	unsigned long long val;
+	void *data = record->data;
+	struct blk_data blk_data;
+	unsigned short what;
+	int long_act = 0;
+
+	field = pevent_find_field(event, "action");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.action = val;
+
+	field = pevent_find_field(event, "bytes");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.bytes = val;
+
+	field = pevent_find_field(event, "device");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.device = val;
+
+	field = pevent_find_field(event, "pdu_len");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.pdu_len = val;
+
+	field = pevent_find_field(event, "data");
+	if (!field)
+		return 1;
+	blk_data.pdu_data = data + field->offset;
+
+	field = pevent_find_field(event, "sector");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &blk_data.sector))
+		return 1;
+
+	field = pevent_find_field(event, "pid");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.pid = val;
+
+	field = pevent_find_field(event, "error");
+	if (!field)
+		return 1;
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+	blk_data.error = val;
+
+	blk_data.event = event;
+
+
+	what	   = blk_data.action & ((1 << BLK_TC_SHIFT) - 1);
+
+	if (blk_data.action == BLK_TN_MESSAGE) {
+		log_action(s, &blk_data, "m");
+		blk_log_msg(s, blk_data.pdu_data, blk_data.pdu_len);
+		goto out;
+	}
+
+	if (what == 0 || what >= ARRAY_SIZE(what2act))
+		trace_seq_printf(s, "Unknown action %x\n", what);
+	else {
+		log_action(s, &blk_data, what2act[what].act[long_act]);
+		what2act[what].print(s, &blk_data);
+	}
+
+ out:
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "ftrace", "blktrace",
+				      blktrace_handler, NULL);
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/24] tools list traceevent: Add hrtimer plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (9 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 10/24] tools list traceevent: Add blk plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 12/24] tools list traceevent: Add kmem plugin Jiri Olsa
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting hrtimer plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile         |  2 +-
 tools/lib/traceevent/plugin_hrtimer.c | 94 +++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_hrtimer.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 178cfa1..6e29f26 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -208,7 +208,7 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o
+PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_hrtimer.c b/tools/lib/traceevent/plugin_hrtimer.c
new file mode 100644
index 0000000..e7fb195
--- /dev/null
+++ b/tools/lib/traceevent/plugin_hrtimer.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ * Copyright (C) 2009 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+
+static int timer_expire_handler(struct trace_seq *s,
+				struct pevent_record *record,
+				struct event_format *event, void *context)
+{
+	trace_seq_printf(s, "hrtimer=");
+
+	if (pevent_print_num_field(s, "0x%llx", event, "timer",
+				   record, 0) == -1)
+		pevent_print_num_field(s, "0x%llx", event, "hrtimer",
+				       record, 1);
+
+	trace_seq_printf(s, " now=");
+
+	pevent_print_num_field(s, "%llu", event, "now", record, 1);
+
+	pevent_print_func_field(s, " function=%s", event, "function",
+				record, 0);
+
+	return 0;
+}
+
+static int timer_start_handler(struct trace_seq *s, struct pevent_record *record,
+			       struct event_format *event, void *context)
+{
+	struct pevent *pevent = event->pevent;
+	struct format_field *fn = pevent_find_field(event, "function");
+	void *data = record->data;
+
+	trace_seq_printf(s, "hrtimer=");
+
+	if (pevent_print_num_field(s, "0x%llx", event, "timer",
+				   record, 0) == -1)
+		pevent_print_num_field(s, "0x%llx", event, "hrtimer",
+				       record, 1);
+
+	if (!fn) {
+		trace_seq_printf(s, " function=MISSING");
+	} else {
+		unsigned long long function;
+		const char *func;
+
+		if (pevent_read_number_field(fn, data, &function))
+			trace_seq_printf(s, " function=INVALID");
+
+		func = pevent_find_function(pevent, function);
+
+		trace_seq_printf(s, " function=%s", func);
+	}
+
+	trace_seq_printf(s, " expires=");
+	pevent_print_num_field(s, "%llu", event, "expires", record, 1);
+
+	trace_seq_printf(s, " softexpires=");
+	pevent_print_num_field(s, "%llu", event, "softexpires", record, 1);
+
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "timer", "hrtimer_expire_entry",
+				      timer_expire_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "timer", "hrtimer_start",
+				      timer_start_handler, NULL);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/24] tools list traceevent: Add kmem plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (10 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 11/24] tools list traceevent: Add hrtimer plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 13/24] tools list traceevent: Add kvm plugin Jiri Olsa
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting kmem plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile      |  2 +-
 tools/lib/traceevent/plugin_kmem.c | 76 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_kmem.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 6e29f26..8e391bc 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -208,7 +208,7 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o
+PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_kmem.c b/tools/lib/traceevent/plugin_kmem.c
new file mode 100644
index 0000000..0f8323c
--- /dev/null
+++ b/tools/lib/traceevent/plugin_kmem.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+
+static int call_site_handler(struct trace_seq *s, struct pevent_record *record,
+			     struct event_format *event, void *context)
+{
+	struct format_field *field;
+	unsigned long long val, addr;
+	void *data = record->data;
+	const char *func;
+
+	field = pevent_find_field(event, "call_site");
+	if (!field)
+		return 1;
+
+	if (pevent_read_number_field(field, data, &val))
+		return 1;
+
+	func = pevent_find_function(event->pevent, val);
+	if (!func)
+		return 1;
+	addr = pevent_find_function_address(event->pevent, val);
+
+	trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr));
+
+	return 1;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "kmem", "kfree",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem", "kmalloc",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem",
+				      "kmem_cache_alloc_node",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem", "kfree",
+				      call_site_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
+				      call_site_handler, NULL);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/24] tools list traceevent: Add kvm plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (11 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 12/24] tools list traceevent: Add kmem plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 14/24] tools list traceevent: Add mac80211 plugin Jiri Olsa
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting kvm plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile     |   2 +-
 tools/lib/traceevent/plugin_kvm.c | 464 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 465 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_kvm.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 8e391bc..3ac01c6 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -208,7 +208,7 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o
+PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_kvm.c b/tools/lib/traceevent/plugin_kvm.c
new file mode 100644
index 0000000..a776cd6
--- /dev/null
+++ b/tools/lib/traceevent/plugin_kvm.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "event-parse.h"
+
+#ifdef HAVE_UDIS86
+
+#include <udis86.h>
+
+static ud_t ud;
+
+static void init_disassembler(void)
+{
+	ud_init(&ud);
+	ud_set_syntax(&ud, UD_SYN_ATT);
+}
+
+static const char *disassemble(unsigned char *insn, int len, uint64_t rip,
+			       int cr0_pe, int eflags_vm,
+			       int cs_d, int cs_l)
+{
+	int mode;
+
+	if (!cr0_pe)
+		mode = 16;
+	else if (eflags_vm)
+		mode = 16;
+	else if (cs_l)
+		mode = 64;
+	else if (cs_d)
+		mode = 32;
+	else
+		mode = 16;
+
+	ud_set_pc(&ud, rip);
+	ud_set_mode(&ud, mode);
+	ud_set_input_buffer(&ud, insn, len);
+	ud_disassemble(&ud);
+	return ud_insn_asm(&ud);
+}
+
+#else
+
+static void init_disassembler(void)
+{
+}
+
+static const char *disassemble(unsigned char *insn, int len, uint64_t rip,
+			       int cr0_pe, int eflags_vm,
+			       int cs_d, int cs_l)
+{
+	static char out[15*3+1];
+	int i;
+
+	for (i = 0; i < len; ++i)
+		sprintf(out + i * 3, "%02x ", insn[i]);
+	out[len*3-1] = '\0';
+	return out;
+}
+
+#endif
+
+
+#define VMX_EXIT_REASONS			\
+	_ER(EXCEPTION_NMI,	0)		\
+	_ER(EXTERNAL_INTERRUPT,	1)		\
+	_ER(TRIPLE_FAULT,	2)		\
+	_ER(PENDING_INTERRUPT,	7)		\
+	_ER(NMI_WINDOW,		8)		\
+	_ER(TASK_SWITCH,	9)		\
+	_ER(CPUID,		10)		\
+	_ER(HLT,		12)		\
+	_ER(INVD,		13)		\
+	_ER(INVLPG,		14)		\
+	_ER(RDPMC,		15)		\
+	_ER(RDTSC,		16)		\
+	_ER(VMCALL,		18)		\
+	_ER(VMCLEAR,		19)		\
+	_ER(VMLAUNCH,		20)		\
+	_ER(VMPTRLD,		21)		\
+	_ER(VMPTRST,		22)		\
+	_ER(VMREAD,		23)		\
+	_ER(VMRESUME,		24)		\
+	_ER(VMWRITE,		25)		\
+	_ER(VMOFF,		26)		\
+	_ER(VMON,		27)		\
+	_ER(CR_ACCESS,		28)		\
+	_ER(DR_ACCESS,		29)		\
+	_ER(IO_INSTRUCTION,	30)		\
+	_ER(MSR_READ,		31)		\
+	_ER(MSR_WRITE,		32)		\
+	_ER(MWAIT_INSTRUCTION,	36)		\
+	_ER(MONITOR_INSTRUCTION,39)		\
+	_ER(PAUSE_INSTRUCTION,	40)		\
+	_ER(MCE_DURING_VMENTRY,	41)		\
+	_ER(TPR_BELOW_THRESHOLD,43)		\
+	_ER(APIC_ACCESS,	44)		\
+	_ER(EOI_INDUCED,	45)		\
+	_ER(EPT_VIOLATION,	48)		\
+	_ER(EPT_MISCONFIG,	49)		\
+	_ER(INVEPT,		50)		\
+	_ER(PREEMPTION_TIMER,	52)		\
+	_ER(WBINVD,		54)		\
+	_ER(XSETBV,		55)		\
+	_ER(APIC_WRITE,		56)		\
+	_ER(INVPCID,		58)
+
+#define SVM_EXIT_REASONS \
+	_ER(EXIT_READ_CR0,	0x000)		\
+	_ER(EXIT_READ_CR3,	0x003)		\
+	_ER(EXIT_READ_CR4,	0x004)		\
+	_ER(EXIT_READ_CR8,	0x008)		\
+	_ER(EXIT_WRITE_CR0,	0x010)		\
+	_ER(EXIT_WRITE_CR3,	0x013)		\
+	_ER(EXIT_WRITE_CR4,	0x014)		\
+	_ER(EXIT_WRITE_CR8,	0x018)		\
+	_ER(EXIT_READ_DR0,	0x020)		\
+	_ER(EXIT_READ_DR1,	0x021)		\
+	_ER(EXIT_READ_DR2,	0x022)		\
+	_ER(EXIT_READ_DR3,	0x023)		\
+	_ER(EXIT_READ_DR4,	0x024)		\
+	_ER(EXIT_READ_DR5,	0x025)		\
+	_ER(EXIT_READ_DR6,	0x026)		\
+	_ER(EXIT_READ_DR7,	0x027)		\
+	_ER(EXIT_WRITE_DR0,	0x030)		\
+	_ER(EXIT_WRITE_DR1,	0x031)		\
+	_ER(EXIT_WRITE_DR2,	0x032)		\
+	_ER(EXIT_WRITE_DR3,	0x033)		\
+	_ER(EXIT_WRITE_DR4,	0x034)		\
+	_ER(EXIT_WRITE_DR5,	0x035)		\
+	_ER(EXIT_WRITE_DR6,	0x036)		\
+	_ER(EXIT_WRITE_DR7,	0x037)		\
+	_ER(EXIT_EXCP_BASE,     0x040)		\
+	_ER(EXIT_INTR,		0x060)		\
+	_ER(EXIT_NMI,		0x061)		\
+	_ER(EXIT_SMI,		0x062)		\
+	_ER(EXIT_INIT,		0x063)		\
+	_ER(EXIT_VINTR,		0x064)		\
+	_ER(EXIT_CR0_SEL_WRITE,	0x065)		\
+	_ER(EXIT_IDTR_READ,	0x066)		\
+	_ER(EXIT_GDTR_READ,	0x067)		\
+	_ER(EXIT_LDTR_READ,	0x068)		\
+	_ER(EXIT_TR_READ,	0x069)		\
+	_ER(EXIT_IDTR_WRITE,	0x06a)		\
+	_ER(EXIT_GDTR_WRITE,	0x06b)		\
+	_ER(EXIT_LDTR_WRITE,	0x06c)		\
+	_ER(EXIT_TR_WRITE,	0x06d)		\
+	_ER(EXIT_RDTSC,		0x06e)		\
+	_ER(EXIT_RDPMC,		0x06f)		\
+	_ER(EXIT_PUSHF,		0x070)		\
+	_ER(EXIT_POPF,		0x071)		\
+	_ER(EXIT_CPUID,		0x072)		\
+	_ER(EXIT_RSM,		0x073)		\
+	_ER(EXIT_IRET,		0x074)		\
+	_ER(EXIT_SWINT,		0x075)		\
+	_ER(EXIT_INVD,		0x076)		\
+	_ER(EXIT_PAUSE,		0x077)		\
+	_ER(EXIT_HLT,		0x078)		\
+	_ER(EXIT_INVLPG,	0x079)		\
+	_ER(EXIT_INVLPGA,	0x07a)		\
+	_ER(EXIT_IOIO,		0x07b)		\
+	_ER(EXIT_MSR,		0x07c)		\
+	_ER(EXIT_TASK_SWITCH,	0x07d)		\
+	_ER(EXIT_FERR_FREEZE,	0x07e)		\
+	_ER(EXIT_SHUTDOWN,	0x07f)		\
+	_ER(EXIT_VMRUN,		0x080)		\
+	_ER(EXIT_VMMCALL,	0x081)		\
+	_ER(EXIT_VMLOAD,	0x082)		\
+	_ER(EXIT_VMSAVE,	0x083)		\
+	_ER(EXIT_STGI,		0x084)		\
+	_ER(EXIT_CLGI,		0x085)		\
+	_ER(EXIT_SKINIT,	0x086)		\
+	_ER(EXIT_RDTSCP,	0x087)		\
+	_ER(EXIT_ICEBP,		0x088)		\
+	_ER(EXIT_WBINVD,	0x089)		\
+	_ER(EXIT_MONITOR,	0x08a)		\
+	_ER(EXIT_MWAIT,		0x08b)		\
+	_ER(EXIT_MWAIT_COND,	0x08c)		\
+	_ER(EXIT_NPF,		0x400)		\
+	_ER(EXIT_ERR,		-1)
+
+#define _ER(reason, val)	{ #reason, val },
+struct str_values {
+	const char	*str;
+	int		val;
+};
+
+static struct str_values vmx_exit_reasons[] = {
+	VMX_EXIT_REASONS
+	{ NULL, -1}
+};
+
+static struct str_values svm_exit_reasons[] = {
+	SVM_EXIT_REASONS
+	{ NULL, -1}
+};
+
+static struct isa_exit_reasons {
+	unsigned isa;
+	struct str_values *strings;
+} isa_exit_reasons[] = {
+	{ .isa = 1, .strings = vmx_exit_reasons },
+	{ .isa = 2, .strings = svm_exit_reasons },
+	{ }
+};
+
+static const char *find_exit_reason(unsigned isa, int val)
+{
+	struct str_values *strings = NULL;
+	int i;
+
+	for (i = 0; isa_exit_reasons[i].strings; ++i)
+		if (isa_exit_reasons[i].isa == isa) {
+			strings = isa_exit_reasons[i].strings;
+			break;
+		}
+	if (!strings)
+		return "UNKNOWN-ISA";
+	for (i = 0; strings[i].val >= 0; i++)
+		if (strings[i].val == val)
+			break;
+	if (strings[i].str)
+		return strings[i].str;
+	return "UNKNOWN";
+}
+
+static int kvm_exit_handler(struct trace_seq *s, struct pevent_record *record,
+			    struct event_format *event, void *context)
+{
+	unsigned long long isa;
+	unsigned long long val;
+	unsigned long long info1 = 0, info2 = 0;
+
+	if (pevent_get_field_val(s, event, "exit_reason", record, &val, 1) < 0)
+		return -1;
+
+	if (pevent_get_field_val(s, event, "isa", record, &isa, 0) < 0)
+		isa = 1;
+
+	trace_seq_printf(s, "reason %s", find_exit_reason(isa, val));
+
+	pevent_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1);
+
+	if (pevent_get_field_val(s, event, "info1", record, &info1, 0) >= 0
+	    && pevent_get_field_val(s, event, "info2", record, &info2, 0) >= 0)
+		trace_seq_printf(s, " info %llx %llx\n", info1, info2);
+
+	return 0;
+}
+
+#define KVM_EMUL_INSN_F_CR0_PE (1 << 0)
+#define KVM_EMUL_INSN_F_EFL_VM (1 << 1)
+#define KVM_EMUL_INSN_F_CS_D   (1 << 2)
+#define KVM_EMUL_INSN_F_CS_L   (1 << 3)
+
+static int kvm_emulate_insn_handler(struct trace_seq *s,
+				    struct pevent_record *record,
+				    struct event_format *event, void *context)
+{
+	unsigned long long rip, csbase, len, flags, failed;
+	int llen;
+	uint8_t *insn;
+	const char *disasm;
+
+	if (pevent_get_field_val(s, event, "rip", record, &rip, 1) < 0)
+		return -1;
+
+	if (pevent_get_field_val(s, event, "csbase", record, &csbase, 1) < 0)
+		return -1;
+
+	if (pevent_get_field_val(s, event, "len", record, &len, 1) < 0)
+		return -1;
+
+	if (pevent_get_field_val(s, event, "flags", record, &flags, 1) < 0)
+		return -1;
+
+	if (pevent_get_field_val(s, event, "failed", record, &failed, 1) < 0)
+		return -1;
+
+	insn = pevent_get_field_raw(s, event, "insn", record, &llen, 1);
+	if (!insn)
+		return -1;
+
+	disasm = disassemble(insn, len, rip,
+			     flags & KVM_EMUL_INSN_F_CR0_PE,
+			     flags & KVM_EMUL_INSN_F_EFL_VM,
+			     flags & KVM_EMUL_INSN_F_CS_D,
+			     flags & KVM_EMUL_INSN_F_CS_L);
+
+	trace_seq_printf(s, "%llx:%llx: %s%s", csbase, rip, disasm,
+			 failed ? " FAIL" : "");
+
+	return 0;
+}
+
+
+static int kvm_nested_vmexit_inject_handler(struct trace_seq *s,
+					    struct pevent_record *record,
+					    struct event_format *event,
+					    void *context)
+{
+	unsigned long long val;
+
+	pevent_print_num_field(s, " rip %0x016llx", event, "rip", record, 1);
+
+	if (pevent_get_field_val(s, event, "exit_code", record, &val, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, "reason %s", find_exit_reason(2, val));
+
+	pevent_print_num_field(s, " ext_inf1: %0x016llx", event,
+			       "exit_info1", record, 1);
+	pevent_print_num_field(s, " ext_inf2: %0x016llx", event,
+			       "exit_info2", record, 1);
+	pevent_print_num_field(s, " ext_int: %0x016llx", event,
+			       "exit_int_info", record, 1);
+	pevent_print_num_field(s, " ext_int_err: %0x016llx", event,
+			       "exit_int_info_err", record, 1);
+
+	return 0;
+}
+
+static int kvm_nested_vmexit_handler(struct trace_seq *s,
+				     struct pevent_record *record,
+				     struct event_format *event, void *context)
+{
+	pevent_print_num_field(s, " rip %0x016llx", event, "rip", record, 1);
+
+	return kvm_nested_vmexit_inject_handler(s, record, event, context);
+}
+
+union kvm_mmu_page_role {
+	unsigned word;
+	struct {
+		unsigned glevels:4;
+		unsigned level:4;
+		unsigned quadrant:2;
+		unsigned pad_for_nice_hex_output:6;
+		unsigned direct:1;
+		unsigned access:3;
+		unsigned invalid:1;
+		unsigned cr4_pge:1;
+		unsigned nxe:1;
+	};
+};
+
+static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
+			      struct event_format *event, void *context)
+{
+	unsigned long long val;
+	static const char *access_str[] =
+		{ "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" };
+	union kvm_mmu_page_role role;
+
+	if (pevent_get_field_val(s, event, "role", record, &val, 1) < 0)
+		return -1;
+
+	role.word = (int)val;
+
+	/*
+	 * We can only use the structure if file is of the same
+	 * endianess.
+	 */
+	if (pevent_is_file_bigendian(event->pevent) ==
+	    pevent_is_host_bigendian(event->pevent)) {
+
+		trace_seq_printf(s, "%u/%u q%u%s %s%s %spge %snxe",
+				 role.level,
+				 role.glevels,
+				 role.quadrant,
+				 role.direct ? " direct" : "",
+				 access_str[role.access],
+				 role.invalid ? " invalid" : "",
+				 role.cr4_pge ? "" : "!",
+				 role.nxe ? "" : "!");
+	} else
+		trace_seq_printf(s, "WORD: %08x", role.word);
+
+	pevent_print_num_field(s, " root %u ",  event,
+			       "root_count", record, 1);
+
+	if (pevent_get_field_val(s, event, "unsync", record, &val, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, "%s%c",  val ? "unsync" : "sync", 0);
+
+	return 0;
+}
+
+static int kvm_mmu_get_page_handler(struct trace_seq *s,
+				    struct pevent_record *record,
+				    struct event_format *event, void *context)
+{
+	unsigned long long val;
+
+	if (pevent_get_field_val(s, event, "created", record, &val, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, "%s ", val ? "new" : "existing");
+
+	if (pevent_get_field_val(s, event, "gfn", record, &val, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, "sp gfn %llx ", val);
+
+	return kvm_mmu_print_role(s, record, event, context);
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	init_disassembler();
+
+	pevent_register_event_handler(pevent, -1, "kvm", "kvm_exit",
+				      kvm_exit_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvm", "kvm_emulate_insn",
+				      kvm_emulate_insn_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit",
+				      kvm_nested_vmexit_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvm",
+				      "kvm_nested_vmexit_inject",
+				      kvm_nested_vmexit_inject_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page",
+				      kvm_mmu_get_page_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page",
+				      kvm_mmu_print_role, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_unsync_page",
+				      kvm_mmu_print_role, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page",
+				      kvm_mmu_print_role, NULL);
+
+	pevent_register_event_handler(pevent, -1, "kvmmmu",
+			"kvm_mmu_prepare_zap_page", kvm_mmu_print_role,
+			NULL);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/24] tools list traceevent: Add mac80211 plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (12 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 13/24] tools list traceevent: Add kvm plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 15/24] tools list traceevent: Add sched_switch plugin Jiri Olsa
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting mac80211 plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile          |   3 +-
 tools/lib/traceevent/plugin_mac80211.c | 204 +++++++++++++++++++++++++++++++++
 2 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_mac80211.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 3ac01c6..690e107 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -208,7 +208,8 @@ $(obj)/%.o: $(src)/%.c
 PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o event-option.o
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
-PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o
+PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o \
+	plugin_mac80211.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_mac80211.c b/tools/lib/traceevent/plugin_mac80211.c
new file mode 100644
index 0000000..070c7c9
--- /dev/null
+++ b/tools/lib/traceevent/plugin_mac80211.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2009 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+
+#define INDENT 65
+
+static void print_string(struct trace_seq *s, struct event_format *event,
+			 const char *name, const void *data)
+{
+	struct format_field *f = pevent_find_field(event, name);
+	int offset;
+	int length;
+
+	if (!f) {
+		trace_seq_printf(s, "NOTFOUND:%s", name);
+		return;
+	}
+
+	offset = f->offset;
+	length = f->size;
+
+	if (!strncmp(f->type, "__data_loc", 10)) {
+		unsigned long long v;
+		if (pevent_read_number_field(f, data, &v)) {
+			trace_seq_printf(s, "invalid_data_loc");
+			return;
+		}
+		offset = v & 0xffff;
+		length = v >> 16;
+	}
+
+	trace_seq_printf(s, "%.*s", length, (char *)data + offset);
+}
+
+struct value_name {
+	unsigned long long value;
+	const char *name;
+};
+
+static void _print_enum(struct trace_seq *s, struct event_format *event,
+			const char *name, const void *data,
+			const struct value_name *names, int n_names)
+{
+	struct format_field *f = pevent_find_field(event, name);
+	unsigned long long val;
+	int i;
+
+	if (!f) {
+		trace_seq_puts(s, "field-not-found");
+		return;
+	}
+
+	if (pevent_read_number_field(f, data, &val)) {
+		trace_seq_puts(s, "field-invalid");
+		return;
+	}
+
+	for (i = 0; i < n_names; i++) {
+		if (names[i].value == val) {
+			trace_seq_puts(s, names[i].name);
+			return;
+		}
+	}
+
+	trace_seq_printf(s, "%llu", val);
+}
+
+#define print_enum(s, ev, name, data, enums...)				\
+	({ static const struct value_name __n[] = { enums };		\
+	_print_enum(s, ev, name, data, __n, sizeof(__n)/sizeof(__n[0]));\
+	})
+
+static void _print_flag(struct trace_seq *s, struct event_format *event,
+			const char *name, const void *data,
+			const struct value_name *names, int n_names)
+{
+	struct format_field *f = pevent_find_field(event, name);
+	unsigned long long val;
+	int i, j, found, first = 1;
+
+	if (!f) {
+		trace_seq_puts(s, "field-not-found");
+		return;
+	}
+
+	if (pevent_read_number_field(f, data, &val)) {
+		trace_seq_puts(s, "field-invalid");
+		return;
+	}
+
+	for (i = 0; i < 64; i++) {
+		if (!(val & (1ULL<<i)))
+			continue;
+		if (!first)
+			trace_seq_putc(s, '|');
+		first = 0;
+
+		found = 0;
+		for (j = 0; j < n_names; j++) {
+			if (i == names[j].value) {
+				trace_seq_puts(s, names[j].name);
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			trace_seq_printf(s, "flag_%d", i);
+	}
+}
+
+#define print_flag(s, ev, name, data, enums...)					\
+	({ static const struct value_name __n[] = { enums };			\
+	_print_flag(s, ev, name, data, __n, sizeof(__n)/sizeof(__n[0]));	\
+	})
+
+#define SF(fn)	pevent_print_num_field(s, fn ":%d", event, fn, record, 0)
+#define SFX(fn)	pevent_print_num_field(s, fn ":%#x", event, fn, record, 0)
+#define SP()	trace_seq_putc(s, ' ')
+
+static int drv_bss_info_changed(struct trace_seq *s,
+				struct pevent_record *record,
+				struct event_format *event, void *context)
+{
+	void *data = record->data;
+
+	print_string(s, event, "wiphy_name", data);
+	trace_seq_printf(s, " vif:");
+	print_string(s, event, "vif_name", data);
+	pevent_print_num_field(s, "(%d)", event, "vif_type", record, 1);
+
+	trace_seq_printf(s, "\n%*s", INDENT, "");
+	SF("assoc"); SP();
+	SF("aid"); SP();
+	SF("cts"); SP();
+	SF("shortpre"); SP();
+	SF("shortslot"); SP();
+	SF("dtimper"); SP();
+	trace_seq_printf(s, "\n%*s", INDENT, "");
+	SF("bcnint"); SP();
+	SFX("assoc_cap"); SP();
+	SFX("basic_rates"); SP();
+	SF("enable_beacon");
+	trace_seq_printf(s, "\n%*s", INDENT, "");
+	SF("ht_operation_mode");
+
+	return 0;
+}
+
+static int drv_config(struct trace_seq *s, struct pevent_record *record,
+		      struct event_format *event, void *context)
+{
+	void *data = record->data;
+
+	print_string(s, event, "wiphy_name", data);
+	trace_seq_putc(s, ' ');
+	print_flag(s, event, "flags", data,
+		{ 0, "MONITOR" },
+		{ 1, "PS" },
+		{ 2, "IDLE" },
+		{ 3, "QOS"},
+	);
+	pevent_print_num_field(s, " chan:%d/", event, "center_freq", record, 1);
+	print_enum(s, event, "channel_type", data,
+		{ 0, "noht" },
+		{ 1, "ht20" },
+		{ 2, "ht40-" },
+		{ 3, "ht40+" });
+	trace_seq_putc(s, ' ');
+	SF("power_level");
+
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "mac80211",
+				      "drv_bss_info_changed",
+				      drv_bss_info_changed, NULL);
+	pevent_register_event_handler(pevent, -1, "mac80211", "drv_config",
+				      drv_config, NULL);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/24] tools list traceevent: Add sched_switch plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (13 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 14/24] tools list traceevent: Add mac80211 plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 16/24] tools list traceevent: Add function plugin Jiri Olsa
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting sched_switch plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile              |   2 +-
 tools/lib/traceevent/plugin_sched_switch.c | 147 +++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_sched_switch.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 690e107..3a5ffd3 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -209,7 +209,7 @@ PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
 PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o \
-	plugin_mac80211.o
+	plugin_mac80211.o plugin_sched_switch.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_sched_switch.c b/tools/lib/traceevent/plugin_sched_switch.c
new file mode 100644
index 0000000..63c422c
--- /dev/null
+++ b/tools/lib/traceevent/plugin_sched_switch.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+
+static void write_state(struct trace_seq *s, int val)
+{
+	const char states[] = "SDTtZXxW";
+	int found = 0;
+	int i;
+
+	for (i=0; i < (sizeof(states) - 1); i++) {
+		if (!(val & (1 << i)))
+			continue;
+
+		if (found)
+			trace_seq_putc(s, '|');
+
+		found = 1;
+		trace_seq_putc(s, states[i]);
+	}
+
+	if (!found)
+		trace_seq_putc(s, 'R');
+}
+
+static void write_and_save_comm(struct format_field *field,
+				struct pevent_record *record,
+				struct trace_seq *s, int pid)
+{
+	const char *comm;
+	int len;
+
+	comm = (char *)(record->data + field->offset);
+	len = s->len;
+	trace_seq_printf(s, "%.*s",
+			 field->size, comm);
+
+	/* make sure the comm has a \0 at the end. */
+	trace_seq_terminate(s);
+	comm = &s->buffer[len];
+
+	/* Help out the comm to ids. This will handle dups */
+	pevent_register_comm(field->event->pevent, comm, pid);
+}
+
+static int sched_wakeup_handler(struct trace_seq *s, struct pevent_record *record,
+				struct event_format *event, void *context)
+{
+	struct format_field *field;
+	unsigned long long val;
+
+	if (pevent_get_field_val(s, event, "pid", record, &val, 1))
+		return trace_seq_putc(s, '!');
+
+	field = pevent_find_any_field(event, "comm");
+	if (field) {
+		write_and_save_comm(field, record, s, val);
+		trace_seq_putc(s, ':');
+	}
+	trace_seq_printf(s, "%lld", val);
+
+	if (pevent_get_field_val(s, event, "prio", record, &val, 0) == 0)
+		trace_seq_printf(s, " [%lld]", val);
+
+	if (pevent_get_field_val(s, event, "success", record, &val, 1) == 0)
+		trace_seq_printf(s, " success=%lld", val);
+
+	if (pevent_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
+		trace_seq_printf(s, " CPU:%03llu", val);
+
+	return 0;
+}
+
+static int sched_switch_handler(struct trace_seq *s, struct pevent_record *record,
+				struct event_format *event, void *context)
+{
+	struct format_field *field;
+	unsigned long long val;
+
+	if (pevent_get_field_val(s, event, "prev_pid", record, &val, 1))
+		return trace_seq_putc(s, '!');
+
+	field = pevent_find_any_field(event, "prev_comm");
+	if (field) {
+		write_and_save_comm(field, record, s, val);
+		trace_seq_putc(s, ':');
+	}
+	trace_seq_printf(s, "%lld ", val);
+
+	if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
+		trace_seq_printf(s, "[%lld] ", val);
+
+	if (pevent_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
+		write_state(s, val);
+
+	trace_seq_puts(s, " ==> ");
+
+	if (pevent_get_field_val(s, event, "next_pid", record, &val, 1))
+		return trace_seq_putc(s, '!');
+
+	field = pevent_find_any_field(event, "next_comm");
+	if (field) {
+		write_and_save_comm(field, record, s, val);
+		trace_seq_putc(s, ':');
+	}
+	trace_seq_printf(s, "%lld", val);
+
+	if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
+		trace_seq_printf(s, " [%lld]", val);
+
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "sched", "sched_switch",
+				      sched_switch_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup",
+				      sched_wakeup_handler, NULL);
+
+	pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
+				      sched_wakeup_handler, NULL);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/24] tools list traceevent: Add function plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (14 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 15/24] tools list traceevent: Add sched_switch plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 17/24] tools list traceevent: Update kvm plugin with is_writable_pte helper Jiri Olsa
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Backporting function plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile          |   2 +-
 tools/lib/traceevent/plugin_function.c | 182 +++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_function.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 3a5ffd3..c926d09 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -209,7 +209,7 @@ PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
 PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o \
-	plugin_mac80211.o plugin_sched_switch.o
+	plugin_mac80211.o plugin_sched_switch.o plugin_function.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_function.c b/tools/lib/traceevent/plugin_function.c
new file mode 100644
index 0000000..d0444ba
--- /dev/null
+++ b/tools/lib/traceevent/plugin_function.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event-parse.h"
+#include "event-utils.h"
+
+static struct func_stack {
+	int index;
+	int size;
+	char **stack;
+} *fstack;
+
+static int cpus = -1;
+
+#define STK_BLK 10
+
+struct plugin_option plugin_options[] =
+{
+	{
+		.name = "parent",
+		.plugin_alias = "ftrace",
+		.description =
+		"Print parent of functions for function events",
+	},
+	{
+		.name = "indent",
+		.plugin_alias = "ftrace",
+		.description =
+		"Try to show function call indents, based on parents",
+		.set = 1,
+	},
+	{
+		.name = NULL,
+	}
+};
+
+static struct plugin_option *ftrace_parent = &plugin_options[0];
+static struct plugin_option *ftrace_indent = &plugin_options[1];
+
+static void add_child(struct func_stack *stack, const char *child, int pos)
+{
+	int i;
+
+	if (!child)
+		return;
+
+	if (pos < stack->size)
+		free(stack->stack[pos]);
+	else {
+		if (!stack->stack)
+			stack->stack = malloc_or_die(sizeof(char *) * STK_BLK);
+		else
+			stack->stack = realloc(stack->stack, sizeof(char *) *
+					       (stack->size + STK_BLK));
+		for (i = stack->size; i < stack->size + STK_BLK; i++)
+			stack->stack[i] = NULL;
+		stack->size += STK_BLK;
+	}
+
+	stack->stack[pos] = strdup(child);
+}
+
+static int get_index(const char *parent, const char *child, int cpu)
+{
+	int i;
+
+	if (cpu < 0)
+		return 0;
+
+	if (cpu > cpus) {
+		if (fstack)
+			fstack = realloc(fstack, sizeof(*fstack) * (cpu + 1));
+		else
+			fstack = malloc_or_die(sizeof(*fstack) * (cpu + 1));
+
+		/* Account for holes in the cpu count */
+		for (i = cpus + 1; i <= cpu; i++)
+			memset(&fstack[i], 0, sizeof(fstack[i]));
+		cpus = cpu;
+	}
+
+	for (i = 0; i < fstack[cpu].size && fstack[cpu].stack[i]; i++) {
+		if (strcmp(parent, fstack[cpu].stack[i]) == 0) {
+			add_child(&fstack[cpu], child, i+1);
+			return i;
+		}
+	}
+
+	/* Not found */
+	add_child(&fstack[cpu], parent, 0);
+	add_child(&fstack[cpu], child, 1);
+	return 0;
+}
+
+static int function_handler(struct trace_seq *s, struct pevent_record *record,
+			    struct event_format *event, void *context)
+{
+	struct pevent *pevent = event->pevent;
+	unsigned long long function;
+	unsigned long long pfunction;
+	const char *func;
+	const char *parent;
+	int i, index = 0;
+
+	if (pevent_get_field_val(s, event, "ip", record, &function, 1))
+		return trace_seq_putc(s, '!');
+
+	func = pevent_find_function(pevent, function);
+
+	if (pevent_get_field_val(s, event, "parent_ip", record, &pfunction, 1))
+		return trace_seq_putc(s, '!');
+
+	parent = pevent_find_function(pevent, pfunction);
+
+	if (ftrace_indent->set)
+		index = get_index(parent, func, record->cpu);
+
+	for (i = 0; i < index; i++)
+		trace_seq_printf(s, "   ");
+
+	if (func)
+		trace_seq_printf(s, "%s", func);
+	else
+		trace_seq_printf(s, "0x%llx", function);
+
+	if (ftrace_parent->set) {
+		trace_seq_printf(s, " <-- ");
+		if (parent)
+			trace_seq_printf(s, "%s", parent);
+		else
+			trace_seq_printf(s, "0x%llx", pfunction);
+	}
+
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_event_handler(pevent, -1, "ftrace", "function",
+				      function_handler, NULL);
+
+	traceevent_add_options("ftrace", plugin_options);
+
+	return 0;
+}
+
+void PEVENT_PLUGIN_UNLOADER(void)
+{
+	int i, x;
+
+	for (i = 0; i <= cpus; i++) {
+		for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++)
+			free(fstack[i].stack[x]);
+		free(fstack[i].stack);
+	}
+
+	traceevent_remove_options(plugin_options);
+
+	free(fstack);
+	fstack = NULL;
+	cpus = -1;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/24] tools list traceevent: Update kvm plugin with is_writable_pte helper
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (15 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 16/24] tools list traceevent: Add function plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 18/24] tools list traceevent: Add xen plugin Jiri Olsa
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding is_writable_pte print helper function,
so the kvmmmu:fast_page_fault print format
gets resolved properly.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/plugin_kvm.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tools/lib/traceevent/plugin_kvm.c b/tools/lib/traceevent/plugin_kvm.c
index a776cd6..ce805c5 100644
--- a/tools/lib/traceevent/plugin_kvm.c
+++ b/tools/lib/traceevent/plugin_kvm.c
@@ -427,6 +427,16 @@ static int kvm_mmu_get_page_handler(struct trace_seq *s,
 	return kvm_mmu_print_role(s, record, event, context);
 }
 
+#define PT_WRITABLE_SHIFT 1
+#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT)
+
+unsigned long long process_is_writable_pte(struct trace_seq *s,
+					   unsigned long long *args)
+{
+	unsigned long pte = args[0];
+	return pte & PT_WRITABLE_MASK;
+}
+
 int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
 {
 	init_disassembler();
@@ -460,5 +470,11 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
 			"kvm_mmu_prepare_zap_page", kvm_mmu_print_role,
 			NULL);
 
+	pevent_register_print_function(pevent,
+				       process_is_writable_pte,
+				       PEVENT_FUNC_ARG_INT,
+				       "is_writable_pte",
+				       PEVENT_FUNC_ARG_LONG,
+				       PEVENT_FUNC_ARG_VOID);
 	return 0;
 }
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/24] tools list traceevent: Add xen plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (16 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 17/24] tools list traceevent: Update kvm plugin with is_writable_pte helper Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 19/24] tools list traceevent: Add scsi plugin Jiri Olsa
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding xen plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile     |   2 +-
 tools/lib/traceevent/plugin_xen.c | 132 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_xen.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index c926d09..268ac9c 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -209,7 +209,7 @@ PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
 PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o \
-	plugin_mac80211.o plugin_sched_switch.o plugin_function.o
+	plugin_mac80211.o plugin_sched_switch.o plugin_function.o plugin_xen.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_xen.c b/tools/lib/traceevent/plugin_xen.c
new file mode 100644
index 0000000..b2f689f
--- /dev/null
+++ b/tools/lib/traceevent/plugin_xen.c
@@ -0,0 +1,132 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "event-parse.h"
+
+#define __HYPERVISOR_set_trap_table        0
+#define __HYPERVISOR_mmu_update            1
+#define __HYPERVISOR_set_gdt               2
+#define __HYPERVISOR_stack_switch          3
+#define __HYPERVISOR_set_callbacks         4
+#define __HYPERVISOR_fpu_taskswitch        5
+#define __HYPERVISOR_sched_op_compat       6
+#define __HYPERVISOR_dom0_op               7
+#define __HYPERVISOR_set_debugreg          8
+#define __HYPERVISOR_get_debugreg          9
+#define __HYPERVISOR_update_descriptor    10
+#define __HYPERVISOR_memory_op            12
+#define __HYPERVISOR_multicall            13
+#define __HYPERVISOR_update_va_mapping    14
+#define __HYPERVISOR_set_timer_op         15
+#define __HYPERVISOR_event_channel_op_compat 16
+#define __HYPERVISOR_xen_version          17
+#define __HYPERVISOR_console_io           18
+#define __HYPERVISOR_physdev_op_compat    19
+#define __HYPERVISOR_grant_table_op       20
+#define __HYPERVISOR_vm_assist            21
+#define __HYPERVISOR_update_va_mapping_otherdomain 22
+#define __HYPERVISOR_iret                 23 /* x86 only */
+#define __HYPERVISOR_vcpu_op              24
+#define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
+#define __HYPERVISOR_mmuext_op            26
+#define __HYPERVISOR_acm_op               27
+#define __HYPERVISOR_nmi_op               28
+#define __HYPERVISOR_sched_op             29
+#define __HYPERVISOR_callback_op          30
+#define __HYPERVISOR_xenoprof_op          31
+#define __HYPERVISOR_event_channel_op     32
+#define __HYPERVISOR_physdev_op           33
+#define __HYPERVISOR_hvm_op               34
+#define __HYPERVISOR_tmem_op              38
+
+/* Architecture-specific hypercall definitions. */
+#define __HYPERVISOR_arch_0               48
+#define __HYPERVISOR_arch_1               49
+#define __HYPERVISOR_arch_2               50
+#define __HYPERVISOR_arch_3               51
+#define __HYPERVISOR_arch_4               52
+#define __HYPERVISOR_arch_5               53
+#define __HYPERVISOR_arch_6               54
+#define __HYPERVISOR_arch_7               55
+
+#define N(x)	[__HYPERVISOR_##x] = "("#x")"
+static const char *xen_hypercall_names[] = {
+	N(set_trap_table),
+	N(mmu_update),
+	N(set_gdt),
+	N(stack_switch),
+	N(set_callbacks),
+	N(fpu_taskswitch),
+	N(sched_op_compat),
+	N(dom0_op),
+	N(set_debugreg),
+	N(get_debugreg),
+	N(update_descriptor),
+	N(memory_op),
+	N(multicall),
+	N(update_va_mapping),
+	N(set_timer_op),
+	N(event_channel_op_compat),
+	N(xen_version),
+	N(console_io),
+	N(physdev_op_compat),
+	N(grant_table_op),
+	N(vm_assist),
+	N(update_va_mapping_otherdomain),
+	N(iret),
+	N(vcpu_op),
+	N(set_segment_base),
+	N(mmuext_op),
+	N(acm_op),
+	N(nmi_op),
+	N(sched_op),
+	N(callback_op),
+	N(xenoprof_op),
+	N(event_channel_op),
+	N(physdev_op),
+	N(hvm_op),
+
+/* Architecture-specific hypercall definitions. */
+	N(arch_0),
+	N(arch_1),
+	N(arch_2),
+	N(arch_3),
+	N(arch_4),
+	N(arch_5),
+	N(arch_6),
+	N(arch_7),
+};
+#undef N
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static const char *xen_hypercall_name(unsigned op)
+{
+	if (op < ARRAY_SIZE(xen_hypercall_names) &&
+	    xen_hypercall_names[op] != NULL)
+		return xen_hypercall_names[op];
+
+	return "";
+}
+
+unsigned long long process_xen_hypercall_name(struct trace_seq *s,
+					      unsigned long long *args)
+{
+	unsigned int op = args[0];
+
+	trace_seq_printf(s, "%s", xen_hypercall_name(op));
+
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_print_function(pevent,
+				       process_xen_hypercall_name,
+				       PEVENT_FUNC_ARG_STRING,
+				       "xen_hypercall_name",
+				       PEVENT_FUNC_ARG_INT,
+				       PEVENT_FUNC_ARG_VOID);
+
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 19/24] tools list traceevent: Add scsi plugin
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (17 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 18/24] tools list traceevent: Add xen plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 20/24] tools list traceevent: Change pevent_parse_event to return event format Jiri Olsa
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding scsi plugin.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/Makefile      |   2 +-
 tools/lib/traceevent/plugin_scsi.c | 431 +++++++++++++++++++++++++++++++++++++
 2 files changed, 432 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/traceevent/plugin_scsi.c

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 268ac9c..0806c15 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -209,7 +209,7 @@ PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-
 PEVENT_LIB_OBJS += kbuffer-parse.o
 
 PLUGIN_OBJS = plugin_jbd2.o plugin_blk.o plugin_hrtimer.o plugin_kmem.o plugin_kvm.o \
-	plugin_mac80211.o plugin_sched_switch.o plugin_function.o plugin_xen.o
+	plugin_mac80211.o plugin_sched_switch.o plugin_function.o plugin_xen.o plugin_scsi.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
diff --git a/tools/lib/traceevent/plugin_scsi.c b/tools/lib/traceevent/plugin_scsi.c
new file mode 100644
index 0000000..f7d2aae
--- /dev/null
+++ b/tools/lib/traceevent/plugin_scsi.c
@@ -0,0 +1,431 @@
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "event-parse.h"
+
+typedef unsigned long sector_t;
+typedef uint64_t    u64;
+typedef unsigned int  u32;
+
+/*
+ *      SCSI opcodes
+ */
+
+#define TEST_UNIT_READY       0x00
+#define REZERO_UNIT           0x01
+#define REQUEST_SENSE         0x03
+#define FORMAT_UNIT           0x04
+#define READ_BLOCK_LIMITS     0x05
+#define REASSIGN_BLOCKS       0x07
+#define INITIALIZE_ELEMENT_STATUS 0x07
+#define READ_6                0x08
+#define WRITE_6               0x0a
+#define SEEK_6                0x0b
+#define READ_REVERSE          0x0f
+#define WRITE_FILEMARKS       0x10
+#define SPACE                 0x11
+#define INQUIRY               0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT           0x15
+#define RESERVE               0x16
+#define RELEASE               0x17
+#define COPY                  0x18
+#define ERASE                 0x19
+#define MODE_SENSE            0x1a
+#define START_STOP            0x1b
+#define RECEIVE_DIAGNOSTIC    0x1c
+#define SEND_DIAGNOSTIC       0x1d
+#define ALLOW_MEDIUM_REMOVAL  0x1e
+
+#define READ_FORMAT_CAPACITIES 0x23
+#define SET_WINDOW            0x24
+#define READ_CAPACITY         0x25
+#define READ_10               0x28
+#define WRITE_10              0x2a
+#define SEEK_10               0x2b
+#define POSITION_TO_ELEMENT   0x2b
+#define WRITE_VERIFY          0x2e
+#define VERIFY                0x2f
+#define SEARCH_HIGH           0x30
+#define SEARCH_EQUAL          0x31
+#define SEARCH_LOW            0x32
+#define SET_LIMITS            0x33
+#define PRE_FETCH             0x34
+#define READ_POSITION         0x34
+#define SYNCHRONIZE_CACHE     0x35
+#define LOCK_UNLOCK_CACHE     0x36
+#define READ_DEFECT_DATA      0x37
+#define MEDIUM_SCAN           0x38
+#define COMPARE               0x39
+#define COPY_VERIFY           0x3a
+#define WRITE_BUFFER          0x3b
+#define READ_BUFFER           0x3c
+#define UPDATE_BLOCK          0x3d
+#define READ_LONG             0x3e
+#define WRITE_LONG            0x3f
+#define CHANGE_DEFINITION     0x40
+#define WRITE_SAME            0x41
+#define UNMAP		      0x42
+#define READ_TOC              0x43
+#define READ_HEADER           0x44
+#define GET_EVENT_STATUS_NOTIFICATION 0x4a
+#define LOG_SELECT            0x4c
+#define LOG_SENSE             0x4d
+#define XDWRITEREAD_10        0x53
+#define MODE_SELECT_10        0x55
+#define RESERVE_10            0x56
+#define RELEASE_10            0x57
+#define MODE_SENSE_10         0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define VARIABLE_LENGTH_CMD   0x7f
+#define REPORT_LUNS           0xa0
+#define SECURITY_PROTOCOL_IN  0xa2
+#define MAINTENANCE_IN        0xa3
+#define MAINTENANCE_OUT       0xa4
+#define MOVE_MEDIUM           0xa5
+#define EXCHANGE_MEDIUM       0xa6
+#define READ_12               0xa8
+#define WRITE_12              0xaa
+#define READ_MEDIA_SERIAL_NUMBER 0xab
+#define WRITE_VERIFY_12       0xae
+#define VERIFY_12	      0xaf
+#define SEARCH_HIGH_12        0xb0
+#define SEARCH_EQUAL_12       0xb1
+#define SEARCH_LOW_12         0xb2
+#define SECURITY_PROTOCOL_OUT 0xb5
+#define READ_ELEMENT_STATUS   0xb8
+#define SEND_VOLUME_TAG       0xb6
+#define WRITE_LONG_2          0xea
+#define EXTENDED_COPY         0x83
+#define RECEIVE_COPY_RESULTS  0x84
+#define ACCESS_CONTROL_IN     0x86
+#define ACCESS_CONTROL_OUT    0x87
+#define READ_16               0x88
+#define WRITE_16              0x8a
+#define READ_ATTRIBUTE        0x8c
+#define WRITE_ATTRIBUTE	      0x8d
+#define VERIFY_16	      0x8f
+#define SYNCHRONIZE_CACHE_16  0x91
+#define WRITE_SAME_16	      0x93
+#define SERVICE_ACTION_IN     0x9e
+/* values for service action in */
+#define	SAI_READ_CAPACITY_16  0x10
+#define SAI_GET_LBA_STATUS    0x12
+/* values for VARIABLE_LENGTH_CMD service action codes
+ * see spc4r17 Section D.3.5, table D.7 and D.8 */
+#define VLC_SA_RECEIVE_CREDENTIAL 0x1800
+/* values for maintenance in */
+#define MI_REPORT_IDENTIFYING_INFORMATION 0x05
+#define MI_REPORT_TARGET_PGS  0x0a
+#define MI_REPORT_ALIASES     0x0b
+#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c
+#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d
+#define MI_REPORT_PRIORITY   0x0e
+#define MI_REPORT_TIMESTAMP  0x0f
+#define MI_MANAGEMENT_PROTOCOL_IN 0x10
+/* value for MI_REPORT_TARGET_PGS ext header */
+#define MI_EXT_HDR_PARAM_FMT  0x20
+/* values for maintenance out */
+#define MO_SET_IDENTIFYING_INFORMATION 0x06
+#define MO_SET_TARGET_PGS     0x0a
+#define MO_CHANGE_ALIASES     0x0b
+#define MO_SET_PRIORITY       0x0e
+#define MO_SET_TIMESTAMP      0x0f
+#define MO_MANAGEMENT_PROTOCOL_OUT 0x10
+/* values for variable length command */
+#define XDREAD_32	      0x03
+#define XDWRITE_32	      0x04
+#define XPWRITE_32	      0x06
+#define XDWRITEREAD_32	      0x07
+#define READ_32		      0x09
+#define VERIFY_32	      0x0a
+#define WRITE_32	      0x0b
+#define WRITE_SAME_32	      0x0d
+
+#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
+#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9])
+
+static const char *
+scsi_trace_misc(struct trace_seq *, unsigned char *, int);
+
+static const char *
+scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+	sector_t lba = 0, txlen = 0;
+
+	lba |= ((cdb[1] & 0x1F) << 16);
+	lba |=  (cdb[2] << 8);
+	lba |=   cdb[3];
+	txlen = cdb[4];
+
+	trace_seq_printf(p, "lba=%llu txlen=%llu",
+			 (unsigned long long)lba, (unsigned long long)txlen);
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+	sector_t lba = 0, txlen = 0;
+
+	lba |= (cdb[2] << 24);
+	lba |= (cdb[3] << 16);
+	lba |= (cdb[4] << 8);
+	lba |=  cdb[5];
+	txlen |= (cdb[7] << 8);
+	txlen |=  cdb[8];
+
+	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
+			 (unsigned long long)lba, (unsigned long long)txlen,
+			 cdb[1] >> 5);
+
+	if (cdb[0] == WRITE_SAME)
+		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
+
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+	sector_t lba = 0, txlen = 0;
+
+	lba |= (cdb[2] << 24);
+	lba |= (cdb[3] << 16);
+	lba |= (cdb[4] << 8);
+	lba |=  cdb[5];
+	txlen |= (cdb[6] << 24);
+	txlen |= (cdb[7] << 16);
+	txlen |= (cdb[8] << 8);
+	txlen |=  cdb[9];
+
+	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
+			 (unsigned long long)lba, (unsigned long long)txlen,
+			 cdb[1] >> 5);
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+	sector_t lba = 0, txlen = 0;
+
+	lba |= ((u64)cdb[2] << 56);
+	lba |= ((u64)cdb[3] << 48);
+	lba |= ((u64)cdb[4] << 40);
+	lba |= ((u64)cdb[5] << 32);
+	lba |= (cdb[6] << 24);
+	lba |= (cdb[7] << 16);
+	lba |= (cdb[8] << 8);
+	lba |=  cdb[9];
+	txlen |= (cdb[10] << 24);
+	txlen |= (cdb[11] << 16);
+	txlen |= (cdb[12] << 8);
+	txlen |=  cdb[13];
+
+	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
+			 (unsigned long long)lba, (unsigned long long)txlen,
+			 cdb[1] >> 5);
+
+	if (cdb[0] == WRITE_SAME_16)
+		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
+
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len, *cmd;
+	sector_t lba = 0, txlen = 0;
+	u32 ei_lbrt = 0;
+
+	switch (SERVICE_ACTION32(cdb)) {
+	case READ_32:
+		cmd = "READ";
+		break;
+	case VERIFY_32:
+		cmd = "VERIFY";
+		break;
+	case WRITE_32:
+		cmd = "WRITE";
+		break;
+	case WRITE_SAME_32:
+		cmd = "WRITE_SAME";
+		break;
+	default:
+		trace_seq_printf(p, "UNKNOWN");
+		goto out;
+	}
+
+	lba |= ((u64)cdb[12] << 56);
+	lba |= ((u64)cdb[13] << 48);
+	lba |= ((u64)cdb[14] << 40);
+	lba |= ((u64)cdb[15] << 32);
+	lba |= (cdb[16] << 24);
+	lba |= (cdb[17] << 16);
+	lba |= (cdb[18] << 8);
+	lba |=  cdb[19];
+	ei_lbrt |= (cdb[20] << 24);
+	ei_lbrt |= (cdb[21] << 16);
+	ei_lbrt |= (cdb[22] << 8);
+	ei_lbrt |=  cdb[23];
+	txlen |= (cdb[28] << 24);
+	txlen |= (cdb[29] << 16);
+	txlen |= (cdb[30] << 8);
+	txlen |=  cdb[31];
+
+	trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u",
+			 cmd, (unsigned long long)lba,
+			 (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt);
+
+	if (SERVICE_ACTION32(cdb) == WRITE_SAME_32)
+		trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1);
+
+out:
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+	unsigned int regions = cdb[7] << 8 | cdb[8];
+
+	trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len, *cmd;
+	sector_t lba = 0;
+	u32 alloc_len = 0;
+
+	switch (SERVICE_ACTION16(cdb)) {
+	case SAI_READ_CAPACITY_16:
+		cmd = "READ_CAPACITY_16";
+		break;
+	case SAI_GET_LBA_STATUS:
+		cmd = "GET_LBA_STATUS";
+		break;
+	default:
+		trace_seq_printf(p, "UNKNOWN");
+		goto out;
+	}
+
+	lba |= ((u64)cdb[2] << 56);
+	lba |= ((u64)cdb[3] << 48);
+	lba |= ((u64)cdb[4] << 40);
+	lba |= ((u64)cdb[5] << 32);
+	lba |= (cdb[6] << 24);
+	lba |= (cdb[7] << 16);
+	lba |= (cdb[8] << 8);
+	lba |=  cdb[9];
+	alloc_len |= (cdb[10] << 24);
+	alloc_len |= (cdb[11] << 16);
+	alloc_len |= (cdb[12] << 8);
+	alloc_len |=  cdb[13];
+
+	trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd,
+			 (unsigned long long)lba, alloc_len);
+
+out:
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+static const char *
+scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	switch (SERVICE_ACTION32(cdb)) {
+	case READ_32:
+	case VERIFY_32:
+	case WRITE_32:
+	case WRITE_SAME_32:
+		return scsi_trace_rw32(p, cdb, len);
+	default:
+		return scsi_trace_misc(p, cdb, len);
+	}
+}
+
+static const char *
+scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	const char *ret = p->buffer + p->len;
+
+	trace_seq_printf(p, "-");
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
+
+const char *
+scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
+{
+	switch (cdb[0]) {
+	case READ_6:
+	case WRITE_6:
+		return scsi_trace_rw6(p, cdb, len);
+	case READ_10:
+	case VERIFY:
+	case WRITE_10:
+	case WRITE_SAME:
+		return scsi_trace_rw10(p, cdb, len);
+	case READ_12:
+	case VERIFY_12:
+	case WRITE_12:
+		return scsi_trace_rw12(p, cdb, len);
+	case READ_16:
+	case VERIFY_16:
+	case WRITE_16:
+	case WRITE_SAME_16:
+		return scsi_trace_rw16(p, cdb, len);
+	case UNMAP:
+		return scsi_trace_unmap(p, cdb, len);
+	case SERVICE_ACTION_IN:
+		return scsi_trace_service_action_in(p, cdb, len);
+	case VARIABLE_LENGTH_CMD:
+		return scsi_trace_varlen(p, cdb, len);
+	default:
+		return scsi_trace_misc(p, cdb, len);
+	}
+}
+
+unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
+						unsigned long long *args)
+{
+	scsi_trace_parse_cdb(s, (unsigned char *) args[0], args[1]);
+	return 0;
+}
+
+int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+{
+	pevent_register_print_function(pevent,
+				       process_scsi_trace_parse_cdb,
+				       PEVENT_FUNC_ARG_STRING,
+				       "scsi_trace_parse_cdb",
+				       PEVENT_FUNC_ARG_PTR,
+				       PEVENT_FUNC_ARG_INT,
+				       PEVENT_FUNC_ARG_VOID);
+	return 0;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 20/24] tools list traceevent: Change pevent_parse_event to return event format
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (18 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 19/24] tools list traceevent: Add scsi plugin Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 21/24] perf tools: Add traceevents Makefile install rule Jiri Olsa
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Changing pevent_parse_event to return 'struct event_format',
for the parsed event if the return pointer is specified.

This way we can remove pevent_parse_format which does the
same stuff just without 'struct pevent' object. We will
need this change in following patches.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.c  | 28 +++++++---------------------
 tools/lib/traceevent/event-parse.h  |  7 ++++---
 tools/perf/util/evsel.c             |  2 +-
 tools/perf/util/trace-event-parse.c |  4 ++--
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 7bc75d6..4a2f223 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5044,25 +5044,6 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
 }
 
 /**
- * pevent_parse_format - parse the event format
- * @buf: the buffer storing the event format string
- * @size: the size of @buf
- * @sys: the system the event belongs to
- *
- * This parses the event format and creates an event structure
- * to quickly parse raw data for a given event.
- *
- * These files currently come from:
- *
- * /sys/kernel/debug/tracing/events/.../.../format
- */
-enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
-				      unsigned long size, const char *sys)
-{
-	return __pevent_parse_format(eventp, NULL, buf, size, sys);
-}
-
-/**
  * pevent_parse_event - parse the event format
  * @pevent: the handle to the pevent
  * @buf: the buffer storing the event format string
@@ -5076,7 +5057,9 @@ enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *
  *
  * /sys/kernel/debug/tracing/events/.../.../format
  */
-enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
+enum pevent_errno pevent_parse_event(struct pevent *pevent,
+				     struct event_format **format,
+				     const char *buf,
 				     unsigned long size, const char *sys)
 {
 	struct event_format *event = NULL;
@@ -5085,7 +5068,7 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
 	if (event == NULL)
 		return ret;
 
-	if (add_event(pevent, event)) {
+	if (pevent && add_event(pevent, event)) {
 		ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
 		goto event_add_failed;
 	}
@@ -5094,6 +5077,9 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
 	if (PRINT_ARGS && event->print_fmt.args)
 		print_args(event->print_fmt.args);
 
+	if (format)
+		*format = event;
+
 	return 0;
 
 event_add_failed:
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index a2d6306..aa002fb 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -557,10 +557,11 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
 int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
 			     int long_size);
 
-enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
+enum pevent_errno pevent_parse_event(struct pevent *pevent,
+				     struct event_format **format,
+				     const char *buf,
 				     unsigned long size, const char *sys);
-enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
-				      unsigned long size, const char *sys);
+
 void pevent_free_format(struct event_format *event);
 
 void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e8745fb..45a2a83 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -207,7 +207,7 @@ struct event_format *event_format__new(const char *sys, const char *name)
 		size += n;
 	} while (n > 0);
 
-	pevent_parse_format(&format, bf, size, sys);
+	pevent_parse_event(NULL, &format, bf, size, sys);
 
 out_free_bf:
 	free(bf);
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index da28065..02eeea45 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -198,13 +198,13 @@ void parse_ftrace_printk(struct pevent *pevent,
 
 int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
 {
-	return pevent_parse_event(pevent, buf, size, "ftrace");
+	return pevent_parse_event(pevent, NULL, buf, size, "ftrace");
 }
 
 int parse_event_file(struct pevent *pevent,
 		     char *buf, unsigned long size, char *sys)
 {
-	return pevent_parse_event(pevent, buf, size, sys);
+	return pevent_parse_event(pevent, NULL, buf, size, sys);
 }
 
 struct event_format *trace_find_next_event(struct pevent *pevent,
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 21/24] perf tools: Add traceevents Makefile install rule
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (19 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 20/24] tools list traceevent: Change pevent_parse_event to return event format Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 22/24] perf tools: Add trace-event object Jiri Olsa
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Instructing perf to install plugins into:
  $HOME/.traceevent/plugins
     - if installed localy under $HOME
  $(perfexecdir)/traceevent/plugins
     - if installed globally

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/Makefile        | 11 ++++++++---
 tools/perf/config/Makefile |  2 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index f5998da..140462a 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -665,12 +665,14 @@ $(sort $(dir $(DIRECTORY_DEPS))):
 $(LIB_FILE): $(LIB_OBJS)
 	$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
 
+LIBTRACEEVENT_FLAGS=$(QUIET_SUBDIR1) O=$(OUTPUT) plugin_dir=$(plugindir_SQ)
+
 # libtraceevent.a
 $(LIBTRACEEVENT):
-	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
+	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) libtraceevent.a plugins
 
 $(LIBTRACEEVENT)-clean:
-	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
+	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) clean
 
 # if subdir is set, we've been called from above so target has been built
 # already
@@ -684,6 +686,9 @@ ifeq ($(subdir),)
 	$(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
 endif
 
+install-traceevent-plugins:
+	$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins
+
 help:
 	@echo 'Perf make targets:'
 	@echo '  doc		- make *all* documentation (see below)'
@@ -791,7 +796,7 @@ endif
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
 	$(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
 
-install: install-bin try-install-man
+install: install-bin try-install-man install-traceevent-plugins
 
 install-python_ext:
 	$(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f6d720d..5e967b9 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -457,6 +457,7 @@ sysconfdir = $(prefix)/etc
 ETC_PERFCONFIG = etc/perfconfig
 endif
 lib = lib
+plugindir=$(perfexecdir)/traceevent/plugins
 
 # Shell quote (do not use $(call) to accommodate ancient setups);
 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
@@ -476,3 +477,4 @@ else
 perfexec_instdir = $(prefix)/$(perfexecdir)
 endif
 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
+plugindir_SQ= $(subst ','\'',$(prefix)/$(plugindir))
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 22/24] perf tools: Add trace-event object
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (20 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 21/24] perf tools: Add traceevents Makefile install rule Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 23/24] perf tools: Add traceevent object to interface traceevent lib Jiri Olsa
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Add trace-event object to keep together 'struct pevent'
object with its loaded plugins with following interface:

int trace_event__init(struct trace_event *t);
  - initalizes 'struct pevent' object and loads plugins for it

void trace_event__cleanup(struct trace_event *t);
  - cleanups both 'struct pevent' and plugins

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/Makefile                 |  1 +
 tools/perf/builtin-script.c         |  2 +-
 tools/perf/util/header.c            |  8 ++++----
 tools/perf/util/python-ext-sources  |  1 +
 tools/perf/util/session.c           |  2 +-
 tools/perf/util/session.h           |  3 ++-
 tools/perf/util/trace-event-parse.c | 13 -------------
 tools/perf/util/trace-event-read.c  | 20 +++++++++++---------
 tools/perf/util/trace-event.c       | 21 +++++++++++++++++++++
 tools/perf/util/trace-event.h       | 13 ++++++++++---
 10 files changed, 52 insertions(+), 32 deletions(-)
 create mode 100644 tools/perf/util/trace-event.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 140462a..4930fc2 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -347,6 +347,7 @@ LIB_OBJS += $(OUTPUT)util/pmu-bison.o
 LIB_OBJS += $(OUTPUT)util/trace-event-read.o
 LIB_OBJS += $(OUTPUT)util/trace-event-info.o
 LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
+LIB_OBJS += $(OUTPUT)util/trace-event.o
 LIB_OBJS += $(OUTPUT)util/svghelper.o
 LIB_OBJS += $(OUTPUT)util/sort.o
 LIB_OBJS += $(OUTPUT)util/hist.o
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 93a34ce..160a5ce 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1538,7 +1538,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 			return -1;
 		}
 
-		err = scripting_ops->generate_script(session->pevent,
+		err = scripting_ops->generate_script(session->tevent.pevent,
 						     "perf-script");
 		goto out;
 	}
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a33197a..11a78d8 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2799,11 +2799,11 @@ int perf_session__read_header(struct perf_session *session)
 
 	symbol_conf.nr_events = nr_attrs;
 
-	perf_header__process_sections(header, fd, &session->pevent,
+	perf_header__process_sections(header, fd, &session->tevent,
 				      perf_file_section__process);
 
 	if (perf_evlist__prepare_tracepoint_events(session->evlist,
-						   session->pevent))
+						   session->tevent.pevent))
 		goto out_delete_evlist;
 
 	return 0;
@@ -2967,7 +2967,7 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
 	lseek(session->fd, offset + sizeof(struct tracing_data_event),
 	      SEEK_SET);
 
-	size_read = trace_report(session->fd, &session->pevent,
+	size_read = trace_report(session->fd, &session->tevent,
 				 session->repipe);
 	padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
 
@@ -2989,7 +2989,7 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
 	}
 
 	perf_evlist__prepare_tracepoint_events(session->evlist,
-					       session->pevent);
+					       session->tevent.pevent);
 
 	return size_read + padding;
 }
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index f75ae1b..19ab265 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -18,4 +18,5 @@ util/cgroup.c
 util/rblist.c
 util/strlist.c
 util/sysfs.c
+util/trace-event.c
 ../../lib/rbtree.c
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 07642a7..a3427b3 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1637,7 +1637,7 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
 			goto out_free;
 
 		*name++ = '\0';
-		format = pevent_find_event_by_name(session->pevent,
+		format = pevent_find_event_by_name(session->tevent.pevent,
 						   tracepoint, name);
 		if (format == NULL) {
 			/*
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 3aa75fb..a544c59 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -1,6 +1,7 @@
 #ifndef __PERF_SESSION_H
 #define __PERF_SESSION_H
 
+#include "trace-event.h"
 #include "hist.h"
 #include "event.h"
 #include "header.h"
@@ -32,7 +33,7 @@ struct perf_session {
 	unsigned long		size;
 	struct machines		machines;
 	struct perf_evlist	*evlist;
-	struct pevent		*pevent;
+	struct trace_event	tevent;
 	struct events_stats	stats;
 	int			fd;
 	bool			fd_pipe;
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 02eeea45..8a70c18 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -28,19 +28,6 @@
 #include "util.h"
 #include "trace-event.h"
 
-struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
-{
-	struct pevent *pevent = pevent_alloc();
-
-	if (pevent != NULL) {
-		pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
-		pevent_set_file_bigendian(pevent, file_bigendian);
-		pevent_set_host_bigendian(pevent, host_bigendian);
-	}
-
-	return pevent;
-}
-
 static int get_common_field(struct scripting_context *context,
 			    int *offset, int *size, const char *type)
 {
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index f211227..e113e18 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -343,7 +343,7 @@ static int read_event_files(struct pevent *pevent)
 	return 0;
 }
 
-ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
+ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
 {
 	char buf[BUFSIZ];
 	char test[] = { 23, 8, 68 };
@@ -356,11 +356,9 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
 	int host_bigendian;
 	int file_long_size;
 	int file_page_size;
-	struct pevent *pevent;
+	struct pevent *pevent = NULL;
 	int err;
 
-	*ppevent = NULL;
-
 	repipe = __repipe;
 	input_fd = fd;
 
@@ -390,12 +388,17 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
 	file_bigendian = buf[0];
 	host_bigendian = bigendian();
 
-	pevent = read_trace_init(file_bigendian, host_bigendian);
-	if (pevent == NULL) {
-		pr_debug("read_trace_init failed");
+	if (trace_event__init(tevent)) {
+		pr_debug("trace_event__init failed");
 		goto out;
 	}
 
+	pevent = tevent->pevent;
+
+	pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
+	pevent_set_file_bigendian(pevent, file_bigendian);
+	pevent_set_host_bigendian(pevent, host_bigendian);
+
 	if (do_read(buf, 1) < 0)
 		goto out;
 	file_long_size = buf[0];
@@ -432,11 +435,10 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
 		pevent_print_printk(pevent);
 	}
 
-	*ppevent = pevent;
 	pevent = NULL;
 
 out:
 	if (pevent)
-		pevent_free(pevent);
+		trace_event__cleanup(tevent);
 	return size;
 }
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
new file mode 100644
index 0000000..a155a77
--- /dev/null
+++ b/tools/perf/util/trace-event.c
@@ -0,0 +1,21 @@
+
+#include <traceevent/event-parse.h>
+#include "trace-event.h"
+
+int trace_event__init(struct trace_event *t)
+{
+	struct pevent *pevent = pevent_alloc();
+
+	if (pevent) {
+		t->plugin_list = traceevent_load_plugins(pevent);
+		t->pevent  = pevent;
+	}
+
+	return pevent ? 0 : -1;
+}
+
+void trace_event__cleanup(struct trace_event *t)
+{
+	pevent_free(t->pevent);
+	traceevent_unload_plugins(t->plugin_list);
+}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 04df631..c099879 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -3,17 +3,24 @@
 
 #include <traceevent/event-parse.h>
 #include "parse-events.h"
-#include "session.h"
 
 struct machine;
 struct perf_sample;
 union perf_event;
 struct perf_tool;
 struct thread;
+struct plugin_list;
+
+struct trace_event {
+	struct pevent *pevent;
+	struct plugin_list *plugin_list;
+};
+
+int trace_event__init(struct trace_event *t);
+void trace_event__cleanup(struct trace_event *t);
 
 int bigendian(void);
 
-struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
 void event_format__print(struct event_format *event,
 			 int cpu, void *data, int size);
 
@@ -27,7 +34,7 @@ raw_field_value(struct event_format *event, const char *name, void *data);
 void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
 void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
 
-ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
+ssize_t trace_report(int fd, struct trace_event *tevent, bool repipe);
 
 struct event_format *trace_find_next_event(struct pevent *pevent,
 					   struct event_format *event);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 23/24] perf tools: Add traceevent object to interface traceevent lib
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (21 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 22/24] perf tools: Add trace-event object Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-01 10:48 ` [PATCH 24/24] perf tools: Overload pr_stat traceevent print function Jiri Olsa
  2013-09-02  8:39 ` [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding traceevent object to interface traceevent lib.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/builtin-trace.c    |   5 ++-
 tools/perf/util/evsel.c       |  44 +------------------
 tools/perf/util/trace-event.c | 100 ++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/trace-event.h |   2 +
 4 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 69a065e..defed87 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -10,6 +10,7 @@
 #include "util/strlist.h"
 #include "util/intlist.h"
 #include "util/thread_map.h"
+#include "trace-event.h"
 
 #include <libaudit.h>
 #include <stdlib.h>
@@ -422,11 +423,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 	sc->fmt  = syscall_fmt__find(sc->name);
 
 	snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
-	sc->tp_format = event_format__new("syscalls", tp_name);
+	sc->tp_format = trace_event__tp_format("syscalls", tp_name);
 
 	if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) {
 		snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias);
-		sc->tp_format = event_format__new("syscalls", tp_name);
+		sc->tp_format = trace_event__tp_format("syscalls", tp_name);
 	}
 
 	if (sc->tp_format == NULL)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 45a2a83..2076eaa 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -23,6 +23,7 @@
 #include "target.h"
 #include "perf_regs.h"
 #include "debug.h"
+#include "trace-event.h"
 
 static struct {
 	bool sample_id_all;
@@ -177,47 +178,6 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
 	return evsel;
 }
 
-struct event_format *event_format__new(const char *sys, const char *name)
-{
-	int fd, n;
-	char *filename;
-	void *bf = NULL, *nbf;
-	size_t size = 0, alloc_size = 0;
-	struct event_format *format = NULL;
-
-	if (asprintf(&filename, "%s/%s/%s/format", tracing_events_path, sys, name) < 0)
-		goto out;
-
-	fd = open(filename, O_RDONLY);
-	if (fd < 0)
-		goto out_free_filename;
-
-	do {
-		if (size == alloc_size) {
-			alloc_size += BUFSIZ;
-			nbf = realloc(bf, alloc_size);
-			if (nbf == NULL)
-				goto out_free_bf;
-			bf = nbf;
-		}
-
-		n = read(fd, bf + size, alloc_size - size);
-		if (n < 0)
-			goto out_free_bf;
-		size += n;
-	} while (n > 0);
-
-	pevent_parse_event(NULL, &format, bf, size, sys);
-
-out_free_bf:
-	free(bf);
-	close(fd);
-out_free_filename:
-	free(filename);
-out:
-	return format;
-}
-
 struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
 {
 	struct perf_evsel *evsel = zalloc(sizeof(*evsel));
@@ -232,7 +192,7 @@ struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
 		if (asprintf(&evsel->name, "%s:%s", sys, name) < 0)
 			goto out_free;
 
-		evsel->tp_format = event_format__new(sys, name);
+		evsel->tp_format = trace_event__tp_format(sys, name);
 		if (evsel->tp_format == NULL)
 			goto out_free;
 
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index a155a77..dd4ced7 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -1,6 +1,17 @@
 
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/kernel.h>
 #include <traceevent/event-parse.h>
 #include "trace-event.h"
+#include "util.h"
+
+static struct trace_event tevent;
 
 int trace_event__init(struct trace_event *t)
 {
@@ -19,3 +30,92 @@ void trace_event__cleanup(struct trace_event *t)
 	pevent_free(t->pevent);
 	traceevent_unload_plugins(t->plugin_list);
 }
+
+static char *debugfs__get_file(const char *file, size_t *sizep)
+{
+	size_t size = 0, alloc_size = 0;
+	void *bf = NULL, *nbf;
+	int fd, n;
+
+	fd = open(file, O_RDONLY);
+	if (fd < 0)
+		return NULL;
+
+	do {
+		if (size == alloc_size) {
+			alloc_size += BUFSIZ;
+			nbf = realloc(bf, alloc_size);
+			if (!nbf)
+				goto out_failed;
+
+			bf = nbf;
+		}
+
+		n = read(fd, bf + size, BUFSIZ);
+		if (n < 0)
+			goto out_failed;
+
+		size += n;
+	} while (n > 0);
+
+	*sizep = size;
+
+	close(fd);
+	return bf;
+
+ out_failed:
+	free(bf);
+	close(fd);
+	return NULL;
+}
+
+static char *get_tracepoint_format(const char *sys, const char *name,
+				   size_t *size)
+{
+	char path[PATH_MAX];
+
+	scnprintf(path, PATH_MAX, "%s/%s/%s/format",
+		  tracing_events_path, sys, name);
+
+	return debugfs__get_file(path, size);
+}
+
+static struct event_format*
+tp_format(const char *sys, const char *name)
+{
+	struct pevent *pevent = tevent.pevent;
+	struct event_format *event = NULL;
+	size_t size;
+	char *data;
+
+	data = get_tracepoint_format(sys, name, &size);
+	if (!data)
+		return NULL;
+
+	pevent_parse_event(pevent, &event, data, size, sys);
+
+	free(data);
+	return event;
+}
+
+struct event_format*
+trace_event__tp_format(const char *sys, const char *name)
+{
+	static bool initialized;
+
+	if (!initialized) {
+		int be = traceevent_host_bigendian();
+		struct pevent *pevent;
+
+		if (trace_event__init(&tevent))
+			return NULL;
+
+		pevent = tevent.pevent;
+		pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
+		pevent_set_file_bigendian(pevent, be);
+		pevent_set_host_bigendian(pevent, be);
+		initialized = true;
+	}
+
+	return tp_format(sys, name);
+}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index c099879..62b0fda 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -18,6 +18,8 @@ struct trace_event {
 
 int trace_event__init(struct trace_event *t);
 void trace_event__cleanup(struct trace_event *t);
+struct event_format*
+trace_event__tp_format(const char *sys, const char *name);
 
 int bigendian(void);
 
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 24/24] perf tools: Overload pr_stat traceevent print function
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (22 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 23/24] perf tools: Add traceevent object to interface traceevent lib Jiri Olsa
@ 2013-09-01 10:48 ` Jiri Olsa
  2013-09-02  8:39 ` [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-01 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

The traceevent lib uses pr_stat to display all standard
info. It's defined as __weak. Overloading it with perf
version plugged into perf output system logic.

Displaying the pr_stat stuff under '-v' option.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/debug.c | 16 ++++++++++++++++
 tools/perf/util/debug.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 399e74c..dc93bc3 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -33,6 +33,22 @@ int eprintf(int level, const char *fmt, ...)
 	return ret;
 }
 
+/*
+ * Overloading libtraceevent standard info print
+ * function, display with -v in perf.
+ */
+void pr_stat(const char *fmt, ...)
+{
+	va_list args;
+
+	if (verbose >= 1) {
+		va_start(args, fmt);
+		vfprintf(stderr, fmt, args);
+		fprintf(stderr, "\n");
+		va_end(args);
+	}
+}
+
 int dump_printf(const char *fmt, ...)
 {
 	va_list args;
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index efbd988..443694c 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -17,4 +17,6 @@ void trace_event(union perf_event *event);
 int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
 int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
 
+void pr_stat(const char *fmt, ...);
+
 #endif	/* __PERF_DEBUG_H */
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [RFC 00/24] perf tools: Add traceevent plugins support
  2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
                   ` (23 preceding siblings ...)
  2013-09-01 10:48 ` [PATCH 24/24] perf tools: Overload pr_stat traceevent print function Jiri Olsa
@ 2013-09-02  8:39 ` Jiri Olsa
  24 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2013-09-02  8:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Corey Ashford, Frederic Weisbecker, Ingo Molnar, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Sun, Sep 01, 2013 at 12:48:25PM +0200, Jiri Olsa wrote:
> hi,
> backporting traceevent plugin support from trace-cmd.

It's reachable here:

git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/core_plugins

jirka

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule
  2013-09-01 10:48 ` [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule Jiri Olsa
@ 2013-09-04  8:35   ` Namhyung Kim
  0 siblings, 0 replies; 31+ messages in thread
From: Namhyung Kim @ 2013-09-04  8:35 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	David Ahern

Hi Jiri,

On Sun,  1 Sep 2013 12:48:26 +0200, Jiri Olsa wrote:
> Currently we fail for following make command:
>
>   $ sudo make install prefix=/opt/perf
>   ...
>       GEN python/perf.so
>   install -d -m 755 '/opt/perf/bin'
>   install perf '/opt/perf/bin'
>   install perf-archive -t '/opt/perf/libexec/perf-core'
>   install: accessing `/opt/perf/libexec/perf-core': No such file or directory
>   make: *** [install-bin] Error 1
>
> Fixing this by properly creating '/opt/perf/libexec/perf-core'
> directory.
>

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/24] perf tools: Remove unused trace-event-* code
  2013-09-01 10:48 ` [PATCH 02/24] perf tools: Remove unused trace-event-* code Jiri Olsa
@ 2013-09-04  8:36   ` Namhyung Kim
  0 siblings, 0 replies; 31+ messages in thread
From: Namhyung Kim @ 2013-09-04  8:36 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	David Ahern

On Sun,  1 Sep 2013 12:48:27 +0200, Jiri Olsa wrote:
> Removing unused trace-event-* code.

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 03/24] perf tools: Unify page_size usage
  2013-09-01 10:48 ` [PATCH 03/24] perf tools: Unify page_size usage Jiri Olsa
@ 2013-09-04  8:37   ` Namhyung Kim
  0 siblings, 0 replies; 31+ messages in thread
From: Namhyung Kim @ 2013-09-04  8:37 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	David Ahern

On Sun,  1 Sep 2013 12:48:28 +0200, Jiri Olsa wrote:
> Making page_size global from the util object.
> Removing the not needed one.

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/24] tools list traceevent: Add plugin support
  2013-09-01 10:48 ` [PATCH 04/24] tools list traceevent: Add plugin support Jiri Olsa
@ 2013-09-16  3:37   ` David Ahern
  0 siblings, 0 replies; 31+ messages in thread
From: David Ahern @ 2013-09-16  3:37 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt

On 9/1/13 4:48 AM, Jiri Olsa wrote:
> Backporting plugin support for traceevent lib.

It would be worthwhile to not where the code is ported from -- 
repository and as of commit id.

David


>
> It's now possible to use following interface
> to load plugins for 'struct pevent' object:
>
> struct plugin_list*
> traceevent_load_plugins(struct pevent *pevent)
>    - loads plusing for 'struct pevent' object and returns
>      loaded plugins list
>
> void traceevent_unload_plugins(struct plugin_list *plugin_list);
>    - unload plugin list
>
> Adding -ldl dependency for perf which is needed
> due to plugins support.
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: David Ahern <dsahern@gmail.com>
> ---
>   tools/lib/traceevent/Makefile       |   2 +-
>   tools/lib/traceevent/event-parse.h  |   5 +
>   tools/lib/traceevent/event-plugin.c | 202 ++++++++++++++++++++++++++++++++++++
>   tools/perf/config/Makefile          |   2 +-
>   4 files changed, 209 insertions(+), 2 deletions(-)
>   create mode 100644 tools/lib/traceevent/event-plugin.c
>
> diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
> index ca6cb77..539f3e5 100644
> --- a/tools/lib/traceevent/Makefile
> +++ b/tools/lib/traceevent/Makefile
> @@ -180,7 +180,7 @@ $(obj)/%.o: $(src)/%.c
>   %.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 = event-parse.o event-plugin.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/event-parse.h b/tools/lib/traceevent/event-parse.h
> index c37b202..8273c6e 100644
> --- a/tools/lib/traceevent/event-parse.h
> +++ b/tools/lib/traceevent/event-parse.h
> @@ -374,6 +374,11 @@ enum pevent_errno {
>   };
>   #undef _PE
>
> +struct plugin_list;
> +
> +struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
> +void traceevent_unload_plugins(struct plugin_list *plugin_list);
> +
>   struct cmdline;
>   struct cmdline_list;
>   struct func_map;
> diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
> new file mode 100644
> index 0000000..d272d87
> --- /dev/null
> +++ b/tools/lib/traceevent/event-plugin.c
> @@ -0,0 +1,202 @@
> +/*
> + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + * 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,  see <http://www.gnu.org/licenses>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + */
> +
> +#include <string.h>
> +#include <dlfcn.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include "event-parse.h"
> +#include "event-utils.h"
> +
> +#define LOCAL_PLUGIN_DIR ".traceevent/plugins"
> +
> +struct plugin_list {
> +	struct plugin_list	*next;
> +	char			*name;
> +	void			*handle;
> +};
> +
> +static void
> +load_plugin(struct pevent *pevent, const char *path,
> +	    const char *file, void *data)
> +{
> +	struct plugin_list **plugin_list = data;
> +	pevent_plugin_load_func func;
> +	struct plugin_list *list;
> +	const char *alias;
> +	char *plugin;
> +	void *handle;
> +
> +	plugin = malloc_or_die(strlen(path) + strlen(file) + 2);
> +
> +	strcpy(plugin, path);
> +	strcat(plugin, "/");
> +	strcat(plugin, file);
> +
> +	handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
> +	if (!handle) {
> +		warning("could not load plugin '%s'\n%s\n",
> +			plugin, dlerror());
> +		goto out_free;
> +	}
> +
> +	alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
> +	if (!alias)
> +		alias = file;
> +
> +	func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
> +	if (!func) {
> +		warning("could not find func '%s' in plugin '%s'\n%s\n",
> +			PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
> +		goto out_free;
> +	}
> +
> +	list = malloc_or_die(sizeof(*list));
> +	list->next = *plugin_list;
> +	list->handle = handle;
> +	list->name = plugin;
> +	*plugin_list = list;
> +
> +	pr_stat("registering plugin: %s", plugin);
> +	func(pevent);
> +	return;
> +
> + out_free:
> +	free(plugin);
> +}
> +
> +static void
> +load_plugins_dir(struct pevent *pevent, const char *suffix,
> +		 const char *path,
> +		 void (*load_plugin)(struct pevent *pevent,
> +				     const char *path,
> +				     const char *name,
> +				     void *data),
> +		 void *data)
> +{
> +	struct dirent *dent;
> +	struct stat st;
> +	DIR *dir;
> +	int ret;
> +
> +	ret = stat(path, &st);
> +	if (ret < 0)
> +		return;
> +
> +	if (!S_ISDIR(st.st_mode))
> +		return;
> +
> +	dir = opendir(path);
> +	if (!dir)
> +		return;
> +
> +	while ((dent = readdir(dir))) {
> +		const char *name = dent->d_name;
> +
> +		if (strcmp(name, ".") == 0 ||
> +		    strcmp(name, "..") == 0)
> +			continue;
> +
> +		/* Only load plugins that end in suffix */
> +		if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0)
> +			continue;
> +
> +		load_plugin(pevent, path, name, data);
> +	}
> +
> +	closedir(dir);
> +}
> +
> +static void
> +load_plugins(struct pevent *pevent, const char *suffix,
> +	     void (*load_plugin)(struct pevent *pevent,
> +				 const char *path,
> +				 const char *name,
> +				 void *data),
> +	     void *data)
> +{
> +	char *home;
> +	char *path;
> +	char *envdir;
> +
> +	/*
> +	 * If a system plugin directory was defined,
> +	 * check that first.
> +	 */
> +#ifdef PLUGIN_DIR
> +	load_plugins_dir(pevent, suffix, PLUGIN_DIR, load_plugin, data);
> +#endif
> +
> +	/*
> +	 * Next let the environment-set plugin directory
> +	 * override the system defaults.
> +	 */
> +	envdir = getenv("TRACEEVENT_PLUGIN_DIR");
> +	if (envdir)
> +		load_plugins_dir(pevent, suffix, envdir, load_plugin, data);
> +
> +	/*
> +	 * Now let the home directory override the environment
> +	 * or system defaults.
> +	 */
> +	home = getenv("HOME");
> +	if (!home)
> +		return;
> +
> +	path = malloc_or_die(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2);
> +
> +	strcpy(path, home);
> +	strcat(path, "/");
> +	strcat(path, LOCAL_PLUGIN_DIR);
> +
> +	load_plugins_dir(pevent, suffix, path, load_plugin, data);
> +
> +	free(path);
> +}
> +
> +struct plugin_list*
> +traceevent_load_plugins(struct pevent *pevent)
> +{
> +	struct plugin_list *list = NULL;
> +
> +	load_plugins(pevent, ".so", load_plugin, &list);
> +	return list;
> +}
> +
> +void
> +traceevent_unload_plugins(struct plugin_list *plugin_list)
> +{
> +	pevent_plugin_unload_func func;
> +	struct plugin_list *list;
> +
> +	while (plugin_list) {
> +		list = plugin_list;
> +		plugin_list = list->next;
> +		func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
> +		if (func)
> +			func();
> +		dlclose(list->handle);
> +		free(list->name);
> +		free(list);
> +	}
> +}
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 214e17e..f6d720d 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -87,7 +87,7 @@ CFLAGS += -Wall
>   CFLAGS += -Wextra
>   CFLAGS += -std=gnu99
>
> -EXTLIBS = -lelf -lpthread -lrt -lm
> +EXTLIBS = -lelf -lpthread -lrt -lm -ldl
>
>   ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
>     CFLAGS += -fstack-protector-all
>


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 05/24] tools list traceevent: Add options support
  2013-09-01 10:48 ` [PATCH 05/24] tools list traceevent: Add options support Jiri Olsa
@ 2013-09-16  3:40   ` David Ahern
  0 siblings, 0 replies; 31+ messages in thread
From: David Ahern @ 2013-09-16  3:40 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt

On 9/1/13 4:48 AM, Jiri Olsa wrote:
> Backporting options support for traceevent lib.

ditto -- where's the code from and last commit id.

>
> It's now possible to use following interface
> to load options for 'struct pevent' object:
>
> void traceevent_add_options(const char *name, struct plugin_option *options);
>    - adds a set of options by a plugin
>
> void traceevent_remove_options(struct plugin_option *options);
>    - removes plugin options that were registered
>
> void traceevent_add_option(const char *name, const char *val);
>    - modifies plugin option

And how is the code used? Take for instance the kvm plugin: would I be 
able to use this interface to pass in a vmlinux path to resolve guest 
symbols or some other option to convert RIPs in kvm tracepoints to symbols?

David

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2013-09-16  3:40 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-01 10:48 [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa
2013-09-01 10:48 ` [PATCH 01/24] perf tools: Fix 'make install prefix=...' build rule Jiri Olsa
2013-09-04  8:35   ` Namhyung Kim
2013-09-01 10:48 ` [PATCH 02/24] perf tools: Remove unused trace-event-* code Jiri Olsa
2013-09-04  8:36   ` Namhyung Kim
2013-09-01 10:48 ` [PATCH 03/24] perf tools: Unify page_size usage Jiri Olsa
2013-09-04  8:37   ` Namhyung Kim
2013-09-01 10:48 ` [PATCH 04/24] tools list traceevent: Add plugin support Jiri Olsa
2013-09-16  3:37   ` David Ahern
2013-09-01 10:48 ` [PATCH 05/24] tools list traceevent: Add options support Jiri Olsa
2013-09-16  3:40   ` David Ahern
2013-09-01 10:48 ` [PATCH 06/24] tools list traceevent: Add plugin build support Jiri Olsa
2013-09-01 10:48 ` [PATCH 07/24] tools list traceevent: Add traceevent_host_bigendian function Jiri Olsa
2013-09-01 10:48 ` [PATCH 08/24] tools list traceevent: Add pevent_print_func_field function Jiri Olsa
2013-09-01 10:48 ` [PATCH 09/24] tools list traceevent: Add jbd2 plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 10/24] tools list traceevent: Add blk plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 11/24] tools list traceevent: Add hrtimer plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 12/24] tools list traceevent: Add kmem plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 13/24] tools list traceevent: Add kvm plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 14/24] tools list traceevent: Add mac80211 plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 15/24] tools list traceevent: Add sched_switch plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 16/24] tools list traceevent: Add function plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 17/24] tools list traceevent: Update kvm plugin with is_writable_pte helper Jiri Olsa
2013-09-01 10:48 ` [PATCH 18/24] tools list traceevent: Add xen plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 19/24] tools list traceevent: Add scsi plugin Jiri Olsa
2013-09-01 10:48 ` [PATCH 20/24] tools list traceevent: Change pevent_parse_event to return event format Jiri Olsa
2013-09-01 10:48 ` [PATCH 21/24] perf tools: Add traceevents Makefile install rule Jiri Olsa
2013-09-01 10:48 ` [PATCH 22/24] perf tools: Add trace-event object Jiri Olsa
2013-09-01 10:48 ` [PATCH 23/24] perf tools: Add traceevent object to interface traceevent lib Jiri Olsa
2013-09-01 10:48 ` [PATCH 24/24] perf tools: Overload pr_stat traceevent print function Jiri Olsa
2013-09-02  8:39 ` [RFC 00/24] perf tools: Add traceevent plugins support Jiri Olsa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox