Re: [tip:perf/core] perf tools: Adding PERF_ATTR_SIZE_VER2 to the header swap check

2012-08-22 Thread Jiri Olsa
On Tue, Aug 21, 2012 at 07:12:10PM +0200, Peter Zijlstra wrote:
 On Tue, 2012-08-21 at 08:51 -0700, tip-bot for Jiri Olsa wrote:
  @@ -1829,6 +1829,7 @@ out_free:
   static const int attr_file_abi_sizes[] = {
  [0] = PERF_ATTR_SIZE_VER0,
  [1] = PERF_ATTR_SIZE_VER1,
  +   [2] = PERF_ATTR_SIZE_VER2,
  0,
   }; 
 
 Didn't we just get to VER4 ?

that's leftover for the branch_sample_type addition

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


[PATCH] perf: Keep the perf_event_attr on version 3

2012-08-22 Thread Jiri Olsa
On Tue, Aug 21, 2012 at 07:11:56PM +0200, Peter Zijlstra wrote:
 On Tue, 2012-08-21 at 08:49 -0700, tip-bot for Jiri Olsa wrote:
   #define PERF_ATTR_SIZE_VER388  /* add: sample_regs_user */
  +#define PERF_ATTR_SIZE_VER496  /* add: sample_stack_user */
 
 Both are introduced in this patch set, there's no release in between,
 why are we doing two version increments? Seems like pointless version
 space inflation to me.

not sure why I did that, attached patch returns that to version3

jirka

---
Stashing version 4 under version 3 and removing version 4,
because both version changes were within single patchset.

Reported-by: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 include/linux/perf_event.h | 4 ++--
 tools/perf/util/header.c   | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 297ca3d..28f9cee 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -205,8 +205,8 @@ enum perf_event_read_format {
 #define PERF_ATTR_SIZE_VER064  /* sizeof first published struct */
 #define PERF_ATTR_SIZE_VER172  /* add: config2 */
 #define PERF_ATTR_SIZE_VER280  /* add: branch_sample_type */
-#define PERF_ATTR_SIZE_VER388  /* add: sample_regs_user */
-#define PERF_ATTR_SIZE_VER496  /* add: sample_stack_user */
+#define PERF_ATTR_SIZE_VER396  /* add: sample_regs_user */
+   /* add: sample_stack_user */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 1e5b6aa..5ed4812 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1831,7 +1831,6 @@ static const int attr_file_abi_sizes[] = {
[1] = PERF_ATTR_SIZE_VER1,
[2] = PERF_ATTR_SIZE_VER2,
[3] = PERF_ATTR_SIZE_VER3,
-   [4] = PERF_ATTR_SIZE_VER4,
0,
 };
 
-- 
1.7.11.4

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


[PATCH] perf tools: Fix 'No libunwind found' make warning message

2012-08-22 Thread Jiri Olsa
On Tue, Aug 21, 2012 at 11:36:28AM +0200, Jiri Olsa wrote:
 On Tue, Aug 21, 2012 at 11:32:31AM +0200, Ingo Molnar wrote:
  
  * Arnaldo Carvalho de Melo a...@infradead.org wrote:
  
 
 SNIP
 
  
  One minor observation, the Makefile tells us:
  
  Makefile:496: No libunwind found. Please install libunwind = 0.99
  
  I guess that should be libunwind-dev[el], right? Plain libunwind 
  is not enough.
 
 right, will fix it
 
 thanks,
 jirka

---
Changing error message when libunwind support is not found
to inform properly to install libunwind-dev[el] package.

Reported-by: Ingo Molnar mi...@elte.hu
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 6bd888d..218cdb5 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -493,7 +493,7 @@ endif
 
 FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) 
$(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
 ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y)
-   msg := $(warning No libunwind found. Please install libunwind = 0.99);
+   msg := $(warning No libunwind found, disables post unwind support. 
Please install libunwind-dev[el] = 0.99);
NO_LIBUNWIND := 1
 endif # Libunwind support
 endif # NO_LIBUNWIND
-- 
1.7.11.4

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


[PATCH 06/13] perf test: Add perf_event_attr record graph test

2012-08-24 Thread Jiri Olsa
Adding tests to validate perf_event_attr data for commands:
  'record -g --'
  'record -g fp
  'record -g dwarf

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com

graph
---
 tools/perf/util/test-attr/test-record-graph-default | 6 ++
 tools/perf/util/test-attr/test-record-graph-dwarf   | 6 ++
 tools/perf/util/test-attr/test-record-graph-fp  | 6 ++
 3 files changed, 18 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-graph-default
 create mode 100644 tools/perf/util/test-attr/test-record-graph-dwarf
 create mode 100644 tools/perf/util/test-attr/test-record-graph-fp

diff --git a/tools/perf/util/test-attr/test-record-graph-default 
b/tools/perf/util/test-attr/test-record-graph-default
new file mode 100644
index 000..833d184
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-graph-default
@@ -0,0 +1,6 @@
+[config]
+command = record
+args= -g -- kill /dev/null 21
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/util/test-attr/test-record-graph-dwarf 
b/tools/perf/util/test-attr/test-record-graph-dwarf
new file mode 100644
index 000..41f3f67
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-graph-dwarf
@@ -0,0 +1,6 @@
+[config]
+command = record
+args= -g dwarf -- kill /dev/null 21
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/util/test-attr/test-record-graph-fp 
b/tools/perf/util/test-attr/test-record-graph-fp
new file mode 100644
index 000..7cef374
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-graph-fp
@@ -0,0 +1,6 @@
+[config]
+command = record
+args= -g fp kill /dev/null 21
+
+[event:base-record]
+sample_type=295
-- 
1.7.11.4

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


[PATCH 12/13] perf test: Add perf_event_attr stat group test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'stat --group -e cycles,instructions'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-stat-group | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-stat-group

diff --git a/tools/perf/util/test-attr/test-stat-group 
b/tools/perf/util/test-attr/test-stat-group
new file mode 100644
index 000..fdc1596
--- /dev/null
+++ b/tools/perf/util/test-attr/test-stat-group
@@ -0,0 +1,15 @@
+[config]
+command = stat
+args= --group -e cycles,instructions kill /dev/null 21
+ret = 1
+
+[event-1:base-stat]
+fd=1
+group_fd=-1
+
+[event-2:base-stat]
+fd=2
+group_fd=1
+config=1
+disabled=0
+enable_on_exec=0
-- 
1.7.11.4

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


[PATCH 13/13] perf test: Add attr tests under builtin test command

2012-08-24 Thread Jiri Olsa
The test attr suite is run only if it's run under perf source
directory, because test attr files are not installed.

If run elsewhere, tests are ommited (notification is displayed)
and finished as successfull.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/builtin-test.c   |  4 
 tools/perf/perf.h   |  1 +
 tools/perf/util/test-attr.c | 14 ++
 3 files changed, 19 insertions(+)

diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 381d5ab..f2d3c50 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1135,6 +1135,10 @@ static struct test {
.func = dso__test_data,
},
{
+   .desc = Test perf attr,
+   .func = test_attr__run,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index a67bb75..2039774 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -174,6 +174,7 @@ void test_attr__init(void);
 int  test_attr__open(struct perf_event_attr *attr,
 pid_t pid, int cpu, int group_fd,
 unsigned long flags);
+int test_attr__run(void);
 
 static inline int
 sys_perf_event_open(struct perf_event_attr *attr,
diff --git a/tools/perf/util/test-attr.c b/tools/perf/util/test-attr.c
index dd83954..eb610f7 100644
--- a/tools/perf/util/test-attr.c
+++ b/tools/perf/util/test-attr.c
@@ -126,3 +126,17 @@ int test_attr__open(struct perf_event_attr *attr,
 
return fd;
 }
+
+int test_attr__run(void)
+{
+   struct stat st;
+   const char *run;
+
+   run = python ./util/test-attr.py -d ./util/test-attr/ -p ./perf;
+
+   if (!lstat(./util/, st))
+   return system(run);
+
+   fprintf(stderr,  (ommitted));
+   return 0;
+}
-- 
1.7.11.4

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


[PATCH 09/13] perf test: Add perf_event_attr record no-inherit test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record -i'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-no-inherit | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-no-inherit

diff --git a/tools/perf/util/test-attr/test-record-no-inherit 
b/tools/perf/util/test-attr/test-record-no-inherit
new file mode 100644
index 000..9079a25
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-no-inherit
@@ -0,0 +1,7 @@
+[config]
+command = record
+args= -i kill /dev/null 21
+
+[event:base-record]
+sample_type=259
+inherit=0
-- 
1.7.11.4

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


[PATCH 04/13] perf test: Add perf_event_attr record freq test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record -F 100'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-freq | 6 ++
 1 file changed, 6 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-freq

diff --git a/tools/perf/util/test-attr/test-record-freq 
b/tools/perf/util/test-attr/test-record-freq
new file mode 100644
index 000..600d0f8
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-freq
@@ -0,0 +1,6 @@
+[config]
+command = record
+args= -F 100 kill /dev/null 21
+
+[event:base-record]
+sample_period=100
-- 
1.7.11.4

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


[PATCH 11/13] perf test: Add perf_event_attr stat no-inherit test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
'stat -i'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-stat-no-inherit | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-stat-no-inherit

diff --git a/tools/perf/util/test-attr/test-stat-no-inherit 
b/tools/perf/util/test-attr/test-stat-no-inherit
new file mode 100644
index 000..d54b2a1e
--- /dev/null
+++ b/tools/perf/util/test-attr/test-stat-no-inherit
@@ -0,0 +1,7 @@
+[config]
+command = stat
+args= -i -e cycles kill /dev/null 21
+ret = 1
+
+[event:base-stat]
+inherit=0
-- 
1.7.11.4

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


[PATCH 08/13] perf test: Add perf_event_attr record no samples test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record -n'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-no-samples | 6 ++
 1 file changed, 6 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-no-samples

diff --git a/tools/perf/util/test-attr/test-record-no-samples 
b/tools/perf/util/test-attr/test-record-no-samples
new file mode 100644
index 000..d0141b2
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-no-samples
@@ -0,0 +1,6 @@
+[config]
+command = record
+args= -n kill /dev/null 21
+
+[event:base-record]
+sample_period=0
-- 
1.7.11.4

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


[PATCH 10/13] perf test: Add perf_event_attr stat basic test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'stat'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/base-stat   | 39 +++
 tools/perf/util/test-attr/test-stat-basic |  6 +
 2 files changed, 45 insertions(+)
 create mode 100644 tools/perf/util/test-attr/base-stat
 create mode 100644 tools/perf/util/test-attr/test-stat-basic

diff --git a/tools/perf/util/test-attr/base-stat 
b/tools/perf/util/test-attr/base-stat
new file mode 100644
index 000..f46db90
--- /dev/null
+++ b/tools/perf/util/test-attr/base-stat
@@ -0,0 +1,39 @@
+[event]
+fd=1
+group_fd=-1
+flags=0
+type=0
+size=96
+config=0
+sample_period=0
+sample_type=0
+read_format=3
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0
+exclude_hv=0
+exclude_idle=0
+mmap=0
+comm=0
+freq=0
+inherit_stat=0
+enable_on_exec=1
+task=0
+watermask=0
+precise_ip=0
+mmap_data=0
+sample_id_all=0
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/util/test-attr/test-stat-basic 
b/tools/perf/util/test-attr/test-stat-basic
new file mode 100644
index 000..74e1788
--- /dev/null
+++ b/tools/perf/util/test-attr/test-stat-basic
@@ -0,0 +1,6 @@
+[config]
+command = stat
+args= -e cycles kill /dev/null 21
+ret = 1
+
+[event:base-stat]
-- 
1.7.11.4

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


[PATCH 07/13] perf test: Add perf_event_attr record period test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record -c 100 -P'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-period | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-period

diff --git a/tools/perf/util/test-attr/test-record-period 
b/tools/perf/util/test-attr/test-record-period
new file mode 100644
index 000..8abc531
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-period
@@ -0,0 +1,7 @@
+[config]
+command = record
+args= -c 100 -P kill /dev/null 21
+
+[event:base-record]
+sample_period=100
+freq=0
-- 
1.7.11.4

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


[PATCH 05/13] perf test: Add perf_event_attr record count test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record -c 123'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-count | 8 
 1 file changed, 8 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-count

diff --git a/tools/perf/util/test-attr/test-record-count 
b/tools/perf/util/test-attr/test-record-count
new file mode 100644
index 000..2f841de
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-count
@@ -0,0 +1,8 @@
+[config]
+command = record
+args= -c 123 kill /dev/null 21
+
+[event:base-record]
+sample_period=123
+sample_type=7
+freq=0
-- 
1.7.11.4

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


[PATCH 03/13] perf test: Add perf_event_attr record group test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record --group -e cycles,instructions'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/test-record-group | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 tools/perf/util/test-attr/test-record-group

diff --git a/tools/perf/util/test-attr/test-record-group 
b/tools/perf/util/test-attr/test-record-group
new file mode 100644
index 000..6cff60f
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-group
@@ -0,0 +1,17 @@
+[config]
+command = record
+args= --group -e cycles,instructions kill 2/dev/null
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=327
+
+[event-2:base-record]
+fd=2
+group_fd=1
+config=1
+sample_type=327
+mmap=0
+comm=0
+enable_on_exec=0
-- 
1.7.11.4

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


[RFC 00/13] perf test: Add perf_event_attr tests

2012-08-24 Thread Jiri Olsa
hi,
this code tests the link between perf stat/record command line
options and final perf_event_attr struct values. Also it tests
the group fd linkage.

It's probably missing many command line option combinations
worth testing. I wanted to check with others for more ideas
before diving into this.

You can check this also here:

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

thanks,
jirka


Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile |   1 +
 tools/perf/builtin-test.c   |   4 +
 tools/perf/perf.c   |   2 +
 tools/perf/perf.h   |  11 ++
 tools/perf/util/test-attr.c | 142 
++
 tools/perf/util/test-attr.py| 272 
++
 tools/perf/util/test-attr/base-record   |  39 
 tools/perf/util/test-attr/base-stat |  39 
 tools/perf/util/test-attr/test-record-basic |   5 +
 tools/perf/util/test-attr/test-record-count |   8 ++
 tools/perf/util/test-attr/test-record-freq  |   6 ++
 tools/perf/util/test-attr/test-record-graph-default |   6 ++
 tools/perf/util/test-attr/test-record-graph-dwarf   |   6 ++
 tools/perf/util/test-attr/test-record-graph-fp  |   6 ++
 tools/perf/util/test-attr/test-record-group |  17 
 tools/perf/util/test-attr/test-record-no-inherit|   7 ++
 tools/perf/util/test-attr/test-record-no-samples|   6 ++
 tools/perf/util/test-attr/test-record-period|   7 ++
 tools/perf/util/test-attr/test-stat-basic   |   6 ++
 tools/perf/util/test-attr/test-stat-group   |  15 +++
 tools/perf/util/test-attr/test-stat-no-inherit  |   7 ++
 21 files changed, 612 insertions(+)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/13] perf test: Add perf_event_attr record basic test

2012-08-24 Thread Jiri Olsa
Adding test to validate perf_event_attr data for command:
  'record'

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/test-attr/base-record   | 39 +
 tools/perf/util/test-attr/test-record-basic |  5 
 2 files changed, 44 insertions(+)
 create mode 100644 tools/perf/util/test-attr/base-record
 create mode 100644 tools/perf/util/test-attr/test-record-basic

diff --git a/tools/perf/util/test-attr/base-record 
b/tools/perf/util/test-attr/base-record
new file mode 100644
index 000..ea2d3c5
--- /dev/null
+++ b/tools/perf/util/test-attr/base-record
@@ -0,0 +1,39 @@
+[event]
+fd=1
+group_fd=-1
+flags=0
+type=0
+size=96
+config=0
+sample_period=4000
+sample_type=263
+read_format=7
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0
+exclude_hv=0
+exclude_idle=0
+mmap=1
+comm=1
+freq=1
+inherit_stat=0
+enable_on_exec=1
+task=0
+watermask=0
+precise_ip=0
+mmap_data=0
+sample_id_all=1
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/util/test-attr/test-record-basic 
b/tools/perf/util/test-attr/test-record-basic
new file mode 100644
index 000..55c0428
--- /dev/null
+++ b/tools/perf/util/test-attr/test-record-basic
@@ -0,0 +1,5 @@
+[config]
+command = record
+args= kill /dev/null 21
+
+[event:base-record]
-- 
1.7.11.4

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


[PATCH 01/13] perf test: Add framework for atomated perf_event_attr tests

2012-08-24 Thread Jiri Olsa
Adding automated test to check event's perf_event_attr values.

The idea is run perf session with kidnaping sys_perf_event_open
function. For each sys_perf_event_open call we store the
perf_event_attr data to the file to be checked later against what
we expect.

You can run this by:
  # python ./util/test-attr.py -d ./util/test-attr/ -p ./perf -v

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile  |   1 +
 tools/perf/perf.c|   2 +
 tools/perf/perf.h|  10 ++
 tools/perf/util/test-attr.c  | 128 
 tools/perf/util/test-attr.py | 272 +++
 5 files changed, 413 insertions(+)
 create mode 100644 tools/perf/util/test-attr.c
 create mode 100644 tools/perf/util/test-attr.py

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 722ddee..746375d 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -405,6 +405,7 @@ LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
 LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
+LIB_OBJS += $(OUTPUT)util/test-attr.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index e7840e5..94092eb13 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -477,6 +477,8 @@ int main(int argc, const char **argv)
}
cmd = argv[0];
 
+   test_attr__init();
+
/*
 * We use PATH to find perf commands, but we prepend some higher
 * precedence paths: the --exec-path option, the PERF_EXEC_PATH
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 87f4ec6..a67bb75 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -5,6 +5,7 @@ struct winsize;
 
 void get_term_dimensions(struct winsize *ws);
 
+
 #if defined(__i386__)
 #include ../../arch/x86/include/asm/unistd.h
 #define rmb()  asm volatile(lock; addl $0,0(%%esp) ::: memory)
@@ -168,11 +169,20 @@ static inline unsigned long long rdclock(void)
(void) (_min1 == _min2);  \
_min1  _min2 ? _min1 : _min2; })
 
+extern bool test_attr__enabled;
+void test_attr__init(void);
+int  test_attr__open(struct perf_event_attr *attr,
+pid_t pid, int cpu, int group_fd,
+unsigned long flags);
+
 static inline int
 sys_perf_event_open(struct perf_event_attr *attr,
  pid_t pid, int cpu, int group_fd,
  unsigned long flags)
 {
+   if (unlikely(test_attr__enabled))
+   return test_attr__open(attr, pid, cpu, group_fd, flags);
+
return syscall(__NR_perf_event_open, attr, pid, cpu,
   group_fd, flags);
 }
diff --git a/tools/perf/util/test-attr.c b/tools/perf/util/test-attr.c
new file mode 100644
index 000..dd83954
--- /dev/null
+++ b/tools/perf/util/test-attr.c
@@ -0,0 +1,128 @@
+
+#include stdlib.h
+#include stdio.h
+#include inttypes.h
+#include linux/types.h
+#include ../perf.h
+#include util.h
+
+#define ENV PERF_TEST_ATTR
+
+bool test_attr__enabled;
+
+static char *dir;
+
+void test_attr__init(void)
+{
+   dir = getenv(ENV);
+   test_attr__enabled = (dir != NULL);
+}
+
+#define BUFSIZE 1024
+
+#define WRITE_ASS(str, fmt, data)  \
+do {   \
+   char buf[BUFSIZE];  \
+   size_t size;\
+   \
+   size = snprintf(buf, BUFSIZE, #str =%fmt \n, data); \
+   if (1 != fwrite(buf, size, 1, file)) {  \
+   perror(test attr - failed to write event file);   \
+   return -1;  \
+   }   \
+   \
+} while (0)
+
+static int store_event(int fd, struct perf_event_attr *attr,
+  pid_t pid, int cpu, int group_fd,
+  unsigned long flags)
+{
+   FILE *file;
+   char path[PATH_MAX];
+
+   snprintf(path, PATH_MAX, %s/event-%d, dir, fd);
+
+   file = fopen(path, w+);
+   if (!file) {
+   perror(test attr - failed to open event file);
+   return -1;
+   }
+
+#define HEADER [event]\n
+   if (1 != fwrite(HEADER, sizeof(HEADER) - 1, 1, file)) {
+   perror(test attr - failed to write event file);
+   return -1;
+   }
+#undef HEADER
+
+   /* syscall arguments

Re: [PATCHv8 00/13] perf: Add backtrace post dwarf unwind

2012-08-01 Thread Jiri Olsa
On Wed, Aug 01, 2012 at 06:04:31AM +0200, Stephane Eranian wrote:
 On Fri, Jul 27, 2012 at 2:23 PM, Jiri Olsa jo...@redhat.com wrote:
  hi,
  patches available also as tarball in here:
  http://people.redhat.com/~jolsa/perf_post_unwind_v8.tar.bz2
 
  v8 changes:
 - patch 2 - added dump registers ABI specification as suggested
 by Stephane
 - v7 patches 9,10,16,17 already in
 
 Patches 4, 7 do not apply cleanly for me on tip-master @ commit 2a7d7ce
 when I use the tarball version of the patchset.

there's conflict with fresh commit..

perf/trace: Add ability to set a target task for events
commit e6dab5ffab59e910ec0e3355f4a6f29f7a7be474
Author: Andrew Vagin ava...@openvz.org
Date:   Wed Jul 11 18:14:58 2012 +0400

I'm testing v9 and will send it out shortly

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


[PATCHv9 00/13] perf: Add backtrace post dwarf unwind

2012-08-01 Thread Jiri Olsa
hi,
patches available also as tarball in here:
http://people.redhat.com/~jolsa/perf_post_unwind_v9.tar.bz2

v9 changes:
   - rebased to current tip tree

v8 changes:
   - patch 2 - added dump registers ABI specification as suggested
   by Stephane
   - v7 patches 9,10,16,17 already in

v7 changes:
   - omitted v6 patches 9 and 15
 They need more work and will be sent separately. I dont want to hold off 
whole
 patchset because of them. We could miss some related backtraces (syscall, 
vdso)
 in this version.
   - v6 patch 11, 14, 20 already in

v6 changes:
   patch 01/23 - unrelated - ftrace stuff
   patch 03/23 - added PERF_SAMPLE_REGS_USER bit
   - added regs_user initialization
   patch 07/23 - added PERF_SAMPLE_STACK_USER bit
   - sample_stack_user changed to u32 and
 added size check
   new patches 1,9,10,20

v5 changes:
   patch 1/19 - having just one enum set of the perf registers
   patch 2/19 - using for_each_set_bit for scanning the mask
  - single regs enum for both 32 and 64 bits versions
  - using regs mask != 0 trigger to trigger the regs dump
   patch 5/19 - adding perf_output_skip so we can skip undumped part of the 
stack in RB
   patch 6/19 - using stack size != 0 trigger to trigger the stack dump
  - do not zero the memory for non retrieved part of the stack dump
   patch 7/19 - adding exclude_callchain_kernel attribute
   patch 8/19 - this could be taken without the rest of the series

v4 changes:
   - no real change from v3, just rebase
   - v3 patch 06/17 got already merged

v3 changes:
   patch 01/17
   - added HAVE_PERF_REGS config option
   patch 02/17, 04/17
   - regs and stack perf interface is more general now
   patch 06/17
   - unrelated online fix for i386 compilation
   patch 16/17
   - few namespace fixies

---
Adding the post unwinding user stack backtrace using dwarf unwind
via libunwind. The original work was done by Frederic. I mostly took
his patches and make them compile in current kernel code plus I added
some stuff here and there.

The main idea is to store user registers and portion of user
stack when the sample data during the record phase. Then during
the report, when the data is presented, perform the actual dwarf
dwarf unwind.

attached patches:
  01/13 perf: Unified API to record selective sets of arch registers
  02/13 perf: Add ability to attach user level registers dump to sample
  03/13 perf, x86: Add copy_from_user_nmi_nochk for best effort copy
  04/13 perf: Factor __output_copy to be usable with specific copy function
  05/13 perf: Add perf_output_skip function to skip bytes in sample
  06/13 perf: Add ability to attach user stack dump to sample
  07/13 perf: Add attribute to filter out callchains
  08/13 perf, tool: Adding PERF_ATTR_SIZE_VER2 to the header swap check
  09/13 perf, tool: Add interface to arch registers sets
  10/13 perf, tool: Add libunwind dependency for dwarf cfi unwinding
  11/13 perf, tool: Support user regs and stack in sample parsing
  12/13 perf, tool: Support for dwarf cfi unwinding on post processing
  13/13 perf, tool: Support for dwarf mode callchain on perf record


I tested on Fedora. There was not much gain on i386, because the
binaries are compiled with frame pointers. Thought the dwarf
backtrace is more accurate and unwraps calls in more details
(functions that do not set the frame pointers).

I could see some improvement on x86_64, where I got full backtrace
where current code could got just the first address out of the
instruction pointer.

Example on x86_64:
[dwarf]
   perf record -g dwarf -e syscalls:sys_enter_write date

   100.00% date  libc-2.14.90.so  [.] __GI___libc_write
   |
   --- __GI___libc_write
   _IO_file_write@@GLIBC_2.2.5
   new_do_write
   _IO_do_write@@GLIBC_2.2.5
   _IO_file_overflow@@GLIBC_2.2.5
   0x4022cd
   0x401ee6
   __libc_start_main
   0x4020b9


[frame pointer]
   perf record -g fp -e syscalls:sys_enter_write date

   100.00% date  libc-2.14.90.so  [.] __GI___libc_write
   |
   --- __GI___libc_write

Also I tested on coreutils binaries mainly, but I could see
getting wider backtraces with dwarf unwind for more complex
application like firefox.

Attached patches should work on both x86 and x86_64.

The unwind backtrace can be interrupted by following reasons:
- bug in unwind information of processed shared library
- bug in unwind processing code (most likely ;) )
- insufficient dump stack size
- until full syscall register storage and vdso support
  we could miss some related backtraces 

jirka
---
 arch/Kconfig   |6 +
 arch/x86/Kconfig   |1 +
 arch/x86/include/asm/perf_event.h  |2 +
 

[PATCH 01/13] perf: Unified API to record selective sets of arch registers

2012-08-01 Thread Jiri Olsa
This brings a new API to help the selective dump of registers on
event sampling, and its implementation for x86 arch.

Added HAVE_PERF_REGS config option to determine if the architecture
provides perf registers ABI.

The information about desired registers will be passed in u64 mask.
It's up to the architecture to map the registers into the mask bits.

For the x86 arch implementation, both 32 and 64 bit registers
bits are defined within single enum to ensure 64 bit system can
provide register dump for compat task if needed in the future.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 arch/Kconfig |6 +++
 arch/x86/Kconfig |1 +
 arch/x86/include/asm/perf_regs.h |   33 ++
 arch/x86/kernel/Makefile |2 +
 arch/x86/kernel/perf_regs.c  |   90 ++
 include/linux/perf_regs.h|   19 
 6 files changed, 151 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/include/asm/perf_regs.h
 create mode 100644 arch/x86/kernel/perf_regs.c
 create mode 100644 include/linux/perf_regs.h

diff --git a/arch/Kconfig b/arch/Kconfig
index 8c3d957..32f4873 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -222,6 +222,12 @@ config HAVE_PERF_EVENTS_NMI
  subsystem.  Also has support for calculating CPU cycle events
  to determine how many clock cycles in a given period.
 
+config HAVE_PERF_REGS
+   bool
+   help
+ Support selective register dumps for perf events. This includes
+ bit-mapping of each registers and a unique architecture id.
+
 config HAVE_ARCH_JUMP_LABEL
bool
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 94de2c5..acebbd6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -60,6 +60,7 @@ config X86
select HAVE_MIXED_BREAKPOINTS_REGS
select PERF_EVENTS
select HAVE_PERF_EVENTS_NMI
+   select HAVE_PERF_REGS
select ANON_INODES
select HAVE_ALIGNED_STRUCT_PAGE if SLUB  !M386
select HAVE_CMPXCHG_LOCAL if !M386
diff --git a/arch/x86/include/asm/perf_regs.h b/arch/x86/include/asm/perf_regs.h
new file mode 100644
index 000..3f2207b
--- /dev/null
+++ b/arch/x86/include/asm/perf_regs.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_X86_PERF_REGS_H
+#define _ASM_X86_PERF_REGS_H
+
+enum perf_event_x86_regs {
+   PERF_REG_X86_AX,
+   PERF_REG_X86_BX,
+   PERF_REG_X86_CX,
+   PERF_REG_X86_DX,
+   PERF_REG_X86_SI,
+   PERF_REG_X86_DI,
+   PERF_REG_X86_BP,
+   PERF_REG_X86_SP,
+   PERF_REG_X86_IP,
+   PERF_REG_X86_FLAGS,
+   PERF_REG_X86_CS,
+   PERF_REG_X86_SS,
+   PERF_REG_X86_DS,
+   PERF_REG_X86_ES,
+   PERF_REG_X86_FS,
+   PERF_REG_X86_GS,
+   PERF_REG_X86_R8,
+   PERF_REG_X86_R9,
+   PERF_REG_X86_R10,
+   PERF_REG_X86_R11,
+   PERF_REG_X86_R12,
+   PERF_REG_X86_R13,
+   PERF_REG_X86_R14,
+   PERF_REG_X86_R15,
+
+   PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
+   PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
+};
+#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8215e56..8d7a619 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -100,6 +100,8 @@ obj-$(CONFIG_SWIOTLB)   += pci-swiotlb.o
 obj-$(CONFIG_OF)   += devicetree.o
 obj-$(CONFIG_UPROBES)  += uprobes.o
 
+obj-$(CONFIG_PERF_EVENTS)  += perf_regs.o
+
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
new file mode 100644
index 000..c00c92a
--- /dev/null
+++ b/arch/x86/kernel/perf_regs.c
@@ -0,0 +1,90 @@
+
+#include linux/kernel.h
+#include linux/bug.h
+#include linux/stddef.h
+#include asm/perf_regs.h
+#include asm/ptrace.h
+
+#ifdef CONFIG_X86_32
+#define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
+#else
+#define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
+#endif
+
+#define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
+
+static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
+   PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
+   PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
+   PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
+   PT_REGS_OFFSET(PERF_REG_X86_DX, dx),
+   PT_REGS_OFFSET(PERF_REG_X86_SI, si),
+   PT_REGS_OFFSET(PERF_REG_X86_DI, di),
+   PT_REGS_OFFSET(PERF_REG_X86_BP, bp),
+   PT_REGS_OFFSET(PERF_REG_X86_SP, sp),
+   PT_REGS_OFFSET(PERF_REG_X86_IP, ip),
+   PT_REGS_OFFSET(PERF_REG_X86_FLAGS, flags),
+   PT_REGS_OFFSET(PERF_REG_X86_CS, cs),
+   PT_REGS_OFFSET(PERF_REG_X86_SS, ss),
+#ifdef CONFIG_X86_32
+   PT_REGS_OFFSET(PERF_REG_X86_DS, ds),
+   PT_REGS_OFFSET(PERF_REG_X86_ES, es),
+   PT_REGS_OFFSET(PERF_REG_X86_FS, fs),
+   PT_REGS_OFFSET(PERF_REG_X86_GS, gs),
+#else
+   /*
+* The pt_regs struct does not store

[PATCH 04/13] perf: Factor __output_copy to be usable with specific copy function

2012-08-01 Thread Jiri Olsa
From: Frederic Weisbecker fweis...@gmail.com

Adding a generic way to use __output_copy function with
specific copy function via DEFINE_PERF_OUTPUT_COPY macro.

Using this to add new __output_copy_user function, that provides
output copy from user pointers. For x86 the copy_from_user_nmi_nochk
function is used and __copy_from_user_inatomic for the rest
of the architectures.

This new function will be used in user stack dump on sample,
coming in next patches.

Signed-off-by: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/include/asm/perf_event.h |2 +
 include/linux/perf_event.h|2 +-
 kernel/events/internal.h  |   62 
 kernel/events/ring_buffer.c   |4 +-
 4 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h 
b/arch/x86/include/asm/perf_event.h
index cb4e43b..054d64f 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -262,4 +262,6 @@ static inline void perf_check_microcode(void) { }
  static inline void amd_pmu_disable_virt(void) { }
 #endif
 
+#define arch_perf_out_copy_user copy_from_user_nmi_nochk
+
 #endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 3d4d847..d41394a 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1319,7 +1319,7 @@ static inline bool has_branch_stack(struct perf_event 
*event)
 extern int perf_output_begin(struct perf_output_handle *handle,
 struct perf_event *event, unsigned int size);
 extern void perf_output_end(struct perf_output_handle *handle);
-extern void perf_output_copy(struct perf_output_handle *handle,
+extern unsigned int perf_output_copy(struct perf_output_handle *handle,
 const void *buf, unsigned int len);
 extern int perf_swevent_get_recursion_context(void);
 extern void perf_swevent_put_recursion_context(int rctx);
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index a096c19..7fd5408 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -2,6 +2,7 @@
 #define _KERNEL_EVENTS_INTERNAL_H
 
 #include linux/hardirq.h
+#include linux/uaccess.h
 
 /* Buffer handling */
 
@@ -76,30 +77,49 @@ static inline unsigned long perf_data_size(struct 
ring_buffer *rb)
return rb-nr_pages  (PAGE_SHIFT + page_order(rb));
 }
 
-static inline void
-__output_copy(struct perf_output_handle *handle,
-  const void *buf, unsigned int len)
+#define DEFINE_OUTPUT_COPY(func_name, memcpy_func) \
+static inline unsigned int \
+func_name(struct perf_output_handle *handle,   \
+ const void *buf, unsigned int len)\
+{  \
+   unsigned long size, written;\
+   \
+   do {\
+   size = min_t(unsigned long, handle-size, len); \
+   \
+   written = memcpy_func(handle-addr, buf, size); \
+   \
+   len -= written; \
+   handle-addr += written;\
+   buf += written; \
+   handle-size -= written;\
+   if (!handle-size) {\
+   struct ring_buffer *rb = handle-rb;\
+   \
+   handle-page++; \
+   handle-page = rb-nr_pages - 1;   \
+   handle-addr = rb-data_pages[handle-page];\
+   handle-size = PAGE_SIZE  page_order(rb); \
+   }   \
+   } while (len  written == size);   \
+   \
+   return len; \
+}
+
+static inline int memcpy_common(void *dst, const void *src, size_t n)
 {
-   do {
-   unsigned long size = min_t(unsigned long, handle-size, len);
-
-   memcpy(handle-addr, buf, size);
-
-   len -= size;
-   handle-addr += size;
-   buf += size;
-   handle-size -= size;
-   if (!handle-size) {
-   struct

[PATCH 03/13] perf, x86: Add copy_from_user_nmi_nochk for best effort copy

2012-08-01 Thread Jiri Olsa
Adding copy_from_user_nmi_nochk that provides the best effort
copy regardless the requesting size crossing the task boundary.

This is going to be useful for stack dump we need in post
DWARF CFI based unwind, where we have predefined size of
the user stack to dump, and we need to store the most of
the requested dump size, regardless this size is crossing
the task boundary.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/include/asm/uaccess.h |2 ++
 arch/x86/lib/usercopy.c|   15 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index e1f3a17..d8d6bcd 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -562,6 +562,8 @@ struct __large_struct { unsigned long buf[100]; };
 #endif /* CONFIG_X86_WP_WORKS_OK */
 
 extern unsigned long
+copy_from_user_nmi_nochk(void *to, const void __user *from, unsigned long n);
+extern unsigned long
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
 extern __must_check long
 strncpy_from_user(char *dst, const char __user *src, long count);
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c
index 4f74d94..29ca1c7 100644
--- a/arch/x86/lib/usercopy.c
+++ b/arch/x86/lib/usercopy.c
@@ -14,7 +14,7 @@
  * best effort, GUP based copy_from_user() that is NMI-safe
  */
 unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+copy_from_user_nmi_nochk(void *to, const void __user *from, unsigned long n)
 {
unsigned long offset, addr = (unsigned long)from;
unsigned long size, len = 0;
@@ -22,9 +22,6 @@ copy_from_user_nmi(void *to, const void __user *from, 
unsigned long n)
void *map;
int ret;
 
-   if (__range_not_ok(from, n, TASK_SIZE))
-   return len;
-
do {
ret = __get_user_pages_fast(addr, 1, 0, page);
if (!ret)
@@ -46,4 +43,14 @@ copy_from_user_nmi(void *to, const void __user *from, 
unsigned long n)
 
return len;
 }
+EXPORT_SYMBOL_GPL(copy_from_user_nmi_nochk);
+
+unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+   if (__range_not_ok(from, n, TASK_SIZE) == 0)
+   return 0;
+
+   return copy_from_user_nmi_nochk(to, from, n);
+}
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
-- 
1.7.7.6

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


[PATCH 07/13] perf: Add attribute to filter out callchains

2012-08-01 Thread Jiri Olsa
From: Frederic Weisbecker fweis...@gmail.com 

Introducing following bits to the the perf_event_attr struct:
  - exclude_callchain_kernel to filter out kernel callchain
from the sample dump
  - exclude_callchain_user to filter out user callchain
from the sample dump

We need to be able to disable standard user callchain dump
when we use the dwarf cfi callchain mode, because frame
pointer based user callchains are useless in this mode.

Implementing also exclude_callchain_kernel to have complete
set of options.

Signed-off-by: Frederic Weisbecker fweis...@gmail.com
[ Added kernel callchains filtering ]
Signed-off-by: Jiri Olsa jo...@redhat.com
CC: Andrew Vagin ava...@openvz.org
---
 include/linux/perf_event.h |5 -
 kernel/events/callchain.c  |   36 +---
 kernel/events/core.c   |6 +-
 kernel/events/internal.h   |3 ++-
 4 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d1d25f6..297ca3d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -268,7 +268,10 @@ struct perf_event_attr {
exclude_host   :  1, /* don't count in host   */
exclude_guest  :  1, /* don't count in guest  */
 
-   __reserved_1   : 43;
+   exclude_callchain_kernel : 1, /* exclude kernel 
callchains */
+   exclude_callchain_user   : 1, /* exclude user 
callchains */
+
+   __reserved_1   : 41;
 
union {
__u32   wakeup_events;/* wakeup every n events */
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index 98d4597..cbed627 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -154,7 +154,8 @@ put_callchain_entry(int rctx)
 }
 
 struct perf_callchain_entry *
-perf_callchain(struct perf_event *event, struct pt_regs *regs)
+perf_callchain(struct perf_event *event, struct pt_regs *regs,
+  int kernel, int user)
 {
int rctx;
struct perf_callchain_entry *entry;
@@ -169,24 +170,29 @@ perf_callchain(struct perf_event *event, struct pt_regs 
*regs)
 
entry-nr = 0;
 
-   if (!user_mode(regs)) {
+   if (kernel  !user_mode(regs)) {
perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
perf_callchain_kernel(entry, regs);
-   if (current-mm)
-   regs = task_pt_regs(current);
-   else
-   regs = NULL;
}
 
-   if (regs) {
-   /*
-* Disallow cross-task user callchains.
-*/
-   if (event-ctx-task  event-ctx-task != current)
-   goto exit_put;
-
-   perf_callchain_store(entry, PERF_CONTEXT_USER);
-   perf_callchain_user(entry, regs);
+   if (user) {
+   if (!user_mode(regs)) {
+   if  (current-mm)
+   regs = task_pt_regs(current);
+   else
+   regs = NULL;
+   }
+
+   if (regs) {
+   /*
+* Disallow cross-task user callchains.
+*/
+   if (event-ctx-task  event-ctx-task != current)
+   goto exit_put;
+
+   perf_callchain_store(entry, PERF_CONTEXT_USER);
+   perf_callchain_user(entry, regs);
+   }
}
 
 exit_put:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c4582bb..0902d4a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4130,8 +4130,12 @@ void perf_prepare_sample(struct perf_event_header 
*header,
 
if (sample_type  PERF_SAMPLE_CALLCHAIN) {
int size = 1;
+   int kernel = !event-attr.exclude_callchain_kernel;
+   int user   = !event-attr.exclude_callchain_user;
 
-   data-callchain = perf_callchain(event, regs);
+   if (kernel || user)
+   data-callchain = perf_callchain(event, regs,
+kernel, user);
 
if (data-callchain)
size += data-callchain-nr;
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index ce7bdfc..95d0215 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -126,7 +126,8 @@ DEFINE_OUTPUT_COPY(__output_copy_user, 
arch_perf_out_copy_user)
 
 /* Callchain handling */
 extern struct perf_callchain_entry *
-perf_callchain(struct perf_event *event, struct pt_regs *regs);
+perf_callchain(struct perf_event *event, struct pt_regs *regs,
+  int kernel, int user);
 extern int get_callchain_buffers(void);
 extern void put_callchain_buffers(void

[PATCH 05/13] perf: Add perf_output_skip function to skip bytes in sample

2012-08-01 Thread Jiri Olsa
Introducing perf_output_skip function to be able to skip data
within the perf ring buffer.

When writing data into perf ring buffer we first reserve needed
place in ring buffer and then copy the actual data.

There's a possibility we won't be able to fill all the reserved
size with data, so we need a way to skip the remaining bytes.

This is going to be useful when storing the user stack dump,
where we might end up with less data than we originally requested.

Signed-off-by: Jiri Olsa jo...@redhat.com
Acked-by: Frederic Weisbecker fweis...@gmail.com
---
 include/linux/perf_event.h  |2 ++
 kernel/events/internal.h|4 
 kernel/events/ring_buffer.c |6 ++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d41394a..8a73f75 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1321,6 +1321,8 @@ extern int perf_output_begin(struct perf_output_handle 
*handle,
 extern void perf_output_end(struct perf_output_handle *handle);
 extern unsigned int perf_output_copy(struct perf_output_handle *handle,
 const void *buf, unsigned int len);
+extern unsigned int perf_output_skip(struct perf_output_handle *handle,
+unsigned int len);
 extern int perf_swevent_get_recursion_context(void);
 extern void perf_swevent_put_recursion_context(int rctx);
 extern void perf_event_enable(struct perf_event *event);
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index 7fd5408..ce7bdfc 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -114,6 +114,10 @@ static inline int memcpy_common(void *dst, const void 
*src, size_t n)
 
 DEFINE_OUTPUT_COPY(__output_copy, memcpy_common)
 
+#define MEMCPY_SKIP(dst, src, n) (n)
+
+DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
+
 #ifndef arch_perf_out_copy_user
 #define arch_perf_out_copy_user __copy_from_user_inatomic
 #endif
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index b4c2ad3..23cb34f 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -188,6 +188,12 @@ unsigned int perf_output_copy(struct perf_output_handle 
*handle,
return __output_copy(handle, buf, len);
 }
 
+unsigned int perf_output_skip(struct perf_output_handle *handle,
+ unsigned int len)
+{
+   return __output_skip(handle, NULL, len);
+}
+
 void perf_output_end(struct perf_output_handle *handle)
 {
perf_output_put_handle(handle);
-- 
1.7.7.6

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


[PATCH 10/13] perf, tool: Add libunwind dependency for dwarf cfi unwinding

2012-08-01 Thread Jiri Olsa
Adding libunwind to be linked with perf if available. It's required
for the to get dwarf cfi unwinding support.

Also building perf with the dwarf call frame informations by default,
so that we can unwind callchains in perf itself.

Adding LIBUNWIND_DIR Makefile variable allowing user to specify
the directory with libunwind to be linked. This is used for
debug purposes.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/Makefile |   30 +-
 tools/perf/config/feature-tests.mak |   25 +
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 0548d93..a1ee011 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -38,6 +38,9 @@ include config/utilities.mak
 # Define NO_NEWT if you do not want TUI support.
 #
 # Define NO_DEMANGLE if you do not want C++ symbol demangling.
+#
+# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
+# backtrace post unwind.
 
 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
@@ -59,6 +62,7 @@ AR = $(CROSS_COMPILE)ar
 ifeq ($(ARCH),i386)
ARCH := x86
NO_PERF_REGS := 0
+   LIBUNWIND_LIBS = -lunwind -lunwind-x86
 endif
 ifeq ($(ARCH),x86_64)
ARCH := x86
@@ -72,6 +76,7 @@ ifeq ($(ARCH),x86_64)
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 
../../arch/x86/lib/memset_64.S
endif
NO_PERF_REGS := 0
+   LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
 endif
 
 # Treat warnings as errors unless directed not to
@@ -92,7 +97,7 @@ ifdef PARSER_DEBUG
PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
 endif
 
-CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 
$(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 
$(PARSER_DEBUG_CFLAGS)
+CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra 
-std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) 
$(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
 EXTLIBS = -lpthread -lrt -lelf -lm
 ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
-D_GNU_SOURCE
 ALL_LDFLAGS = $(LDFLAGS)
@@ -457,6 +462,21 @@ ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
 endif # Dwarf support
 endif # NO_DWARF
 
+ifndef NO_LIBUNWIND
+# for linking with debug library, run like:
+# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+ifdef LIBUNWIND_DIR
+   LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
+   LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+endif
+
+FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) 
$(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y)
+   msg := $(warning No libunwind found. Please install libunwind = 0.99);
+   NO_LIBUNWIND := 1
+endif # Libunwind support
+endif # NO_LIBUNWIND
+
 -include arch/$(ARCH)/Makefile
 
 ifneq ($(OUTPUT),)
@@ -488,6 +508,14 @@ else
 endif # PERF_HAVE_DWARF_REGS
 endif # NO_DWARF
 
+ifdef NO_LIBUNWIND
+   BASIC_CFLAGS += -DNO_LIBUNWIND_SUPPORT
+else
+   EXTLIBS += $(LIBUNWIND_LIBS)
+   BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
+   BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+endif
+
 ifdef NO_NEWT
BASIC_CFLAGS += -DNO_NEWT_SUPPORT
 else
diff --git a/tools/perf/config/feature-tests.mak 
b/tools/perf/config/feature-tests.mak
index 6c18785..2f1156a 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -154,3 +154,28 @@ int main(void)
return 0;
 }
 endef
+
+ifndef NO_LIBUNWIND
+define SOURCE_LIBUNWIND
+#include libunwind.h
+#include stdlib.h
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+  unw_word_t ip,
+  unw_dyn_info_t *di,
+  unw_proc_info_t *pi,
+  int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+int main(void)
+{
+   unw_addr_space_t addr_space;
+   addr_space = unw_create_addr_space(NULL, 0);
+   unw_init_remote(NULL, addr_space, NULL);
+   dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+   return 0;
+}
+endef
+endif
-- 
1.7.7.6

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


[PATCH 11/13] perf, tool: Support user regs and stack in sample parsing

2012-08-01 Thread Jiri Olsa
Adding following info to be parsed out of the event sample:
 - user register set
 - user stack dump

Both are global and specific to all events within the session.
This info will be used in the unwind patches coming in shortly.

Adding simple output printout (report -D) for both register and
stack dumps.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/builtin-test.c |4 ++--
 tools/perf/util/event.h   |   16 +++-
 tools/perf/util/evlist.c  |8 
 tools/perf/util/evlist.h  |1 +
 tools/perf/util/evsel.c   |   30 +-
 tools/perf/util/header.c  |2 ++
 tools/perf/util/python.c  |3 ++-
 tools/perf/util/session.c |   36 
 tools/perf/util/session.h |8 ++--
 9 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index d909eb7..000efb0 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -564,7 +564,7 @@ static int test__basic_mmap(void)
}
 
err = perf_event__parse_sample(event, attr.sample_type, 
sample_size,
-  false, sample, false);
+  false, 0, sample, false);
if (err) {
pr_err(Can't parse sample, err = %d\n, err);
goto out_munmap;
@@ -790,7 +790,7 @@ static int test__PERF_RECORD(void)
 
err = perf_event__parse_sample(event, 
sample_type,
   sample_size, 
true,
-  sample, false);
+  0, sample, 
false);
if (err  0) {
if (verbose)
perf_event__fprintf(event, 
stderr);
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1b19728..ed978eb 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -69,6 +69,16 @@ struct sample_event {
u64 array[];
 };
 
+struct regs_dump {
+   u64 *regs;
+};
+
+struct stack_dump {
+   u16 offset;
+   u64 size;
+   char *data;
+};
+
 struct perf_sample {
u64 ip;
u32 pid, tid;
@@ -82,6 +92,8 @@ struct perf_sample {
void *raw_data;
struct ip_callchain *callchain;
struct branch_stack *branch_stack;
+   struct regs_dump  user_regs;
+   struct stack_dump user_stack;
 };
 
 #define BUILD_ID_SIZE 20
@@ -199,7 +211,9 @@ const char *perf_event__name(unsigned int id);
 
 int perf_event__parse_sample(const union perf_event *event, u64 type,
 int sample_size, bool sample_id_all,
-struct perf_sample *sample, bool swapped);
+u64 sample_regs_user, struct perf_sample *data,
+bool swapped);
+
 int perf_event__synthesize_sample(union perf_event *event, u64 type,
  const struct perf_sample *sample,
  bool swapped);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3edfd34..057a27d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -689,6 +689,14 @@ bool perf_evlist__valid_sample_type(const struct 
perf_evlist *evlist)
return true;
 }
 
+u64 perf_evlist__sample_regs_user(const struct perf_evlist *evlist)
+{
+   struct perf_evsel *first;
+
+   first = list_entry(evlist-entries.next, struct perf_evsel, node);
+   return first-attr.sample_regs_user;
+}
+
 u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
 {
struct perf_evsel *first;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 40d4d3c..8dbf46c 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -124,6 +124,7 @@ u16 perf_evlist__id_hdr_size(const struct perf_evlist 
*evlist);
 
 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
+u64 perf_evlist__sample_regs_user(const struct perf_evlist *evlist);
 
 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
   struct list_head *list,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e817713..3a284b1 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -8,6 +8,7 @@
  */
 
 #include byteswap.h
+#include linux/bitops.h
 #include asm/bug.h
 #include evsel.h
 #include evlist.h
@@ -730,7 +731,8 @@ static bool sample_overlap(const union perf_event *event,
 
 int perf_event__parse_sample(const union perf_event *event, u64 type,
 int sample_size, bool sample_id_all

[PATCH 12/13] perf, tool: Support for dwarf cfi unwinding on post processing

2012-08-01 Thread Jiri Olsa
This brings the support for dwarf cfi unwinding on perf post
processing. Call frame informations are retrieved and then passed
to libunwind that requests memory and register content from the
applications.

Adding unwind object to handle the user stack backtrace based
on the user register values and user stack dump.

The unwind object access the libunwind via remote interface
and provides to it all the necessary data to unwind the stack.

The unwind interface provides following function:
unwind__get_entries

And callback (specified in above function) to retrieve
the backtrace entries:
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry,
 void *arg);

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/Makefile|2 +
 tools/perf/arch/x86/Makefile   |3 +
 tools/perf/arch/x86/util/unwind.c  |  111 
 tools/perf/builtin-report.c|   24 +-
 tools/perf/builtin-script.c|   16 +-
 tools/perf/builtin-top.c   |5 +-
 tools/perf/util/include/linux/compiler.h   |1 +
 tools/perf/util/map.h  |7 +-
 .../perf/util/scripting-engines/trace-event-perl.c |3 +-
 .../util/scripting-engines/trace-event-python.c|3 +-
 tools/perf/util/session.c  |   61 ++-
 tools/perf/util/session.h  |3 +-
 tools/perf/util/trace-event-scripting.c|3 +-
 tools/perf/util/trace-event.h  |5 +-
 tools/perf/util/unwind.c   |  567 
 tools/perf/util/unwind.h   |   34 ++
 16 files changed, 811 insertions(+), 37 deletions(-)
 create mode 100644 tools/perf/arch/x86/util/unwind.c
 create mode 100644 tools/perf/util/unwind.c
 create mode 100644 tools/perf/util/unwind.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index a1ee011..52e9e6c 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -328,6 +328,7 @@ LIB_H += util/cgroup.h
 LIB_H += $(TRACE_EVENT_DIR)event-parse.h
 LIB_H += util/target.h
 LIB_H += util/perf_regs.h
+LIB_H += util/unwind.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -514,6 +515,7 @@ else
EXTLIBS += $(LIBUNWIND_LIBS)
BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+   LIB_OBJS += $(OUTPUT)util/unwind.o
 endif
 
 ifdef NO_NEWT
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 744e629..815841c 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -2,4 +2,7 @@ ifndef NO_DWARF
 PERF_HAVE_DWARF_REGS := 1
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
 endif
+ifndef NO_LIBUNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
+endif
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
diff --git a/tools/perf/arch/x86/util/unwind.c 
b/tools/perf/arch/x86/util/unwind.c
new file mode 100644
index 000..78d956e
--- /dev/null
+++ b/tools/perf/arch/x86/util/unwind.c
@@ -0,0 +1,111 @@
+
+#include errno.h
+#include libunwind.h
+#include perf_regs.h
+#include ../../util/unwind.h
+
+#ifdef ARCH_X86_64
+int unwind__arch_reg_id(int regnum)
+{
+   int id;
+
+   switch (regnum) {
+   case UNW_X86_64_RAX:
+   id = PERF_REG_X86_AX;
+   break;
+   case UNW_X86_64_RDX:
+   id = PERF_REG_X86_DX;
+   break;
+   case UNW_X86_64_RCX:
+   id = PERF_REG_X86_CX;
+   break;
+   case UNW_X86_64_RBX:
+   id = PERF_REG_X86_BX;
+   break;
+   case UNW_X86_64_RSI:
+   id = PERF_REG_X86_SI;
+   break;
+   case UNW_X86_64_RDI:
+   id = PERF_REG_X86_DI;
+   break;
+   case UNW_X86_64_RBP:
+   id = PERF_REG_X86_BP;
+   break;
+   case UNW_X86_64_RSP:
+   id = PERF_REG_X86_SP;
+   break;
+   case UNW_X86_64_R8:
+   id = PERF_REG_X86_R8;
+   break;
+   case UNW_X86_64_R9:
+   id = PERF_REG_X86_R9;
+   break;
+   case UNW_X86_64_R10:
+   id = PERF_REG_X86_R10;
+   break;
+   case UNW_X86_64_R11:
+   id = PERF_REG_X86_R11;
+   break;
+   case UNW_X86_64_R12:
+   id = PERF_REG_X86_R12;
+   break;
+   case UNW_X86_64_R13:
+   id = PERF_REG_X86_R13;
+   break;
+   case UNW_X86_64_R14:
+   id = PERF_REG_X86_R14;
+   break;
+   case UNW_X86_64_R15:
+   id = PERF_REG_X86_R15;
+   break;
+   case UNW_X86_64_RIP:
+   id = PERF_REG_X86_IP

[PATCH 13/13] perf, tool: Support for dwarf mode callchain on perf record

2012-08-01 Thread Jiri Olsa
This patch enables perf to use the dwarf unwind code.

It extends the perf record '-g' option with following arguments:
  'fp'   - provides framepointer based user
   stack backtrace
  'dwarf[,size]' - provides dwarf (libunwind) based user stack
   backtrace. The size specifies the size of the
   user stack dump. If omitted it is 8192 by default.

If libunwind is found during the perf build, then the 'dwarf'
argument becomes available for record command. The 'fp' stays as
default option in any case.

Examples: (perf compiled with libunwind)

   perf record -g dwarf ls
  - provides dwarf unwind with 8192 as stack dump size

   perf record -g dwarf,4096 ls
  - provides dwarf unwind with 4096 as stack dump size

   perf record -g -- ls
   perf record -g fp ls
  - provides frame pointer unwind

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/builtin-record.c |  108 ++-
 tools/perf/perf.h   |9 +++-
 tools/perf/util/evsel.c |   13 +-
 3 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f5a6452..fff130b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,6 +31,15 @@
 #include sched.h
 #include sys/mman.h
 
+#define CALLCHAIN_HELP do call-graph (stack chain/backtrace) recording: 
+
+#ifdef NO_LIBUNWIND_SUPPORT
+static char callchain_help[] = CALLCHAIN_HELP [fp];
+#else
+static unsigned long default_stack_dump_size = 8192;
+static char callchain_help[] = CALLCHAIN_HELP [fp] dwarf;
+#endif
+
 enum write_mode_t {
WRITE_FORCE,
WRITE_APPEND
@@ -732,6 +741,100 @@ error:
return ret;
 }
 
+#ifndef NO_LIBUNWIND_SUPPORT
+static int get_stack_size(char *str, unsigned long *_size)
+{
+   char *endptr;
+   unsigned long size;
+   unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
+
+   size = strtoul(str, endptr, 0);
+
+   do {
+   if (*endptr)
+   break;
+
+   size = round_up(size, sizeof(u64));
+   if (!size || size  max_size)
+   break;
+
+   *_size = size;
+   return 0;
+
+   } while (0);
+
+   pr_err(callchain: Incorrect stack dump size (max %ld): %s\n,
+  max_size, str);
+   return -1;
+}
+#endif /* !NO_LIBUNWIND_SUPPORT */
+
+static int
+parse_callchain_opt(const struct option *opt __used, const char *arg,
+   int unset)
+{
+   struct perf_record *rec = (struct perf_record *)opt-value;
+   char *tok, *name, *saveptr = NULL;
+   char buf[20];
+   int ret = -1;
+
+   /* --no-call-graph */
+   if (unset)
+   return 0;
+
+   /* We specified default option if none is provided. */
+   BUG_ON(!arg);
+
+   /* We need buffer that we know we can write to. */
+   snprintf(buf, 20, %s, arg);
+
+   tok = strtok_r((char *)buf, ,, saveptr);
+   name = tok ? : (char *)buf;
+
+   do {
+   /* Framepointer style */
+   if (!strncmp(name, fp, sizeof(fp))) {
+   if (!strtok_r(NULL, ,, saveptr)) {
+   rec-opts.call_graph = CALLCHAIN_FP;
+   ret = 0;
+   } else
+   pr_err(callchain: No more arguments 
+  needed for -g fp\n);
+   break;
+
+#ifndef NO_LIBUNWIND_SUPPORT
+   /* Dwarf style */
+   } else if (!strncmp(name, dwarf, sizeof(dwarf))) {
+   ret = 0;
+   rec-opts.call_graph = CALLCHAIN_DWARF;
+   rec-opts.stack_dump_size = default_stack_dump_size;
+
+   tok = strtok_r(NULL, ,, saveptr);
+   if (tok) {
+   unsigned long size = 0;
+
+   ret = get_stack_size(tok, size);
+   rec-opts.stack_dump_size = size;
+   }
+
+   if (!ret)
+   pr_debug(callchain: stack dump size %d\n,
+rec-opts.stack_dump_size);
+#endif /* !NO_LIBUNWIND_SUPPORT */
+   } else {
+   pr_err(callchain: Unknown -g option 
+  value: %s\n, name);
+   break;
+   }
+
+   } while (0);
+
+   if (!ret)
+   pr_debug(callchain: type %d\n, rec-opts.call_graph);
+
+   return ret;
+}
+
 static const char * const record_usage[] = {
perf record [options] [command],
perf record [options] -- command [options],
@@ -803,8 +906,9 @@ const struct option record_options[] = {
 number

[PATCH 09/13] perf, tool: Add interface to arch registers sets

2012-08-01 Thread Jiri Olsa
Adding header files to access unified API for arch registers.
  util/perf_regs.h - global perf_reg declarations
  arch/x86/include/perf_regs.h - x86 arch specific

Adding perf_reg_name function to obtain register name based
on the reg ID value, and PERF_REGS_MASK macro with mask
definition of all current arch registers (will be used in
unwind patches).

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile |   13 +-
 tools/perf/arch/x86/include/perf_regs.h |   80 +++
 tools/perf/util/perf_regs.h |   14 +
 3 files changed, 106 insertions(+), 1 deletions(-)
 create mode 100644 tools/perf/arch/x86/include/perf_regs.h
 create mode 100644 tools/perf/util/perf_regs.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 77f124f..0548d93 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -50,13 +50,15 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e 
s/sun4u/sparc64/ \
  -e s/s390x/s390/ -e s/parisc64/parisc/ \
  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
  -e s/sh[234].*/sh/ )
+NO_PERF_REGS := 1
 
 CC = $(CROSS_COMPILE)gcc
 AR = $(CROSS_COMPILE)ar
 
 # Additional ARCH settings for x86
 ifeq ($(ARCH),i386)
-ARCH := x86
+   ARCH := x86
+   NO_PERF_REGS := 0
 endif
 ifeq ($(ARCH),x86_64)
ARCH := x86
@@ -69,6 +71,7 @@ ifeq ($(ARCH),x86_64)
ARCH_CFLAGS := -DARCH_X86_64
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 
../../arch/x86/lib/memset_64.S
endif
+   NO_PERF_REGS := 0
 endif
 
 # Treat warnings as errors unless directed not to
@@ -319,6 +322,7 @@ LIB_H += $(ARCH_INCLUDE)
 LIB_H += util/cgroup.h
 LIB_H += $(TRACE_EVENT_DIR)event-parse.h
 LIB_H += util/target.h
+LIB_H += util/perf_regs.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -670,6 +674,13 @@ else
endif
 endif
 
+ifeq ($(NO_PERF_REGS),0)
+   ifeq ($(ARCH),x86)
+   LIB_H += arch/x86/include/perf_regs.h
+   endif
+else
+   BASIC_CFLAGS += -DNO_PERF_REGS
+endif
 
 ifdef NO_STRLCPY
BASIC_CFLAGS += -DNO_STRLCPY
diff --git a/tools/perf/arch/x86/include/perf_regs.h 
b/tools/perf/arch/x86/include/perf_regs.h
new file mode 100644
index 000..46fc9f1
--- /dev/null
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -0,0 +1,80 @@
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include stdlib.h
+#include ../../util/types.h
+#include ../../../../../arch/x86/include/asm/perf_regs.h
+
+#ifndef ARCH_X86_64
+#define PERF_REGS_MASK ((1ULL  PERF_REG_X86_32_MAX) - 1)
+#else
+#define REG_NOSUPPORT ((1ULL  PERF_REG_X86_DS) | \
+  (1ULL  PERF_REG_X86_ES) | \
+  (1ULL  PERF_REG_X86_FS) | \
+  (1ULL  PERF_REG_X86_GS))
+#define PERF_REGS_MASK (((1ULL  PERF_REG_X86_64_MAX) - 1)  ~REG_NOSUPPORT)
+#endif
+#define PERF_REG_IP PERF_REG_X86_IP
+#define PERF_REG_SP PERF_REG_X86_SP
+
+static inline const char *perf_reg_name(int id)
+{
+   switch (id) {
+   case PERF_REG_X86_AX:
+   return AX;
+   case PERF_REG_X86_BX:
+   return BX;
+   case PERF_REG_X86_CX:
+   return CX;
+   case PERF_REG_X86_DX:
+   return DX;
+   case PERF_REG_X86_SI:
+   return SI;
+   case PERF_REG_X86_DI:
+   return DI;
+   case PERF_REG_X86_BP:
+   return BP;
+   case PERF_REG_X86_SP:
+   return SP;
+   case PERF_REG_X86_IP:
+   return IP;
+   case PERF_REG_X86_FLAGS:
+   return FLAGS;
+   case PERF_REG_X86_CS:
+   return CS;
+   case PERF_REG_X86_SS:
+   return SS;
+   case PERF_REG_X86_DS:
+   return DS;
+   case PERF_REG_X86_ES:
+   return ES;
+   case PERF_REG_X86_FS:
+   return FS;
+   case PERF_REG_X86_GS:
+   return GS;
+#ifdef ARCH_X86_64
+   case PERF_REG_X86_R8:
+   return R8;
+   case PERF_REG_X86_R9:
+   return R9;
+   case PERF_REG_X86_R10:
+   return R10;
+   case PERF_REG_X86_R11:
+   return R11;
+   case PERF_REG_X86_R12:
+   return R12;
+   case PERF_REG_X86_R13:
+   return R13;
+   case PERF_REG_X86_R14:
+   return R14;
+   case PERF_REG_X86_R15:
+   return R15;
+#endif /* ARCH_X86_64 */
+   default:
+   return NULL;
+   }
+
+   return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
new file mode 100644
index 000..3efb79a
--- /dev/null
+++ b/tools/perf/util/perf_regs.h
@@ -0,0 +1,14 @@
+#ifndef __PERF_REGS_H
+#define __PERF_REGS_H
+
+#ifndef NO_PERF_REGS_DEFS
+#include perf_regs.h
+#else
+#define PERF_REGS_MASK 0

[PATCH 08/13] perf, tool: Adding PERF_ATTR_SIZE_VER2 to the header swap check

2012-08-01 Thread Jiri Olsa
Updating attr_file_abi_sizes array with PERF_ATTR_SIZE_VER2 version,
so we have the swap check complete.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/header.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 3a6d204..5d470a3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1820,6 +1820,7 @@ out_free:
 static const int attr_file_abi_sizes[] = {
[0] = PERF_ATTR_SIZE_VER0,
[1] = PERF_ATTR_SIZE_VER1,
+   [2] = PERF_ATTR_SIZE_VER2,
0,
 };
 
-- 
1.7.7.6

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


[PATCH 02/13] perf: Add ability to attach user level registers dump to sample

2012-08-01 Thread Jiri Olsa
Introducing PERF_SAMPLE_REGS_USER sample type bit to trigger
the dump of user level registers on sample. Registers we want
to dump are specified by sample_regs_user bitmask.

Only user level registers are dumped at the moment. Meaning the
register values of the user space context as it was before the
user entered the kernel for whatever reason (syscall, irq,
exception, or a PMI happening in userspace).

The layout of the sample_regs_user bitmap is described in
asm/perf_regs.h for archs that support register dump.

This is going to be useful to bring Dwarf CFI based stack
unwinding on top of samples.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
[ Dump registers ABI specification. ]
Suggested-by: Stephane Eranian eran...@google.com
---
 arch/x86/kernel/perf_regs.c |   15 ++
 include/linux/perf_event.h  |   35 +--
 include/linux/perf_regs.h   |6 
 kernel/events/core.c|   66 +++
 4 files changed, 119 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
index c00c92a..83cf975 100644
--- a/arch/x86/kernel/perf_regs.c
+++ b/arch/x86/kernel/perf_regs.c
@@ -1,5 +1,7 @@
 
 #include linux/kernel.h
+#include linux/sched.h
+#include linux/perf_event.h
 #include linux/bug.h
 #include linux/stddef.h
 #include asm/perf_regs.h
@@ -71,6 +73,11 @@ int perf_reg_validate(u64 mask)
 
return 0;
 }
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+   return PERF_SAMPLE_REGS_ABI_32;
+}
 #else /* CONFIG_X86_64 */
 #define REG_NOSUPPORT ((1ULL  PERF_REG_X86_DS) | \
   (1ULL  PERF_REG_X86_ES) | \
@@ -87,4 +94,12 @@ int perf_reg_validate(u64 mask)
 
return 0;
 }
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+   if (test_tsk_thread_flag(task, TIF_IA32))
+   return PERF_SAMPLE_REGS_ABI_32;
+   else
+   return PERF_SAMPLE_REGS_ABI_64;
+}
 #endif /* CONFIG_X86_32 */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 7602ccb..3d4d847 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -130,8 +130,9 @@ enum perf_event_sample_format {
PERF_SAMPLE_STREAM_ID   = 1U  9,
PERF_SAMPLE_RAW = 1U  10,
PERF_SAMPLE_BRANCH_STACK= 1U  11,
+   PERF_SAMPLE_REGS_USER   = 1U  12,
 
-   PERF_SAMPLE_MAX = 1U  12, /* non-ABI */
+   PERF_SAMPLE_MAX = 1U  13, /* non-ABI */
 };
 
 /*
@@ -163,6 +164,15 @@ enum perf_branch_sample_type {
 PERF_SAMPLE_BRANCH_HV)
 
 /*
+ * Values to determine ABI of the registers dump.
+ */
+enum perf_sample_regs_abi {
+   PERF_SAMPLE_REGS_ABI_NONE   = 0,
+   PERF_SAMPLE_REGS_ABI_32 = 1,
+   PERF_SAMPLE_REGS_ABI_64 = 2,
+};
+
+/*
  * The format of the data returned by read() on a perf event fd,
  * as specified by attr.read_format:
  *
@@ -194,6 +204,7 @@ enum perf_event_read_format {
 #define PERF_ATTR_SIZE_VER064  /* sizeof first published struct */
 #define PERF_ATTR_SIZE_VER172  /* add: config2 */
 #define PERF_ATTR_SIZE_VER280  /* add: branch_sample_type */
+#define PERF_ATTR_SIZE_VER388  /* add: sample_regs_user */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
@@ -271,7 +282,13 @@ struct perf_event_attr {
__u64   bp_len;
__u64   config2; /* extension of config1 */
};
-   __u64   branch_sample_type; /* enum branch_sample_type */
+   __u64   branch_sample_type; /* enum perf_branch_sample_type */
+
+   /*
+* Defines set of user regs to dump on samples.
+* See asm/perf_regs.h for details.
+*/
+   __u64   sample_regs_user;
 };
 
 /*
@@ -548,6 +565,9 @@ enum perf_event_type {
 *char  data[size];} PERF_SAMPLE_RAW
 *
 *  { u64 from, to, flags } lbr[nr];}  PERF_SAMPLE_BRANCH_STACK
+*
+*  { u64   abi; # enum perf_sample_regs_abi
+*u64   regs[weight(mask)]; }  
PERF_SAMPLE_REGS_USER
 * };
 */
PERF_RECORD_SAMPLE  = 9,
@@ -609,6 +629,7 @@ struct perf_guest_info_callbacks {
 #include linux/static_key.h
 #include linux/atomic.h
 #include linux/sysfs.h
+#include linux/perf_regs.h
 #include asm/local.h
 
 struct perf_callchain_entry {
@@ -654,6 +675,11 @@ struct perf_branch_stack {
struct perf_branch_entryentries[0];
 };
 
+struct perf_regs_user {
+   __u64   abi;
+   struct pt_regs  *regs;
+};
+
 struct task_struct;
 
 /*
@@ -1133,6 +1159,7 @@ struct perf_sample_data {
struct perf_callchain_entry *callchain;
struct perf_raw_record  *raw;
struct perf_branch_stack*br_stack

Re: perf: commit 44f24cb3156a1e (Factor DSO symtab types) causes segfaults

2012-08-01 Thread Jiri Olsa
On Wed, Aug 01, 2012 at 01:57:40PM +0200, Markus Trippelsdorf wrote:
 On 2012.07.31 at 16:14 +0200, Ingo Molnar wrote:
  Jiri Olsa (4):
perf symbols: Factor DSO symtab types to generic binary types
 
 The commit above causes perf segfaults on my machine (running glibc trunk):
 
 (gdb) run top --stdio
 Starting program: /usr/src/linux/tools/perf/perf top --stdio
 warning: no loadable sections found in added symbol-file system-supplied DSO 
 at 0x77ffa000
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library /lib/libthread_db.so.1.
 
 Program received signal SIGSEGV, Segmentation fault.
 dso__load (dso=0x6661d0, map=map@entry=0x666170, filter=filter@entry=0x426840 
 symbol_filter) at util/symbol.c:1833
 1833dso-symtab_type = binary_type_symtab[i];
 (gdb) bt
 #0  dso__load (dso=0x6661d0, map=map@entry=0x666170, 
 filter=filter@entry=0x426840 symbol_filter) at util/symbol.c:1833
 #1  0x0045fe87 in map__load (self=self@entry=0x666170, 
 filter=filter@entry=0x426840 symbol_filter) at util/map.c:124
 #2  0x0045ffbd in map__find_symbol (self=0x666170, addr=11008, 
 filter=filter@entry=0x426840 symbol_filter) at util/map.c:168
 #3  0x0043b5df in perf_event__preprocess_sample 
 (event=event@entry=0x744c8720, machine=machine@entry=0x647730, 
 al=al@entry=0x7fffb030, sample=sample@entry=0x7fffb060, 
 filter=filter@entry=0x426840 symbol_filter) at util/event.c:886
 #4  0x00426d8e in perf_event__process_sample (machine=0x647730, 
 sample=0x7fffb060, evsel=optimized out, event=0x744c8720, 
 tool=0x7fffb2c0) at builtin-top.c:723
 #5  perf_top__mmap_read_idx (top=top@entry=0x7fffb2c0, idx=idx@entry=3) 
 at builtin-top.c:858
 #6  0x004291c3 in perf_top__mmap_read (top=optimized out) at 
 builtin-top.c:873
 #7  __cmd_top (top=0x7fffb2c0) at builtin-top.c:1040
 #8  cmd_top (argc=optimized out, argv=optimized out, prefix=optimized 
 out) at builtin-top.c:1348
 #9  0x00414d03 in run_builtin (p=p@entry=0x4dc888, argc=argc@entry=2, 
 argv=argv@entry=0x7fffe0b0) at perf.c:273
 #10 0x00415487 in handle_internal_command (argv=0x7fffe0b0, 
 argc=2) at perf.c:345
 #11 run_argv (argv=0x7fffdeb0, argcp=0x7fffdebc) at perf.c:389
 #12 main (argc=2, argv=0x7fffe0b0) at perf.c:487
 (gdb)
hi,
I cannot reproduce, but found one obvious bug,
could you please test?

thanks,
jirka

---
 tools/perf/util/symbol.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fdad4eee..fe86612 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = {
DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
+#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
 
 static enum dso_binary_type binary_type_data[] = {
DSO_BINARY_TYPE__BUILD_ID_CACHE,
@@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = {
DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data)
+#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
 
 int dso__name_len(const struct dso *dso)
 {
-- 
1.7.7.6

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


Re: perf: commit 44f24cb3156a1e (Factor DSO symtab types) causes segfaults

2012-08-01 Thread Jiri Olsa
On Wed, Aug 01, 2012 at 02:25:22PM +0200, Markus Trippelsdorf wrote:
 On 2012.08.01 at 14:21 +0200, Jiri Olsa wrote:
  On Wed, Aug 01, 2012 at 01:57:40PM +0200, Markus Trippelsdorf wrote:
   On 2012.07.31 at 16:14 +0200, Ingo Molnar wrote:
Jiri Olsa (4):
  perf symbols: Factor DSO symtab types to generic binary types
   
   The commit above causes perf segfaults on my machine (running glibc 
   trunk):
   
   (gdb) run top --stdio
   Starting program: /usr/src/linux/tools/perf/perf top --stdio
   warning: no loadable sections found in added symbol-file system-supplied 
   DSO at 0x77ffa000
   [Thread debugging using libthread_db enabled]
   Using host libthread_db library /lib/libthread_db.so.1.
   
   Program received signal SIGSEGV, Segmentation fault.
   dso__load (dso=0x6661d0, map=map@entry=0x666170, 
   filter=filter@entry=0x426840 symbol_filter) at util/symbol.c:1833
   1833dso-symtab_type = binary_type_symtab[i];
   (gdb) bt
   #0  dso__load (dso=0x6661d0, map=map@entry=0x666170, 
   filter=filter@entry=0x426840 symbol_filter) at util/symbol.c:1833
   #1  0x0045fe87 in map__load (self=self@entry=0x666170, 
   filter=filter@entry=0x426840 symbol_filter) at util/map.c:124
   #2  0x0045ffbd in map__find_symbol (self=0x666170, addr=11008, 
   filter=filter@entry=0x426840 symbol_filter) at util/map.c:168
   #3  0x0043b5df in perf_event__preprocess_sample 
   (event=event@entry=0x744c8720, machine=machine@entry=0x647730, 
   al=al@entry=0x7fffb030, sample=sample@entry=0x7fffb060, 
   filter=filter@entry=0x426840 symbol_filter) at util/event.c:886
   #4  0x00426d8e in perf_event__process_sample (machine=0x647730, 
   sample=0x7fffb060, evsel=optimized out, event=0x744c8720, 
   tool=0x7fffb2c0) at builtin-top.c:723
   #5  perf_top__mmap_read_idx (top=top@entry=0x7fffb2c0, 
   idx=idx@entry=3) at builtin-top.c:858
   #6  0x004291c3 in perf_top__mmap_read (top=optimized out) at 
   builtin-top.c:873
   #7  __cmd_top (top=0x7fffb2c0) at builtin-top.c:1040
   #8  cmd_top (argc=optimized out, argv=optimized out, 
   prefix=optimized out) at builtin-top.c:1348
   #9  0x00414d03 in run_builtin (p=p@entry=0x4dc888, 
   argc=argc@entry=2, argv=argv@entry=0x7fffe0b0) at perf.c:273
   #10 0x00415487 in handle_internal_command (argv=0x7fffe0b0, 
   argc=2) at perf.c:345
   #11 run_argv (argv=0x7fffdeb0, argcp=0x7fffdebc) at perf.c:389
   #12 main (argc=2, argv=0x7fffe0b0) at perf.c:487
   (gdb)
 
  I cannot reproduce, but found one obvious bug,
  could you please test?
 
 Your patch fixes the issue.
 Thank you.

thanks, I'll send official patch ASAP

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


[PATCH] perf, tool: Fix array sizes for binary types arrays

2012-08-01 Thread Jiri Olsa
Following commit introduced wrong array boundaries, that could
lead to SIGSEGV.

  perf symbols: Factor DSO symtab types to generic binary types
  commit 44f24cb3156a1e7d2b6bb501b7f6153aed08994c
  Author: Jiri Olsa jo...@redhat.com

Fixing to use proper array size.

Reported-by: Markus Trippelsdorf mar...@trippelsdorf.de
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/symbol.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fdad4eee..fe86612 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = {
DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
+#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
 
 static enum dso_binary_type binary_type_data[] = {
DSO_BINARY_TYPE__BUILD_ID_CACHE,
@@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = {
DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data)
+#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
 
 int dso__name_len(const struct dso *dso)
 {
-- 
1.7.7.6

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


[PATCH] perf, test: Fix parse events automated tests

2012-08-01 Thread Jiri Olsa
Parse events tests got broken after following commit:

  perf tools: Fix trace events storms due to weight demux
  commit 0983cc0dbca45250cbb5984bec7c303ac265b8e5
  Author: Frederic Weisbecker fweis...@gmail.com

that added PERF_SAMPLE_PERIOD sample type for tracepoints.

Updating related tests.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/util/parse-events-test.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/parse-events-test.c 
b/tools/perf/util/parse-events-test.c
index 1b997d2..127d648 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -13,6 +13,9 @@ do { \
} \
 } while (0)
 
+#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
+PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
+
 static int test__checkevent_tracepoint(struct perf_evlist *evlist)
 {
struct perf_evsel *evsel = list_entry(evlist-entries.next,
@@ -21,8 +24,7 @@ static int test__checkevent_tracepoint(struct perf_evlist 
*evlist)
TEST_ASSERT_VAL(wrong number of entries, 1 == evlist-nr_entries);
TEST_ASSERT_VAL(wrong type, PERF_TYPE_TRACEPOINT == evsel-attr.type);
TEST_ASSERT_VAL(wrong sample_type,
-   (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
-   evsel-attr.sample_type);
+   PERF_TP_SAMPLE_TYPE == evsel-attr.sample_type);
TEST_ASSERT_VAL(wrong sample_period, 1 == evsel-attr.sample_period);
return 0;
 }
@@ -37,8 +39,7 @@ static int test__checkevent_tracepoint_multi(struct 
perf_evlist *evlist)
TEST_ASSERT_VAL(wrong type,
PERF_TYPE_TRACEPOINT == evsel-attr.type);
TEST_ASSERT_VAL(wrong sample_type,
-   (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
-   == evsel-attr.sample_type);
+   PERF_TP_SAMPLE_TYPE == evsel-attr.sample_type);
TEST_ASSERT_VAL(wrong sample_period,
1 == evsel-attr.sample_period);
}
@@ -428,8 +429,7 @@ static int test__checkevent_list(struct perf_evlist *evlist)
evsel = list_entry(evsel-node.next, struct perf_evsel, node);
TEST_ASSERT_VAL(wrong type, PERF_TYPE_TRACEPOINT == evsel-attr.type);
TEST_ASSERT_VAL(wrong sample_type,
-   (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
-   evsel-attr.sample_type);
+   PERF_TP_SAMPLE_TYPE == evsel-attr.sample_type);
TEST_ASSERT_VAL(wrong sample_period, 1 == evsel-attr.sample_period);
TEST_ASSERT_VAL(wrong exclude_user, evsel-attr.exclude_user);
TEST_ASSERT_VAL(wrong exclude_kernel, !evsel-attr.exclude_kernel);
-- 
1.7.7.6

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


Re: [PATCH 13/13] perf, tool: Support for dwarf mode callchain on perf record

2012-08-01 Thread Jiri Olsa
On Wed, Aug 01, 2012 at 08:26:11AM -0600, David Ahern wrote:
 On 8/1/12 4:11 AM, Jiri Olsa wrote:
 +static int
 +parse_callchain_opt(const struct option *opt __used, const char *arg,
 +int unset)
 +{
 +struct perf_record *rec = (struct perf_record *)opt-value;
 +char *tok, *name, *saveptr = NULL;
 +char buf[20];
 +int ret = -1;
 +
 +/* --no-call-graph */
 +if (unset)
 +return 0;
 +
 +/* We specified default option if none is provided. */
 +BUG_ON(!arg);
 +
 +/* We need buffer that we know we can write to. */
 +snprintf(buf, 20, %s, arg);
 
 Isn't arg the user supplied string? What if the user messes up and
 passes in 20+ characters to -g argument?

  [jolsa@dhcp-26-214 perf]$ ./perf record -g 
dwarf123213214321432143214321432143214321432143214321 ls
  callchain: Unknown -g option value: dwarf12321321432143
  ...

hm, but if user specified it like this:

  [jolsa@dhcp-26-214 perf]$ ./perf record -vg 'dwarf,5' 
ls
  callchain: Incorrect stack dump size (max 65528):  

then we're in trouble.. I'll send a fix

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


Re: [PATCH 07/13] perf: Add attribute to filter out callchains

2012-08-02 Thread Jiri Olsa
On Thu, Aug 02, 2012 at 11:38:26AM +0400, Andrew Vagin wrote:
 On Wed, Aug 01, 2012 at 02:10:59PM +0400, Jiri Olsa wrote:
  From: Frederic Weisbecker fweis...@gmail.com 
  
  Introducing following bits to the the perf_event_attr struct:
- exclude_callchain_kernel to filter out kernel callchain
  from the sample dump
- exclude_callchain_user to filter out user callchain
  from the sample dump
  
  We need to be able to disable standard user callchain dump
  when we use the dwarf cfi callchain mode, because frame
  pointer based user callchains are useless in this mode.
  
  Implementing also exclude_callchain_kernel to have complete
  set of options.
  
  Signed-off-by: Frederic Weisbecker fweis...@gmail.com
  [ Added kernel callchains filtering ]
  Signed-off-by: Jiri Olsa jo...@redhat.com
  CC: Andrew Vagin ava...@openvz.org
 
 Acked-by: Andrew Vagin ava...@openvz.org
 
 
  diff --git a/kernel/events/core.c b/kernel/events/core.c
  index c4582bb..0902d4a 100644
  --- a/kernel/events/core.c
  +++ b/kernel/events/core.c
  @@ -4130,8 +4130,12 @@ void perf_prepare_sample(struct perf_event_header 
  *header,
   
  if (sample_type  PERF_SAMPLE_CALLCHAIN) {
  int size = 1;
  +   int kernel = !event-attr.exclude_callchain_kernel;
  +   int user   = !event-attr.exclude_callchain_user;
   
  -   data-callchain = perf_callchain(event, regs);
  +   if (kernel || user)
  +   data-callchain = perf_callchain(event, regs,
  +kernel, user);
 I am not sure, that we need two arguments kernel and user here,
 we can get them from event inside perf_callchain...

right.. I'll send an update with other fixies

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


Re: [PATCH 03/17] perf, x86: Add copy_from_user_nmi_nochk for best effort copy

2012-08-03 Thread Jiri Olsa
On Thu, Aug 02, 2012 at 11:47:30AM -0700, Andy Lutomirski wrote:
 On 07/22/2012 05:14 AM, Jiri Olsa wrote:
  Adding copy_from_user_nmi_nochk that provides the best effort
  copy regardless the requesting size crossing the task boundary.
  
  This is going to be useful for stack dump we need in post
  DWARF CFI based unwind, where we have predefined size of
  the user stack to dump, and we need to store the most of
  the requested dump size, regardless this size is crossing
  the task boundary.
 
 Huh?  This is a TASK_SIZE check, which makes sure that the request
 doesn't cross into kernel land.  Otherwise userspace could presumably
 read kernel memory by setting bogus values of sp.

haven't realized that..  new version won't have this

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


Re: [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs

2012-08-20 Thread Jiri Olsa
On Mon, Aug 20, 2012 at 10:25:42AM +0200, Stephane Eranian wrote:
 On Mon, Jul 9, 2012 at 10:37 PM, Jiri Olsa jo...@redhat.com wrote:

SNIP

  +static ssize_t event_sysfs_data(char *page, u64 config)
  +{
  +   u64 event  = (config  ARCH_PERFMON_EVENTSEL_EVENT) |
  +(config  AMD64_EVENTSEL_EVENT)  24;
  +   u64 umask  = (config  ARCH_PERFMON_EVENTSEL_UMASK)  8;
  +   u64 inv= (config  ARCH_PERFMON_EVENTSEL_INV)  23;
  +   u64 cmask  = (config  ARCH_PERFMON_EVENTSEL_CMASK)  24;
  +   ssize_t ret;
  +
  +   /*
  +* We have whole page size to spend and just little data
  +* to write, so we can safely use sprintf.
  +*/
  +   ret = sprintf(page, event=0x%02llx, event);
  +
  +   if (umask)
  +   ret += sprintf(page + ret, ,umask=0x%02llx, umask);
  +
  +   if (inv)
  +   ret += sprintf(page + ret, ,inv);
  +
  +   if (cmask)
  +   ret += sprintf(page + ret, ,cmask=0x%02llx, cmask);
  +
 
 You are not handling the model specific modifiers such as any_thread on Intel.
 It's not used right now. But you should handle the case now. That will avoid
 problems in the future.

ok, will add those

 
  +   ret += sprintf(page + ret, \n);
  +
  +   return ret;
  +}

SNIP

   static const struct attribute_group *x86_pmu_attr_groups[] = {
  x86_pmu_attr_group,
  x86_pmu_format_group,
  +   x86_pmu_events_group,
  NULL,
   };
 
 You are not checking whether or not the generic event is even available on the
 host core PMU. You don't want to expose generic events which are not 
 available.

thats what patch 2 does

 And if you do this, then you need to take care of the other arch as well. They
 also deserve the extended syntax.

hm, I could try to add something for ppc, but that's where my arch
hw availability ends

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


Re: [PATCH 5/8] perf tools: Catch event names from command line

2012-08-20 Thread Jiri Olsa
On Thu, Aug 16, 2012 at 09:10:21PM +0200, Robert Richter wrote:
 Use command line string provided by the -e option to name events. This
 way we get unique events names that also support pmu event syntax
 (pmu_name/config/modifier). No need to reconstruct the name
 anymore from its attributes. We use the event_desc of the header to
 store the name in the perf.data header. Thus it is also available for
 perf report.
 
 Implemented by putting the parser in different states to parse events
 or configs.

I like the idea of multiple states in parser,
but parse tests fails:

[jolsa@krava perf]$ ./perf test -vvv parse
 5: parse events tests:
--- start ---
running test 0 'syscalls:sys_enter_open'
running test 1 'syscalls:*'
running test 2 'r1a'
running test 3 '1:1'
running test 4 'instructions'
running test 5 'cycles/period=10,config2/'
running test 6 'faults'
running test 7 'L1-dcache-load-miss'
running test 8 'mem:0'
running test 9 'mem:0:x'
running test 10 'mem:0:r'
running test 11 'mem:0:w'
running test 12 'syscalls:sys_enter_open:k'
running test 13 'syscalls:*:u'
running test 14 'r1a:kp'
running test 15 '1:1:hp'
running test 16 'instructions:h'
running test 17 'faults:u'
running test 18 'L1-dcache-load-miss:kp'
running test 19 'mem:0:u'
FAILED util/parse-events-test.c:309 wrong name
 end 
parse events tests: FAILED!


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


Re: [GIT PULL 00/24] perf/core improvements and fixes

2012-08-21 Thread Jiri Olsa
On Tue, Aug 21, 2012 at 11:32:31AM +0200, Ingo Molnar wrote:
 
 * Arnaldo Carvalho de Melo a...@infradead.org wrote:
 

SNIP

 
 One minor observation, the Makefile tells us:
 
 Makefile:496: No libunwind found. Please install libunwind = 0.99
 
 I guess that should be libunwind-dev[el], right? Plain libunwind 
 is not enough.

right, will fix it

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


[PATCH] misc: ifdef KMOD, saving some bytes probably

2008-02-08 Thread Jiri Olsa
found some code in misc.c that could be ifdef'ed for KMOD

Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
---
 drivers/char/misc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index a39101f..3455b09 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -126,7 +126,8 @@ static int misc_open(struct inode * inode, struct file * 
file)
break;
}
}
-   
+
+#if defined(CONFIG_KMOD)
if (!new_fops) {
mutex_unlock(misc_mtx);
request_module(char-major-%d-%d, MISC_MAJOR, minor);
@@ -141,6 +142,10 @@ static int misc_open(struct inode * inode, struct file * 
file)
if (!new_fops)
goto fail;
}
+#else
+   if (!new_fops)
+   goto fail;
+#endif
 
err = 0;
old_fops = file-f_op;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] fs: removing unused fops from struct char_device_struct

2008-02-20 Thread Jiri Olsa
Hi,

seems struct char_device_struct::fops is no longer used, removing it.
I checked with make allyesconfig and got proper compile.

Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
---
 fs/char_dev.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index c3bfa76..e4527fb 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -55,7 +55,6 @@ static struct char_device_struct {
unsigned int baseminor;
int minorct;
char name[64];
-   struct file_operations *fops;
struct cdev *cdev;  /* will die */
 } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fs: removing unused fops from struct char_device_struct

2008-02-20 Thread Jiri Olsa
oops, sorry... for some reason I though you were the guy :)
I'll resend

jirka


Greg KH wrote:
 On Wed, Feb 20, 2008 at 09:57:23PM +0100, Jiri Olsa wrote:
 Hi,

 seems struct char_device_struct::fops is no longer used, removing it.
 I checked with make allyesconfig and got proper compile.

 Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
 
 Hm, why send this to me?
 
 Did I make the mistake of touching this file last?  Hm, nope, someone
 else touched it after I did, I'm safe :)
 
 Seriously, I have no problem with this, but it should probably go
 through Andrew.
 
 thanks,
 
 greg k-h
 

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


[PATCH] kernel: Removing duplicit #includes

2007-11-07 Thread Jiri Olsa

Removing duplicit #includes for kernel/
Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
---
kernel/printk.c  |1 -
kernel/profile.c |2 --
kernel/sysctl.c  |1 -
3 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/kernel/printk.c b/kernel/printk.c
index a30fe33..3f06748 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -32,7 +32,6 @@
#include linux/security.h
#include linux/bootmem.h
#include linux/syscalls.h
-#include linux/jiffies.h

#include asm/uaccess.h

diff --git a/kernel/profile.c b/kernel/profile.c
index 5e95330..92b71ea 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -20,7 +20,6 @@
#include linux/mm.h
#include linux/cpumask.h
#include linux/cpu.h
-#include linux/profile.h
#include linux/highmem.h
#include linux/mutex.h
#include asm/sections.h
@@ -425,7 +424,6 @@ void profile_tick(int type)
#ifdef CONFIG_PROC_FS
#include linux/proc_fs.h
#include asm/uaccess.h
-#include asm/ptrace.h

static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
   int count, int *eof, void *data)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3b4efbe..5aec15e 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -37,7 +37,6 @@
#include linux/highuid.h
#include linux/writeback.h
#include linux/hugetlb.h
-#include linux/security.h
#include linux/initrd.h
#include linux/times.h
#include linux/limits.h
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] kernel: Removing duplicit #includes

2007-11-07 Thread Jiri Olsa
Removing duplicit #includes for kernel/
Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
---
 kernel/printk.c  |1 -
 kernel/profile.c |2 --
 kernel/sysctl.c  |1 -
 3 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/kernel/printk.c b/kernel/printk.c
index a30fe33..3f06748 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -32,7 +32,6 @@
 #include linux/security.h
 #include linux/bootmem.h
 #include linux/syscalls.h
-#include linux/jiffies.h
 
 #include asm/uaccess.h
 
diff --git a/kernel/profile.c b/kernel/profile.c
index 5e95330..92b71ea 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -20,7 +20,6 @@
 #include linux/mm.h
 #include linux/cpumask.h
 #include linux/cpu.h
-#include linux/profile.h
 #include linux/highmem.h
 #include linux/mutex.h
 #include asm/sections.h
@@ -425,7 +424,6 @@ void profile_tick(int type)
 #ifdef CONFIG_PROC_FS
 #include linux/proc_fs.h
 #include asm/uaccess.h
-#include asm/ptrace.h
 
 static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3b4efbe..5aec15e 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -37,7 +37,6 @@
 #include linux/highuid.h
 #include linux/writeback.h
 #include linux/hugetlb.h
-#include linux/security.h
 #include linux/initrd.h
 #include linux/times.h
 #include linux/limits.h
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] kernel: Removing duplicit #includes

2007-11-07 Thread Jiri Olsa
sorry, the patch is mangled, I will resend another 

Jiri Olsa wrote:
 Removing duplicit #includes for kernel/
 Signed-off-by: Jiri Olsa [EMAIL PROTECTED]
 ---
 kernel/printk.c  |1 -
 kernel/profile.c |2 --
 kernel/sysctl.c  |1 -
 3 files changed, 0 insertions(+), 4 deletions(-)
 
 diff --git a/kernel/printk.c b/kernel/printk.c
 index a30fe33..3f06748 100644
 --- a/kernel/printk.c
 +++ b/kernel/printk.c
 @@ -32,7 +32,6 @@
 #include linux/security.h
 #include linux/bootmem.h
 #include linux/syscalls.h
 -#include linux/jiffies.h
 
 #include asm/uaccess.h
 
 diff --git a/kernel/profile.c b/kernel/profile.c
 index 5e95330..92b71ea 100644
 --- a/kernel/profile.c
 +++ b/kernel/profile.c
 @@ -20,7 +20,6 @@
 #include linux/mm.h
 #include linux/cpumask.h
 #include linux/cpu.h
 -#include linux/profile.h
 #include linux/highmem.h
 #include linux/mutex.h
 #include asm/sections.h
 @@ -425,7 +424,6 @@ void profile_tick(int type)
 #ifdef CONFIG_PROC_FS
 #include linux/proc_fs.h
 #include asm/uaccess.h
 -#include asm/ptrace.h
 
 static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
 diff --git a/kernel/sysctl.c b/kernel/sysctl.c
 index 3b4efbe..5aec15e 100644
 --- a/kernel/sysctl.c
 +++ b/kernel/sysctl.c
 @@ -37,7 +37,6 @@
 #include linux/highuid.h
 #include linux/writeback.h
 #include linux/hugetlb.h
 -#include linux/security.h
 #include linux/initrd.h
 #include linux/times.h
 #include linux/limits.h
 

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


Re: [PATCHv3 0/3] perf tool: Add new event group management

2012-07-09 Thread Jiri Olsa
On Fri, Jul 06, 2012 at 03:42:54AM +0200, Stephane Eranian wrote:
 On Fri, Jul 6, 2012 at 3:32 AM, Ulrich Drepper drep...@gmail.com wrote:
  On Thu, Jul 5, 2012 at 12:15 PM, Stephane Eranian eran...@google.com 
  wrote:
  I don't understand why you actually need the :2 suffix. There can
  only be one leader. So assume it is the first one. Users have to
  know the first one is the leader which seems like a natural thing
  to do for me. It would make you syntax less ugly than it already
  is.
 
  In a blue sky world I would have done this.  In fact, this is what I
  tried before reading the sources to find out there is no group support
  so far.  But given that multiple -e options already have a meaning I
  would be hesitant to change this.
 
 That's why I said you activate grouping via -e only when you have
 the --group-events or --group-reads option in front. That would
 not change the meaning of the multiple -e when none of those
 group options are specified.

I discussed this with peter..

peterz the {} thing allows: 1) multiple groups in a single -e, 2) group 
attributes 

as for the leader sampling, we can have the first event to become the leader
by default (omit the leader index modifier) and enable the leader sampling by
another modifier:

peterz right, just make it a single 'l' (el not one) to indicate 'leader' 
sampling


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


[PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax

2012-07-09 Thread Jiri Olsa
hi,
here's the change to make following syntax available:
  perf stat -e cpu/event=instructions/u ls

this is identical to:
  perf stat -e instructions:u ls

v3 changes:
  - patches v2 1,5,6,9 are already in
  - patch 1 - sysfs 'events' attribute file names with dashes '-'
- using 'event/umask/inv/cmask' terms assigments instead simple 
'config'
  - patch 2 - undefined events sysfs attributes filtered out

v2 changes:
  - making the hw events translations available under the 'events',
the userspace trnaslation is then done by existing term aliasing
code with some little tweeks ;)
  - patches 1-3 are independent fixies

Attached patches:
  1/6 perf, x86: Making hardware events translations available in sysfs
  2/6 perf, x86: Filter out undefined events from sysfs events attribute
  3/6 perf, tool: Fix pmu object alias initialization
  4/6 perf, tool: Properly free format data
  5/6 perf, tool: Add support to specify hw event as pmu event term
  6/6 perf, test: Add automated tests for pmu sysfs translated events

jirka
---
 arch/x86/kernel/cpu/perf_event.c|   98 
+
 tools/perf/util/parse-events-test.c |   75 
+++--
 tools/perf/util/parse-events.c  |   13 +
 tools/perf/util/parse-events.h  |2 ++
 tools/perf/util/parse-events.y  |9 ++
 tools/perf/util/pmu.c   |   59 
---
 6 files changed, 232 insertions(+), 24 deletions(-)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/6] perf, x86: Making hardware events translations available in sysfs

2012-07-09 Thread Jiri Olsa
Making hardware events translations available through the sysfs.
Adding 'events' group attribute under the sysfs x86 PMU record
with attribute/file for each hardware event:

  # ls  /sys/devices/cpu/events/
  branch-instructions
  branch-misses
  bus-cycles
  cache-misses
  cache-references
  cpu-cycles
  instructions
  ref-cycles
  stalled-cycles-backend
  stalled-cycles-frontend

The file - hw event ID mappings is:

  file  hw event ID
  ---
  cpu-cyclesPERF_COUNT_HW_CPU_CYCLES
  instructions  PERF_COUNT_HW_INSTRUCTIONS
  cache-references  PERF_COUNT_HW_CACHE_REFERENCES
  cache-misses  PERF_COUNT_HW_CACHE_MISSES
  branch-instructions   PERF_COUNT_HW_BRANCH_INSTRUCTIONS
  branch-misses PERF_COUNT_HW_BRANCH_MISSES
  bus-cyclesPERF_COUNT_HW_BUS_CYCLES
  stalled-cycles-frontend   PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
  stalled-cycles-backendPERF_COUNT_HW_STALLED_CYCLES_BACKEND
  ref-cyclesPERF_COUNT_HW_REF_CPU_CYCLES

Each file in 'events' directory contains term translation for the
symbolic hw event for the currently running cpu model.

  # cat /sys/devices/cpu/events/stalled-cycles-backend
  event=0xb1,umask=0x01,inv,cmask=0x01

Suggested-by: Peter Zijlstra a.p.zijls...@chello.nl
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/kernel/cpu/perf_event.c |   74 ++
 1 file changed, 74 insertions(+)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 29557aa..09452c2 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1638,9 +1638,83 @@ static struct attribute_group x86_pmu_attr_group = {
.attrs = x86_pmu_attrs,
 };
 
+static ssize_t event_sysfs_data(char *page, u64 config)
+{
+   u64 event  = (config  ARCH_PERFMON_EVENTSEL_EVENT) |
+(config  AMD64_EVENTSEL_EVENT)  24;
+   u64 umask  = (config  ARCH_PERFMON_EVENTSEL_UMASK)  8;
+   u64 inv= (config  ARCH_PERFMON_EVENTSEL_INV)  23;
+   u64 cmask  = (config  ARCH_PERFMON_EVENTSEL_CMASK)  24;
+   ssize_t ret;
+
+   /*
+* We have whole page size to spend and just little data
+* to write, so we can safely use sprintf.
+*/
+   ret = sprintf(page, event=0x%02llx, event);
+
+   if (umask)
+   ret += sprintf(page + ret, ,umask=0x%02llx, umask);
+
+   if (inv)
+   ret += sprintf(page + ret, ,inv);
+
+   if (cmask)
+   ret += sprintf(page + ret, ,cmask=0x%02llx, cmask);
+
+   ret += sprintf(page + ret, \n);
+
+   return ret;
+}
+
+#define PMU_EVENTS_ATTR(_name, _id)\
+static ssize_t \
+_id##_show(struct device *dev, \
+  struct device_attribute *attr,   \
+  char *page)  \
+{  \
+   u64 config = x86_pmu.event_map(_id);\
+   BUILD_BUG_ON(_id = PERF_COUNT_HW_MAX); \
+   return event_sysfs_data(page, config);  \
+}  \
+   \
+static struct device_attribute event_attr_##_id =  \
+   __ATTR(_name, 0444, _id##_show, NULL)
+
+PMU_EVENTS_ATTR(cpu-cycles, PERF_COUNT_HW_CPU_CYCLES);
+PMU_EVENTS_ATTR(instructions, PERF_COUNT_HW_INSTRUCTIONS);
+PMU_EVENTS_ATTR(cache-references, PERF_COUNT_HW_CACHE_REFERENCES);
+PMU_EVENTS_ATTR(cache-misses, PERF_COUNT_HW_CACHE_MISSES);
+PMU_EVENTS_ATTR(branch-instructions, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+PMU_EVENTS_ATTR(branch-misses, PERF_COUNT_HW_BRANCH_MISSES);
+PMU_EVENTS_ATTR(bus-cycles, PERF_COUNT_HW_BUS_CYCLES);
+PMU_EVENTS_ATTR(stalled-cycles-frontend, 
PERF_COUNT_HW_STALLED_CYCLES_FRONTEND);
+PMU_EVENTS_ATTR(stalled-cycles-backend, PERF_COUNT_HW_STALLED_CYCLES_BACKEND);
+PMU_EVENTS_ATTR(ref-cycles, PERF_COUNT_HW_REF_CPU_CYCLES);
+
+static struct attribute *events_attr[] = {
+   event_attr_PERF_COUNT_HW_CPU_CYCLES.attr,
+   event_attr_PERF_COUNT_HW_INSTRUCTIONS.attr,
+   event_attr_PERF_COUNT_HW_CACHE_REFERENCES.attr,
+   event_attr_PERF_COUNT_HW_CACHE_MISSES.attr,
+   event_attr_PERF_COUNT_HW_BRANCH_INSTRUCTIONS.attr,
+   event_attr_PERF_COUNT_HW_BRANCH_MISSES.attr,
+   event_attr_PERF_COUNT_HW_BUS_CYCLES.attr,
+   event_attr_PERF_COUNT_HW_STALLED_CYCLES_FRONTEND.attr,
+   event_attr_PERF_COUNT_HW_STALLED_CYCLES_BACKEND.attr,
+   event_attr_PERF_COUNT_HW_REF_CPU_CYCLES.attr,
+   NULL,
+};
+
+static struct attribute_group x86_pmu_events_group = {
+   .name = events,
+   .attrs = events_attr,
+};
+
 static const struct attribute_group *x86_pmu_attr_groups[] = {
x86_pmu_attr_group,
x86_pmu_format_group

[PATCH 3/6] perf, tool: Fix pmu object alias initialization

2012-07-09 Thread Jiri Olsa
The pmu_lookup should return pmus that do not expose the 'events'
group attribute in sysfs. Also it should fail when any other error
during 'events' lookup is hit (pmu_aliases fails).

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/pmu.c |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 67715a4..3c86022 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -161,7 +161,7 @@ static int pmu_aliases(char *name, struct list_head *head)
 %s/bus/event_source/devices/%s/events, sysfs, name);
 
if (stat(path, st)  0)
-   return -1;
+   return 0;/* no error if 'events' does not exist */
 
if (pmu_aliases_parse(path, head))
return -1;
@@ -237,6 +237,9 @@ static struct perf_pmu *pmu_lookup(char *name)
if (pmu_format(name, format))
return NULL;
 
+   if (pmu_aliases(name, aliases))
+   return NULL;
+
if (pmu_type(name, type))
return NULL;
 
@@ -244,8 +247,6 @@ static struct perf_pmu *pmu_lookup(char *name)
if (!pmu)
return NULL;
 
-   pmu_aliases(name, aliases);
-
INIT_LIST_HEAD(pmu-format);
INIT_LIST_HEAD(pmu-aliases);
list_splice(format, pmu-format);
-- 
1.7.10.4

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


[PATCH 6/6] perf, test: Add automated tests for pmu sysfs translated events

2012-07-09 Thread Jiri Olsa
Adding automated tests for all events found under PMU/events
directory. Tested events are in 'cpu/event=xxx/u' format,
where 'xxx' is substibuted by every event found.

The 'event=xxx' term is translated to the cpu specific term.
We only check that the event is created (not the real config
numbers) and that modifier is properly set.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/parse-events-test.c |   75 ++-
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/parse-events-test.c 
b/tools/perf/util/parse-events-test.c
index 1b997d2..a2aac11 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -13,6 +13,8 @@ do { \
} \
 } while (0)
 
+static int test_cnt;
+
 static int test__checkevent_tracepoint(struct perf_evlist *evlist)
 {
struct perf_evsel *evsel = list_entry(evlist-entries.next,
@@ -470,6 +472,23 @@ static int test__checkevent_pmu_name(struct perf_evlist 
*evlist)
return 0;
 }
 
+static int test__checkevent_pmu_events(struct perf_evlist *evlist)
+{
+   struct perf_evsel *evsel;
+
+   evsel = list_entry(evlist-entries.next, struct perf_evsel, node);
+   TEST_ASSERT_VAL(wrong number of entries, 1 == evlist-nr_entries);
+   TEST_ASSERT_VAL(wrong type, PERF_TYPE_RAW == evsel-attr.type);
+   TEST_ASSERT_VAL(wrong exclude_user,
+   !evsel-attr.exclude_user);
+   TEST_ASSERT_VAL(wrong exclude_kernel,
+   evsel-attr.exclude_kernel);
+   TEST_ASSERT_VAL(wrong exclude_hv, evsel-attr.exclude_hv);
+   TEST_ASSERT_VAL(wrong precise_ip, !evsel-attr.precise_ip);
+
+   return 0;
+}
+
 static int test__checkterms_simple(struct list_head *terms)
 {
struct parse_events__term *term;
@@ -666,6 +685,8 @@ static int test_event(struct test__event_st *e)
struct perf_evlist *evlist;
int ret;
 
+   pr_debug(running test %4d '%s'\n, test_cnt++, e-name);
+
evlist = perf_evlist__new(NULL, NULL);
if (evlist == NULL)
return -ENOMEM;
@@ -691,7 +712,6 @@ static int test_events(struct test__event_st *events, 
unsigned cnt)
for (i = 0; i  cnt; i++) {
struct test__event_st *e = events[i];
 
-   pr_debug(running test %d '%s'\n, i, e-name);
ret = test_event(e);
if (ret)
break;
@@ -732,7 +752,7 @@ static int test_terms(struct test__term *terms, unsigned 
cnt)
for (i = 0; i  cnt; i++) {
struct test__term *t = terms[i];
 
-   pr_debug(running test %d '%s'\n, i, t-str);
+   pr_debug(running test %4d '%s'\n, test_cnt, t-str);
ret = test_term(t);
if (ret)
break;
@@ -756,6 +776,51 @@ static int test_pmu(void)
return !ret;
 }
 
+static int test_pmu_events(void)
+{
+   struct stat st;
+   char path[PATH_MAX];
+   struct dirent *ent;
+   DIR *dir;
+   int ret;
+
+   snprintf(path, PATH_MAX, %s/bus/event_source/devices/cpu/events/,
+sysfs_find_mountpoint());
+
+   ret = stat(path, st);
+   if (ret) {
+   pr_debug(ommiting PMU cpu events tests\n);
+   return 0;
+   }
+
+   dir = opendir(path);
+   if (!dir) {
+   pr_debug(can't open pmu event dir);
+   return -1;
+   }
+
+   while (!ret  (ent = readdir(dir))) {
+#define MAX_NAME 100
+   struct test__event_st e;
+   char name[MAX_NAME];
+
+   if (!strcmp(ent-d_name, .) ||
+   !strcmp(ent-d_name, ..))
+   continue;
+
+   snprintf(name, MAX_NAME, cpu/event=%s/u, ent-d_name);
+
+   e.name  = name;
+   e.check = test__checkevent_pmu_events;
+
+   ret = test_event(e);
+#undef MAX_NAME
+   }
+
+   closedir(dir);
+   return ret;
+}
+
 int parse_events__test(void)
 {
int ret;
@@ -772,5 +837,11 @@ do {   
\
if (test_pmu())
TEST_EVENTS(test__events_pmu);
 
+   if (test_pmu()) {
+   ret = test_pmu_events();
+   if (ret)
+   return ret;
+   }
+
return test_terms(test__terms, ARRAY_SIZE(test__terms));
 }
-- 
1.7.10.4

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


[PATCH 5/6] perf, tool: Add support to specify hw event as pmu event term

2012-07-09 Thread Jiri Olsa
Adding a way to specify hw event as pmu event term like:
 'cpu/event=cpu-cycles/u'
 'cpu/event=instructions,.../u'

The 'event=cpu-cycles' term is replaced/translated by the hw events
term translation, which is exposed by sysfs 'events' group attribute.

Adding parser bits, the rest is already handled by the pmu alias code.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/parse-events.c |   13 +
 tools/perf/util/parse-events.h |2 ++
 tools/perf/util/parse-events.y |9 +
 3 files changed, 24 insertions(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 1aa721d..780bc45 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1045,6 +1045,19 @@ int parse_events__term_str(struct parse_events__term 
**term,
config, str, 0);
 }
 
+int parse_events__term_sym_hw(struct parse_events__term **term,
+ char *config, unsigned idx)
+{
+   struct event_symbol *sym;
+
+   BUG_ON(idx = PERF_COUNT_HW_MAX);
+   sym = event_symbols_hw[idx];
+
+   return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
+   PARSE_EVENTS__TERM_TYPE_USER, config,
+   (char *) sym-symbol, 0);
+}
+
 int parse_events__term_clone(struct parse_events__term **new,
 struct parse_events__term *term)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ee9c218..eaf2fd7 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -76,6 +76,8 @@ int parse_events__term_num(struct parse_events__term **_term,
   int type_term, char *config, long num);
 int parse_events__term_str(struct parse_events__term **_term,
   int type_term, char *config, char *str);
+int parse_events__term_sym_hw(struct parse_events__term **term,
+ char *config, unsigned idx);
 int parse_events__term_clone(struct parse_events__term **new,
 struct parse_events__term *term);
 void parse_events__free_terms(struct list_head *terms);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 2bc5fbf..9c74d8a 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -269,6 +269,15 @@ PE_NAME '=' PE_VALUE
$$ = term;
 }
 |
+PE_NAME '=' PE_VALUE_SYM_HW
+{
+   struct parse_events__term *term;
+   int config = $3  255;
+
+   ABORT_ON(parse_events__term_sym_hw(term, $1, config));
+   $$ = term;
+}
+|
 PE_NAME
 {
struct parse_events__term *term;
-- 
1.7.10.4

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


[PATCH 2/6] perf, x86: Filter out undefined events from sysfs events attribute

2012-07-09 Thread Jiri Olsa
The sysfs events group attribute currently shows all hw events,
including also undefined ones.

This patch filters out all undefined events out of the sysfs events
group attribute, so they don't even show up.

Suggested-by: Peter Zijlstra a.p.zijls...@chello.nl
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/kernel/cpu/perf_event.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 09452c2..9fb23dd 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1306,6 +1306,8 @@ static struct attribute_group x86_pmu_format_group = {
.attrs = NULL,
 };
 
+static void __init filter_events_group(void);
+
 static int __init init_hw_perf_events(void)
 {
struct x86_pmu_quirk *quirk;
@@ -1352,6 +1354,8 @@ static int __init init_hw_perf_events(void)
x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
x86_pmu_format_group.attrs = x86_pmu.format_attrs;
 
+   filter_events_group();
+
pr_info(... version:%d\n, x86_pmu.version);
pr_info(... bit width:  %d\n, x86_pmu.cntval_bits);
pr_info(... generic registers:  %d\n, x86_pmu.num_counters);
@@ -1718,6 +1722,26 @@ static const struct attribute_group 
*x86_pmu_attr_groups[] = {
NULL,
 };
 
+/*
+ * Remove all undefined events (x86_pmu.event_map(id) == 0)
+ * out of events_attr attributes.
+ */
+static void __init filter_events_group(void)
+{
+   int i, j;
+
+   for (i = 0; events_attr[i]; i++) {
+   if (x86_pmu.event_map(i))
+   continue;
+
+   for (j = i; events_attr[j]; j++)
+   events_attr[j] = events_attr[j + 1];
+
+   /* Check the shifted attr. */
+   i--;
+   }
+}
+
 static void x86_pmu_flush_branch_stack(void)
 {
if (x86_pmu.flush_branch_stack)
-- 
1.7.10.4

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


[PATCH 4/6] perf, tool: Properly free format data

2012-07-09 Thread Jiri Olsa
Format data are allocated during PMU lookup. If the lookup
fails in next steps, we don't release the format data.

This patch ensures that format data get released in case
there's failure during PMU load.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/pmu.c |   58 ++---
 1 file changed, 36 insertions(+), 22 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 3c86022..e8cff3d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -15,6 +15,14 @@ extern FILE *perf_pmu_in;
 
 static LIST_HEAD(pmus);
 
+static void pmu_format_release(struct list_head *head)
+{
+   struct perf_pmu__format *format, *h;
+
+   list_for_each_entry_safe(format, h, head, list)
+   free(format);
+}
+
 /*
  * Parse  process all the sysfs attributes located under
  * the directory specified in 'dir' parameter.
@@ -229,32 +237,38 @@ static struct perf_pmu *pmu_lookup(char *name)
LIST_HEAD(aliases);
__u32 type;
 
-   /*
-* The pmu data we store  need consists of the pmu
-* type value and format definitions. Load both right
-* now.
-*/
-   if (pmu_format(name, format))
-   return NULL;
+   do {
+   /*
+   * The pmu data we store  need consists of the pmu
+   * type value, format and events definitions. Load
+   * all of them right now.
+   */
+   if (pmu_format(name, format))
+   break;
 
-   if (pmu_aliases(name, aliases))
-   return NULL;
+   if (pmu_aliases(name, aliases))
+   break;
 
-   if (pmu_type(name, type))
-   return NULL;
+   if (pmu_type(name, type))
+   break;
 
-   pmu = zalloc(sizeof(*pmu));
-   if (!pmu)
-   return NULL;
+   pmu = zalloc(sizeof(*pmu));
+   if (!pmu)
+   break;
 
-   INIT_LIST_HEAD(pmu-format);
-   INIT_LIST_HEAD(pmu-aliases);
-   list_splice(format, pmu-format);
-   list_splice(aliases, pmu-aliases);
-   pmu-name = strdup(name);
-   pmu-type = type;
-   list_add_tail(pmu-list, pmus);
-   return pmu;
+   INIT_LIST_HEAD(pmu-format);
+   INIT_LIST_HEAD(pmu-aliases);
+   list_splice(format, pmu-format);
+   list_splice(aliases, pmu-aliases);
+   pmu-name = strdup(name);
+   pmu-type = type;
+   list_add_tail(pmu-list, pmus);
+   return pmu;
+
+   } while (0);
+
+   pmu_format_release(format);
+   return NULL;
 }
 
 static struct perf_pmu *pmu_find(char *name)
-- 
1.7.10.4

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


[PATCH 02/17] perf: Add ability to attach user level registers dump to sample

2012-07-22 Thread Jiri Olsa
Introducing PERF_SAMPLE_REGS_USER sample type bit to trigger
the dump of user level registers on sample. Registers we want
to dump are specified by sample_regs_user bitmask.

Only user level registers are dumped at the moment. Meaning the
register values of the user space context as it was before the
user entered the kernel for whatever reason (syscall, irq,
exception, or a PMI happening in userspace).

The layout of the sample_regs_user bitmap is described in
asm/perf_regs.h for archs that support register dump.

This is going to be useful to bring Dwarf CFI based stack
unwinding on top of samples.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 include/linux/perf_event.h |   20 --
 kernel/events/core.c   |   61 
 2 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 76c5c8b..57f209d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -130,8 +130,9 @@ enum perf_event_sample_format {
PERF_SAMPLE_STREAM_ID   = 1U  9,
PERF_SAMPLE_RAW = 1U  10,
PERF_SAMPLE_BRANCH_STACK= 1U  11,
+   PERF_SAMPLE_REGS_USER   = 1U  12,
 
-   PERF_SAMPLE_MAX = 1U  12, /* non-ABI */
+   PERF_SAMPLE_MAX = 1U  13, /* non-ABI */
 };
 
 /*
@@ -194,6 +195,7 @@ enum perf_event_read_format {
 #define PERF_ATTR_SIZE_VER064  /* sizeof first published struct */
 #define PERF_ATTR_SIZE_VER172  /* add: config2 */
 #define PERF_ATTR_SIZE_VER280  /* add: branch_sample_type */
+#define PERF_ATTR_SIZE_VER388  /* add: sample_regs_user */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
@@ -271,7 +273,13 @@ struct perf_event_attr {
__u64   bp_len;
__u64   config2; /* extension of config1 */
};
-   __u64   branch_sample_type; /* enum branch_sample_type */
+   __u64   branch_sample_type; /* enum perf_branch_sample_type */
+
+   /*
+* Defines set of user regs to dump on samples.
+* See asm/perf_regs.h for details.
+*/
+   __u64   sample_regs_user;
 };
 
 /*
@@ -548,6 +556,9 @@ enum perf_event_type {
 *char  data[size];} PERF_SAMPLE_RAW
 *
 *  { u64 from, to, flags } lbr[nr];}  PERF_SAMPLE_BRANCH_STACK
+*
+*  { u64   available;
+*u64   regs[weight(mask)]; }  
PERF_SAMPLE_REGS_USER
 * };
 */
PERF_RECORD_SAMPLE  = 9,
@@ -609,6 +620,7 @@ struct perf_guest_info_callbacks {
 #include linux/static_key.h
 #include linux/atomic.h
 #include linux/sysfs.h
+#include linux/perf_regs.h
 #include asm/local.h
 
 struct perf_callchain_entry {
@@ -1133,6 +1145,7 @@ struct perf_sample_data {
struct perf_callchain_entry *callchain;
struct perf_raw_record  *raw;
struct perf_branch_stack*br_stack;
+   struct pt_regs  *regs_user;
 };
 
 static inline void perf_sample_data_init(struct perf_sample_data *data,
@@ -1142,7 +1155,8 @@ static inline void perf_sample_data_init(struct 
perf_sample_data *data,
data-addr = addr;
data-raw  = NULL;
data-br_stack = NULL;
-   data-period= period;
+   data-period = period;
+   data-regs_user = NULL;
 }
 
 extern void perf_output_sample(struct perf_output_handle *handle,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f1cf0ed..e817e32 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3756,6 +3756,33 @@ int perf_unregister_guest_info_callbacks(struct 
perf_guest_info_callbacks *cbs)
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
 
+static void
+perf_output_sample_regs(struct perf_output_handle *handle,
+   struct pt_regs *regs, u64 mask)
+{
+   int bit;
+
+   for_each_set_bit(bit, (const unsigned long *) mask,
+sizeof(mask) * BITS_PER_BYTE) {
+   u64 val;
+
+   val = perf_reg_value(regs, bit);
+   perf_output_put(handle, val);
+   }
+}
+
+static struct pt_regs *perf_sample_regs_user(struct pt_regs *regs)
+{
+   if (!user_mode(regs)) {
+   if (current-mm)
+   regs = task_pt_regs(current);
+   else
+   regs = NULL;
+   }
+
+   return regs;
+}
+
 static void __perf_event_header__init_id(struct perf_event_header *header,
 struct perf_sample_data *data,
 struct perf_event *event)
@@ -4016,6 +4043,23 @@ void perf_output_sample(struct perf_output_handle 
*handle,
perf_output_put(handle

[PATCH 08/17] perf, tool: Adding PERF_ATTR_SIZE_VER2 to the header swap check

2012-07-22 Thread Jiri Olsa
Updating attr_file_abi_sizes array with PERF_ATTR_SIZE_VER2 version,
so we have the swap check complete.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/header.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 5a47aba..9678af6 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1814,6 +1814,7 @@ out_free:
 static const int attr_file_abi_sizes[] = {
[0] = PERF_ATTR_SIZE_VER0,
[1] = PERF_ATTR_SIZE_VER1,
+   [2] = PERF_ATTR_SIZE_VER2,
0,
 };
 
-- 
1.7.7.6

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


[PATCH 12/17] perf, tool: Add libunwind dependency for dwarf cfi unwinding

2012-07-22 Thread Jiri Olsa
Adding libunwind to be linked with perf if available. It's required
for the to get dwarf cfi unwinding support.

Also building perf with the dwarf call frame informations by default,
so that we can unwind callchains in perf itself.

Adding LIBUNWIND_DIR Makefile variable allowing user to specify
the directory with libunwind to be linked. This is used for
debug purposes.

Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/Makefile |   30 +-
 tools/perf/config/feature-tests.mak |   25 +
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 576db7e..d0c3291 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -38,6 +38,9 @@ include config/utilities.mak
 # Define NO_NEWT if you do not want TUI support.
 #
 # Define NO_DEMANGLE if you do not want C++ symbol demangling.
+#
+# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
+# backtrace post unwind.
 
 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
@@ -59,6 +62,7 @@ AR = $(CROSS_COMPILE)ar
 ifeq ($(ARCH),i386)
ARCH := x86
NO_PERF_REGS := 0
+   LIBUNWIND_LIBS = -lunwind -lunwind-x86
 endif
 ifeq ($(ARCH),x86_64)
ARCH := x86
@@ -72,6 +76,7 @@ ifeq ($(ARCH),x86_64)
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 
../../arch/x86/lib/memset_64.S
endif
NO_PERF_REGS := 0
+   LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
 endif
 
 # Treat warnings as errors unless directed not to
@@ -92,7 +97,7 @@ ifdef PARSER_DEBUG
PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
 endif
 
-CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 
$(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 
$(PARSER_DEBUG_CFLAGS)
+CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra 
-std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) 
$(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
 EXTLIBS = -lpthread -lrt -lelf -lm
 ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
-D_GNU_SOURCE
 ALL_LDFLAGS = $(LDFLAGS)
@@ -456,6 +461,21 @@ ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
 endif # Dwarf support
 endif # NO_DWARF
 
+ifndef NO_LIBUNWIND
+# for linking with debug library, run like:
+# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+ifdef LIBUNWIND_DIR
+   LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
+   LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+endif
+
+FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) 
$(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y)
+   msg := $(warning No libunwind found. Please install libunwind = 0.99);
+   NO_LIBUNWIND := 1
+endif # Libunwind support
+endif # NO_LIBUNWIND
+
 -include arch/$(ARCH)/Makefile
 
 ifneq ($(OUTPUT),)
@@ -487,6 +507,14 @@ else
 endif # PERF_HAVE_DWARF_REGS
 endif # NO_DWARF
 
+ifdef NO_LIBUNWIND
+   BASIC_CFLAGS += -DNO_LIBUNWIND_SUPPORT
+else
+   EXTLIBS += $(LIBUNWIND_LIBS)
+   BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
+   BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+endif
+
 ifdef NO_NEWT
BASIC_CFLAGS += -DNO_NEWT_SUPPORT
 else
diff --git a/tools/perf/config/feature-tests.mak 
b/tools/perf/config/feature-tests.mak
index 6c18785..2f1156a 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -154,3 +154,28 @@ int main(void)
return 0;
 }
 endef
+
+ifndef NO_LIBUNWIND
+define SOURCE_LIBUNWIND
+#include libunwind.h
+#include stdlib.h
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+  unw_word_t ip,
+  unw_dyn_info_t *di,
+  unw_proc_info_t *pi,
+  int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+int main(void)
+{
+   unw_addr_space_t addr_space;
+   addr_space = unw_create_addr_space(NULL, 0);
+   unw_init_remote(NULL, addr_space, NULL);
+   dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+   return 0;
+}
+endef
+endif
-- 
1.7.7.6

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


[PATCH 01/17] perf: Unified API to record selective sets of arch registers

2012-07-22 Thread Jiri Olsa
This brings a new API to help the selective dump of registers on
event sampling, and its implementation for x86 arch.

Added HAVE_PERF_REGS config option to determine if the architecture
provides perf registers ABI.

The information about desired registers will be passed in u64 mask.
It's up to the architecture to map the registers into the mask bits.

For the x86 arch implementation, both 32 and 64 bit registers
bits are defined within single enum to ensure 64 bit system can
provide register dump for compat task if needed in the future.

Signed-off-by: Jiri Olsa jo...@redhat.com
Original-patch-by: Frederic Weisbecker fweis...@gmail.com
---
 arch/Kconfig |6 +++
 arch/x86/Kconfig |1 +
 arch/x86/include/asm/perf_regs.h |   33 ++
 arch/x86/kernel/Makefile |2 +
 arch/x86/kernel/perf_regs.c  |   90 ++
 include/linux/perf_regs.h|   19 
 6 files changed, 151 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/include/asm/perf_regs.h
 create mode 100644 arch/x86/kernel/perf_regs.c
 create mode 100644 include/linux/perf_regs.h

diff --git a/arch/Kconfig b/arch/Kconfig
index 8c3d957..32f4873 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -222,6 +222,12 @@ config HAVE_PERF_EVENTS_NMI
  subsystem.  Also has support for calculating CPU cycle events
  to determine how many clock cycles in a given period.
 
+config HAVE_PERF_REGS
+   bool
+   help
+ Support selective register dumps for perf events. This includes
+ bit-mapping of each registers and a unique architecture id.
+
 config HAVE_ARCH_JUMP_LABEL
bool
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 94de2c5..acebbd6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -60,6 +60,7 @@ config X86
select HAVE_MIXED_BREAKPOINTS_REGS
select PERF_EVENTS
select HAVE_PERF_EVENTS_NMI
+   select HAVE_PERF_REGS
select ANON_INODES
select HAVE_ALIGNED_STRUCT_PAGE if SLUB  !M386
select HAVE_CMPXCHG_LOCAL if !M386
diff --git a/arch/x86/include/asm/perf_regs.h b/arch/x86/include/asm/perf_regs.h
new file mode 100644
index 000..3f2207b
--- /dev/null
+++ b/arch/x86/include/asm/perf_regs.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_X86_PERF_REGS_H
+#define _ASM_X86_PERF_REGS_H
+
+enum perf_event_x86_regs {
+   PERF_REG_X86_AX,
+   PERF_REG_X86_BX,
+   PERF_REG_X86_CX,
+   PERF_REG_X86_DX,
+   PERF_REG_X86_SI,
+   PERF_REG_X86_DI,
+   PERF_REG_X86_BP,
+   PERF_REG_X86_SP,
+   PERF_REG_X86_IP,
+   PERF_REG_X86_FLAGS,
+   PERF_REG_X86_CS,
+   PERF_REG_X86_SS,
+   PERF_REG_X86_DS,
+   PERF_REG_X86_ES,
+   PERF_REG_X86_FS,
+   PERF_REG_X86_GS,
+   PERF_REG_X86_R8,
+   PERF_REG_X86_R9,
+   PERF_REG_X86_R10,
+   PERF_REG_X86_R11,
+   PERF_REG_X86_R12,
+   PERF_REG_X86_R13,
+   PERF_REG_X86_R14,
+   PERF_REG_X86_R15,
+
+   PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
+   PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
+};
+#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8215e56..8d7a619 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -100,6 +100,8 @@ obj-$(CONFIG_SWIOTLB)   += pci-swiotlb.o
 obj-$(CONFIG_OF)   += devicetree.o
 obj-$(CONFIG_UPROBES)  += uprobes.o
 
+obj-$(CONFIG_PERF_EVENTS)  += perf_regs.o
+
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
new file mode 100644
index 000..c00c92a
--- /dev/null
+++ b/arch/x86/kernel/perf_regs.c
@@ -0,0 +1,90 @@
+
+#include linux/kernel.h
+#include linux/bug.h
+#include linux/stddef.h
+#include asm/perf_regs.h
+#include asm/ptrace.h
+
+#ifdef CONFIG_X86_32
+#define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
+#else
+#define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
+#endif
+
+#define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
+
+static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
+   PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
+   PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
+   PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
+   PT_REGS_OFFSET(PERF_REG_X86_DX, dx),
+   PT_REGS_OFFSET(PERF_REG_X86_SI, si),
+   PT_REGS_OFFSET(PERF_REG_X86_DI, di),
+   PT_REGS_OFFSET(PERF_REG_X86_BP, bp),
+   PT_REGS_OFFSET(PERF_REG_X86_SP, sp),
+   PT_REGS_OFFSET(PERF_REG_X86_IP, ip),
+   PT_REGS_OFFSET(PERF_REG_X86_FLAGS, flags),
+   PT_REGS_OFFSET(PERF_REG_X86_CS, cs),
+   PT_REGS_OFFSET(PERF_REG_X86_SS, ss),
+#ifdef CONFIG_X86_32
+   PT_REGS_OFFSET(PERF_REG_X86_DS, ds),
+   PT_REGS_OFFSET(PERF_REG_X86_ES, es),
+   PT_REGS_OFFSET(PERF_REG_X86_FS, fs),
+   PT_REGS_OFFSET(PERF_REG_X86_GS, gs),
+#else
+   /*
+* The pt_regs struct does not store

[PATCH 06/17] perf: Add ability to attach user stack dump to sample

2012-07-22 Thread Jiri Olsa
Introducing PERF_SAMPLE_STACK_USER sample type bit to trigger
the dump of the user level stack on sample. The size of the
dump is specified by sample_stack_user value.

Being able to dump parts of the user stack, starting from the
stack pointer, will be useful to make a post mortem dwarf CFI
based stack unwinding.

Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 include/linux/perf_event.h |   18 ++-
 kernel/events/core.c   |  121 +++-
 2 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index a4c53da..b4663b3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -131,8 +131,9 @@ enum perf_event_sample_format {
PERF_SAMPLE_RAW = 1U  10,
PERF_SAMPLE_BRANCH_STACK= 1U  11,
PERF_SAMPLE_REGS_USER   = 1U  12,
+   PERF_SAMPLE_STACK_USER  = 1U  13,
 
-   PERF_SAMPLE_MAX = 1U  13, /* non-ABI */
+   PERF_SAMPLE_MAX = 1U  14, /* non-ABI */
 };
 
 /*
@@ -196,6 +197,7 @@ enum perf_event_read_format {
 #define PERF_ATTR_SIZE_VER172  /* add: config2 */
 #define PERF_ATTR_SIZE_VER280  /* add: branch_sample_type */
 #define PERF_ATTR_SIZE_VER388  /* add: sample_regs_user */
+#define PERF_ATTR_SIZE_VER496  /* add: sample_stack_user */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
@@ -280,6 +282,14 @@ struct perf_event_attr {
 * See asm/perf_regs.h for details.
 */
__u64   sample_regs_user;
+
+   /*
+* Defines size of the user stack to dump on samples.
+*/
+   __u32   sample_stack_user;
+
+   /* Align to u64. */
+   __u32   __reserved_2;
 };
 
 /*
@@ -559,6 +569,10 @@ enum perf_event_type {
 *
 *  { u64   available;
 *u64   regs[weight(mask)]; }  
PERF_SAMPLE_REGS_USER
+*
+*  { u64   size;
+*char  data[size];
+*u64   dyn_size; }  PERF_SAMPLE_STACK_USER
 * };
 */
PERF_RECORD_SAMPLE  = 9,
@@ -1146,6 +1160,7 @@ struct perf_sample_data {
struct perf_raw_record  *raw;
struct perf_branch_stack*br_stack;
struct pt_regs  *regs_user;
+   u64 stack_user_size;
 };
 
 static inline void perf_sample_data_init(struct perf_sample_data *data,
@@ -1157,6 +1172,7 @@ static inline void perf_sample_data_init(struct 
perf_sample_data *data,
data-br_stack = NULL;
data-period = period;
data-regs_user = NULL;
+   data-stack_user_size = 0;
 }
 
 extern void perf_output_sample(struct perf_output_handle *handle,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index e817e32..8a9cf80 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3771,6 +3771,45 @@ perf_output_sample_regs(struct perf_output_handle 
*handle,
}
 }
 
+static void
+perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
+ struct pt_regs *regs)
+{
+   /* Case of a kernel thread, nothing to dump */
+   if (!regs) {
+   u64 size = 0;
+   perf_output_put(handle, size);
+   } else {
+   unsigned long sp;
+   unsigned int rem;
+   u64 dyn_size;
+
+   /*
+* We dump:
+* static size
+*   - the size requested by user or the best one we can fit
+* in to the sample max size
+* data
+*   - user stack dump data
+* dynamic size
+*   - the actual dumped size
+*/
+
+   /* Static size. */
+   perf_output_put(handle, dump_size);
+
+   /* Data. */
+   sp = user_stack_pointer(regs);
+   rem = __output_copy_user(handle, (void *) sp, dump_size);
+   dyn_size = dump_size - rem;
+
+   perf_output_skip(handle, rem);
+
+   /* Dynamic size. */
+   perf_output_put(handle, dyn_size);
+   }
+}
+
 static struct pt_regs *perf_sample_regs_user(struct pt_regs *regs)
 {
if (!user_mode(regs)) {
@@ -4060,6 +4099,11 @@ void perf_output_sample(struct perf_output_handle 
*handle,
mask);
}
}
+
+   if (sample_type  PERF_SAMPLE_STACK_USER)
+   perf_output_sample_ustack(handle,
+ data-stack_user_size,
+ data-regs_user);
 }
 
 void perf_prepare_sample(struct perf_event_header *header

[PATCH 07/17] perf: Add attribute to filter out callchains

2012-07-22 Thread Jiri Olsa
From: Frederic Weisbecker fweis...@gmail.com

Introducing following bits to the the perf_event_attr struct:
  - exclude_callchain_kernel to filter out kernel callchain
from the sample dump
  - exclude_callchain_user to filter out user callchain
from the sample dump

We need to be able to disable standard user callchain dump
when we use the dwarf cfi callchain mode, because frame
pointer based user callchains are useless in this mode.

Implementing also exclude_callchain_kernel to have complete
set of options.

Signed-off-by: Frederic Weisbecker fweis...@gmail.com
[ Added kernel callchains filtering ]
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 include/linux/perf_event.h |5 -
 kernel/events/callchain.c  |   25 +++--
 kernel/events/core.c   |5 -
 kernel/events/internal.h   |3 ++-
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index b4663b3..91c2de2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -259,7 +259,10 @@ struct perf_event_attr {
exclude_host   :  1, /* don't count in host   */
exclude_guest  :  1, /* don't count in guest  */
 
-   __reserved_1   : 43;
+   exclude_callchain_kernel : 1, /* exclude kernel 
callchains */
+   exclude_callchain_user   : 1, /* exclude user 
callchains */
+
+   __reserved_1   : 41;
 
union {
__u32   wakeup_events;/* wakeup every n events */
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index 6581a04..905ffb2 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -153,12 +153,12 @@ put_callchain_entry(int rctx)
put_recursion_context(__get_cpu_var(callchain_recursion), rctx);
 }
 
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+   int kernel, int user)
 {
int rctx;
struct perf_callchain_entry *entry;
 
-
entry = get_callchain_entry(rctx);
if (rctx == -1)
return NULL;
@@ -168,18 +168,23 @@ struct perf_callchain_entry *perf_callchain(struct 
pt_regs *regs)
 
entry-nr = 0;
 
-   if (!user_mode(regs)) {
+   if (kernel  !user_mode(regs)) {
perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
perf_callchain_kernel(entry, regs);
-   if (current-mm)
-   regs = task_pt_regs(current);
-   else
-   regs = NULL;
}
 
-   if (regs) {
-   perf_callchain_store(entry, PERF_CONTEXT_USER);
-   perf_callchain_user(entry, regs);
+   if (user) {
+   if (!user_mode(regs)) {
+   if  (current-mm)
+   regs = task_pt_regs(current);
+   else
+   regs = NULL;
+   }
+
+   if (regs) {
+   perf_callchain_store(entry, PERF_CONTEXT_USER);
+   perf_callchain_user(entry, regs);
+   }
}
 
 exit_put:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8a9cf80..78f405e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4126,8 +4126,11 @@ void perf_prepare_sample(struct perf_event_header 
*header,
 
if (sample_type  PERF_SAMPLE_CALLCHAIN) {
int size = 1;
+   int kernel = !event-attr.exclude_callchain_kernel;
+   int user   = !event-attr.exclude_callchain_user;
 
-   data-callchain = perf_callchain(regs);
+   if (kernel || user)
+   data-callchain = perf_callchain(regs, kernel, user);
 
if (data-callchain)
size += data-callchain-nr;
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index be1ef29..abcc03d 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -125,7 +125,8 @@ DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
 DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user)
 
 /* Callchain handling */
-extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
+extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+  int kernel, int user);
 extern int get_callchain_buffers(void);
 extern void put_callchain_buffers(void);
 
-- 
1.7.7.6

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


[PATCH 11/17] perf, tool: Add interface to arch registers sets

2012-07-22 Thread Jiri Olsa
Adding header files to access unified API for arch registers.
  util/perf_regs.h - global perf_reg declarations
  arch/x86/include/perf_regs.h - x86 arch specific

Adding perf_reg_name function to obtain register name based
on the reg ID value, and PERF_REGS_MASK macro with mask
definition of all current arch registers (will be used in
unwind patches).

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile |   13 +-
 tools/perf/arch/x86/include/perf_regs.h |   80 +++
 tools/perf/util/perf_regs.h |   14 +
 3 files changed, 106 insertions(+), 1 deletions(-)
 create mode 100644 tools/perf/arch/x86/include/perf_regs.h
 create mode 100644 tools/perf/util/perf_regs.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 75d74e5..576db7e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -50,13 +50,15 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e 
s/sun4u/sparc64/ \
  -e s/s390x/s390/ -e s/parisc64/parisc/ \
  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
  -e s/sh[234].*/sh/ )
+NO_PERF_REGS := 1
 
 CC = $(CROSS_COMPILE)gcc
 AR = $(CROSS_COMPILE)ar
 
 # Additional ARCH settings for x86
 ifeq ($(ARCH),i386)
-ARCH := x86
+   ARCH := x86
+   NO_PERF_REGS := 0
 endif
 ifeq ($(ARCH),x86_64)
ARCH := x86
@@ -69,6 +71,7 @@ ifeq ($(ARCH),x86_64)
ARCH_CFLAGS := -DARCH_X86_64
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 
../../arch/x86/lib/memset_64.S
endif
+   NO_PERF_REGS := 0
 endif
 
 # Treat warnings as errors unless directed not to
@@ -319,6 +322,7 @@ LIB_H += $(ARCH_INCLUDE)
 LIB_H += util/cgroup.h
 LIB_H += $(TRACE_EVENT_DIR)event-parse.h
 LIB_H += util/target.h
+LIB_H += util/perf_regs.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -669,6 +673,13 @@ else
endif
 endif
 
+ifeq ($(NO_PERF_REGS),0)
+   ifeq ($(ARCH),x86)
+   LIB_H += arch/x86/include/perf_regs.h
+   endif
+else
+   BASIC_CFLAGS += -DNO_PERF_REGS
+endif
 
 ifdef NO_STRLCPY
BASIC_CFLAGS += -DNO_STRLCPY
diff --git a/tools/perf/arch/x86/include/perf_regs.h 
b/tools/perf/arch/x86/include/perf_regs.h
new file mode 100644
index 000..46fc9f1
--- /dev/null
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -0,0 +1,80 @@
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include stdlib.h
+#include ../../util/types.h
+#include ../../../../../arch/x86/include/asm/perf_regs.h
+
+#ifndef ARCH_X86_64
+#define PERF_REGS_MASK ((1ULL  PERF_REG_X86_32_MAX) - 1)
+#else
+#define REG_NOSUPPORT ((1ULL  PERF_REG_X86_DS) | \
+  (1ULL  PERF_REG_X86_ES) | \
+  (1ULL  PERF_REG_X86_FS) | \
+  (1ULL  PERF_REG_X86_GS))
+#define PERF_REGS_MASK (((1ULL  PERF_REG_X86_64_MAX) - 1)  ~REG_NOSUPPORT)
+#endif
+#define PERF_REG_IP PERF_REG_X86_IP
+#define PERF_REG_SP PERF_REG_X86_SP
+
+static inline const char *perf_reg_name(int id)
+{
+   switch (id) {
+   case PERF_REG_X86_AX:
+   return AX;
+   case PERF_REG_X86_BX:
+   return BX;
+   case PERF_REG_X86_CX:
+   return CX;
+   case PERF_REG_X86_DX:
+   return DX;
+   case PERF_REG_X86_SI:
+   return SI;
+   case PERF_REG_X86_DI:
+   return DI;
+   case PERF_REG_X86_BP:
+   return BP;
+   case PERF_REG_X86_SP:
+   return SP;
+   case PERF_REG_X86_IP:
+   return IP;
+   case PERF_REG_X86_FLAGS:
+   return FLAGS;
+   case PERF_REG_X86_CS:
+   return CS;
+   case PERF_REG_X86_SS:
+   return SS;
+   case PERF_REG_X86_DS:
+   return DS;
+   case PERF_REG_X86_ES:
+   return ES;
+   case PERF_REG_X86_FS:
+   return FS;
+   case PERF_REG_X86_GS:
+   return GS;
+#ifdef ARCH_X86_64
+   case PERF_REG_X86_R8:
+   return R8;
+   case PERF_REG_X86_R9:
+   return R9;
+   case PERF_REG_X86_R10:
+   return R10;
+   case PERF_REG_X86_R11:
+   return R11;
+   case PERF_REG_X86_R12:
+   return R12;
+   case PERF_REG_X86_R13:
+   return R13;
+   case PERF_REG_X86_R14:
+   return R14;
+   case PERF_REG_X86_R15:
+   return R15;
+#endif /* ARCH_X86_64 */
+   default:
+   return NULL;
+   }
+
+   return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
new file mode 100644
index 000..3efb79a
--- /dev/null
+++ b/tools/perf/util/perf_regs.h
@@ -0,0 +1,14 @@
+#ifndef __PERF_REGS_H
+#define __PERF_REGS_H
+
+#ifndef NO_PERF_REGS_DEFS
+#include perf_regs.h
+#else
+#define PERF_REGS_MASK 0

[PATCH 10/17] perf, tool: Add interface to read DSO image data

2012-07-22 Thread Jiri Olsa
Adding following interface for DSO object to allow
reading of DSO image data:

  dso__data_fd
- opens DSO and returns file descriptor
  Binary types are used to locate/open DSO in following order:
DSO_BINARY_TYPE__BUILD_ID_CACHE
DSO_BINARY_TYPE__SYSTEM_PATH_DSO
  In other word we first try to open DSO build-id path,
  and if that fails we try to open DSO system path.

  dso__data_read_offset
- reads DSO data from specified offset

  dso__data_read_addr
- reads DSO data from specified address/map.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/symbol.c |  109 ++
 tools/perf/util/symbol.h |8 +++
 2 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 79fc779..ff4d603 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -65,6 +65,14 @@ static enum dso_binary_type binary_type_symtab[] = {
 
 #define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
 
+static enum dso_binary_type binary_type_data[] = {
+   DSO_BINARY_TYPE__BUILD_ID_CACHE,
+   DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+   DSO_BINARY_TYPE__NOT_FOUND,
+};
+
+#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data)
+
 int dso__name_len(const struct dso *dso)
 {
if (!dso)
@@ -336,6 +344,7 @@ struct dso *dso__new(const char *name)
for (i = 0; i  MAP__NR_TYPES; ++i)
dso-symbols[i] = dso-symbol_names[i] = RB_ROOT;
dso-symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
+   dso-data_type   = DSO_BINARY_TYPE__NOT_FOUND;
dso-loaded = 0;
dso-sorted_by_name = 0;
dso-has_build_id = 0;
@@ -2946,3 +2955,103 @@ struct map *dso__new_map(const char *name)
 
return map;
 }
+
+static int open_dso(struct dso *dso, struct machine *machine)
+{
+   char *root_dir = (char *) ;
+   char *name;
+   int fd;
+
+   name = malloc(PATH_MAX);
+   if (!name)
+   return -ENOMEM;
+
+   if (machine)
+   root_dir = machine-root_dir;
+
+   if (dso__binary_type_file(dso, dso-data_type,
+ root_dir, name, PATH_MAX)) {
+   free(name);
+   return -EINVAL;
+   }
+
+   fd = open(name, O_RDONLY);
+   free(name);
+   return fd;
+}
+
+int dso__data_fd(struct dso *dso, struct machine *machine)
+{
+   int i = 0;
+
+   if (dso-data_type != DSO_BINARY_TYPE__NOT_FOUND)
+   return open_dso(dso, machine);
+
+   do {
+   int fd;
+
+   dso-data_type = binary_type_data[i++];
+
+   fd = open_dso(dso, machine);
+   if (fd = 0)
+   return fd;
+
+   } while (dso-data_type != DSO_BINARY_TYPE__NOT_FOUND);
+
+   return -EINVAL;
+}
+
+static ssize_t dso_cache_read(struct dso *dso __used, u64 offset __used,
+ u8 *data __used, ssize_t size __used)
+{
+   return -EINVAL;
+}
+
+static int dso_cache_add(struct dso *dso __used, u64 offset __used,
+u8 *data __used, ssize_t size __used)
+{
+   return 0;
+}
+
+static ssize_t read_dso_data(struct dso *dso, struct machine *machine,
+u64 offset, u8 *data, ssize_t size)
+{
+   ssize_t rsize = -1;
+   int fd;
+
+   fd = dso__data_fd(dso, machine);
+   if (fd  0)
+   return -1;
+
+   do {
+   if (-1 == lseek(fd, offset, SEEK_SET))
+   break;
+
+   rsize = read(fd, data, size);
+   if (-1 == rsize)
+   break;
+
+   if (dso_cache_add(dso, offset, data, size))
+   pr_err(Failed to add data int dso cache.);
+
+   } while (0);
+
+   close(fd);
+   return rsize;
+}
+
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+   if (dso_cache_read(dso, offset, data, size))
+   return read_dso_data(dso, machine, offset, data, size);
+   return 0;
+}
+
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+   struct machine *machine, u64 addr,
+   u8 *data, ssize_t size)
+{
+   u64 offset = map-map_ip(map, addr);
+   return dso__data_read_offset(dso, machine, offset, data, size);
+}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index dc474f0..9b9ea00 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -189,6 +189,7 @@ struct dso {
enum dso_kernel_typekernel;
enum dso_swap_type  needs_swap;
enum dso_binary_typesymtab_type;
+   enum dso_binary_typedata_type;
u8   adjust_symbols:1;
u8   has_build_id:1;
u8   hit:1

[PATCH 14/17] perf, tool: Support for dwarf cfi unwinding on post processing

2012-07-22 Thread Jiri Olsa
This brings the support for dwarf cfi unwinding on perf post
processing. Call frame informations are retrieved and then passed
to libunwind that requests memory and register content from the
applications.

Adding unwind object to handle the user stack backtrace based
on the user register values and user stack dump.

The unwind object access the libunwind via remote interface
and provides to it all the necessary data to unwind the stack.

The unwind interface provides following function:
unwind__get_entries

And callback (specified in above function) to retrieve
the backtrace entries:
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry,
 void *arg);

Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/Makefile|2 +
 tools/perf/arch/x86/Makefile   |3 +
 tools/perf/arch/x86/util/unwind.c  |  111 
 tools/perf/builtin-report.c|   24 +-
 tools/perf/builtin-script.c|   16 +-
 tools/perf/builtin-top.c   |5 +-
 tools/perf/util/include/linux/compiler.h   |1 +
 tools/perf/util/map.h  |7 +-
 .../perf/util/scripting-engines/trace-event-perl.c |3 +-
 .../util/scripting-engines/trace-event-python.c|3 +-
 tools/perf/util/session.c  |   61 ++-
 tools/perf/util/session.h  |3 +-
 tools/perf/util/trace-event-scripting.c|3 +-
 tools/perf/util/trace-event.h  |5 +-
 tools/perf/util/unwind.c   |  567 
 tools/perf/util/unwind.h   |   34 ++
 16 files changed, 811 insertions(+), 37 deletions(-)
 create mode 100644 tools/perf/arch/x86/util/unwind.c
 create mode 100644 tools/perf/util/unwind.c
 create mode 100644 tools/perf/util/unwind.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index d0c3291..c18c790 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -328,6 +328,7 @@ LIB_H += util/cgroup.h
 LIB_H += $(TRACE_EVENT_DIR)event-parse.h
 LIB_H += util/target.h
 LIB_H += util/perf_regs.h
+LIB_H += util/unwind.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -513,6 +514,7 @@ else
EXTLIBS += $(LIBUNWIND_LIBS)
BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+   LIB_OBJS += $(OUTPUT)util/unwind.o
 endif
 
 ifdef NO_NEWT
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 744e629..815841c 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -2,4 +2,7 @@ ifndef NO_DWARF
 PERF_HAVE_DWARF_REGS := 1
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
 endif
+ifndef NO_LIBUNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
+endif
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
diff --git a/tools/perf/arch/x86/util/unwind.c 
b/tools/perf/arch/x86/util/unwind.c
new file mode 100644
index 000..78d956e
--- /dev/null
+++ b/tools/perf/arch/x86/util/unwind.c
@@ -0,0 +1,111 @@
+
+#include errno.h
+#include libunwind.h
+#include perf_regs.h
+#include ../../util/unwind.h
+
+#ifdef ARCH_X86_64
+int unwind__arch_reg_id(int regnum)
+{
+   int id;
+
+   switch (regnum) {
+   case UNW_X86_64_RAX:
+   id = PERF_REG_X86_AX;
+   break;
+   case UNW_X86_64_RDX:
+   id = PERF_REG_X86_DX;
+   break;
+   case UNW_X86_64_RCX:
+   id = PERF_REG_X86_CX;
+   break;
+   case UNW_X86_64_RBX:
+   id = PERF_REG_X86_BX;
+   break;
+   case UNW_X86_64_RSI:
+   id = PERF_REG_X86_SI;
+   break;
+   case UNW_X86_64_RDI:
+   id = PERF_REG_X86_DI;
+   break;
+   case UNW_X86_64_RBP:
+   id = PERF_REG_X86_BP;
+   break;
+   case UNW_X86_64_RSP:
+   id = PERF_REG_X86_SP;
+   break;
+   case UNW_X86_64_R8:
+   id = PERF_REG_X86_R8;
+   break;
+   case UNW_X86_64_R9:
+   id = PERF_REG_X86_R9;
+   break;
+   case UNW_X86_64_R10:
+   id = PERF_REG_X86_R10;
+   break;
+   case UNW_X86_64_R11:
+   id = PERF_REG_X86_R11;
+   break;
+   case UNW_X86_64_R12:
+   id = PERF_REG_X86_R12;
+   break;
+   case UNW_X86_64_R13:
+   id = PERF_REG_X86_R13;
+   break;
+   case UNW_X86_64_R14:
+   id = PERF_REG_X86_R14;
+   break;
+   case UNW_X86_64_R15:
+   id = PERF_REG_X86_R15;
+   break;
+   case UNW_X86_64_RIP:
+   id = PERF_REG_X86_IP

[PATCH 15/17] perf, tool: Support for dwarf mode callchain on perf record

2012-07-22 Thread Jiri Olsa
This patch enables perf to use the dwarf unwind code.

It extends the perf record '-g' option with following arguments:
  'fp'   - provides framepointer based user
   stack backtrace
  'dwarf[,size]' - provides dwarf (libunwind) based user stack
   backtrace. The size specifies the size of the
   user stack dump. If omitted it is 8192 by default.

If libunwind is found during the perf build, then the 'dwarf'
argument becomes available for record command. The 'fp' stays as
default option in any case.

Examples: (perf compiled with libunwind)

   perf record -g dwarf ls
  - provides dwarf unwind with 8192 as stack dump size

   perf record -g dwarf,4096 ls
  - provides dwarf unwind with 4096 as stack dump size

   perf record -g -- ls
   perf record -g fp ls
  - provides frame pointer unwind

Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/builtin-record.c |  108 ++-
 tools/perf/perf.h   |9 +++-
 tools/perf/util/evsel.c |   13 +-
 3 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f5a6452..fff130b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,6 +31,15 @@
 #include sched.h
 #include sys/mman.h
 
+#define CALLCHAIN_HELP do call-graph (stack chain/backtrace) recording: 
+
+#ifdef NO_LIBUNWIND_SUPPORT
+static char callchain_help[] = CALLCHAIN_HELP [fp];
+#else
+static unsigned long default_stack_dump_size = 8192;
+static char callchain_help[] = CALLCHAIN_HELP [fp] dwarf;
+#endif
+
 enum write_mode_t {
WRITE_FORCE,
WRITE_APPEND
@@ -732,6 +741,100 @@ error:
return ret;
 }
 
+#ifndef NO_LIBUNWIND_SUPPORT
+static int get_stack_size(char *str, unsigned long *_size)
+{
+   char *endptr;
+   unsigned long size;
+   unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
+
+   size = strtoul(str, endptr, 0);
+
+   do {
+   if (*endptr)
+   break;
+
+   size = round_up(size, sizeof(u64));
+   if (!size || size  max_size)
+   break;
+
+   *_size = size;
+   return 0;
+
+   } while (0);
+
+   pr_err(callchain: Incorrect stack dump size (max %ld): %s\n,
+  max_size, str);
+   return -1;
+}
+#endif /* !NO_LIBUNWIND_SUPPORT */
+
+static int
+parse_callchain_opt(const struct option *opt __used, const char *arg,
+   int unset)
+{
+   struct perf_record *rec = (struct perf_record *)opt-value;
+   char *tok, *name, *saveptr = NULL;
+   char buf[20];
+   int ret = -1;
+
+   /* --no-call-graph */
+   if (unset)
+   return 0;
+
+   /* We specified default option if none is provided. */
+   BUG_ON(!arg);
+
+   /* We need buffer that we know we can write to. */
+   snprintf(buf, 20, %s, arg);
+
+   tok = strtok_r((char *)buf, ,, saveptr);
+   name = tok ? : (char *)buf;
+
+   do {
+   /* Framepointer style */
+   if (!strncmp(name, fp, sizeof(fp))) {
+   if (!strtok_r(NULL, ,, saveptr)) {
+   rec-opts.call_graph = CALLCHAIN_FP;
+   ret = 0;
+   } else
+   pr_err(callchain: No more arguments 
+  needed for -g fp\n);
+   break;
+
+#ifndef NO_LIBUNWIND_SUPPORT
+   /* Dwarf style */
+   } else if (!strncmp(name, dwarf, sizeof(dwarf))) {
+   ret = 0;
+   rec-opts.call_graph = CALLCHAIN_DWARF;
+   rec-opts.stack_dump_size = default_stack_dump_size;
+
+   tok = strtok_r(NULL, ,, saveptr);
+   if (tok) {
+   unsigned long size = 0;
+
+   ret = get_stack_size(tok, size);
+   rec-opts.stack_dump_size = size;
+   }
+
+   if (!ret)
+   pr_debug(callchain: stack dump size %d\n,
+rec-opts.stack_dump_size);
+#endif /* !NO_LIBUNWIND_SUPPORT */
+   } else {
+   pr_err(callchain: Unknown -g option 
+  value: %s\n, name);
+   break;
+   }
+
+   } while (0);
+
+   if (!ret)
+   pr_debug(callchain: type %d\n, rec-opts.call_graph);
+
+   return ret;
+}
+
 static const char * const record_usage[] = {
perf record [options] [command],
perf record [options] -- command [options],
@@ -803,8 +906,9 @@ const struct option record_options[] = {
 number

[PATCH 17/17] perf, tool: Add dso data caching tests

2012-07-22 Thread Jiri Olsa
Adding automated test for DSO data reading. Testing raw/cached
reads from different file/cache locations.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/Makefile |1 +
 tools/perf/builtin-test.c   |4 +
 tools/perf/util/dso-test-data.c |  154 +++
 tools/perf/util/symbol.h|1 +
 4 files changed, 160 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/util/dso-test-data.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index c18c790..1f550fa 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -364,6 +364,7 @@ LIB_OBJS += $(OUTPUT)util/usage.o
 LIB_OBJS += $(OUTPUT)util/wrapper.o
 LIB_OBJS += $(OUTPUT)util/sigchain.o
 LIB_OBJS += $(OUTPUT)util/symbol.o
+LIB_OBJS += $(OUTPUT)util/dso-test-data.o
 LIB_OBJS += $(OUTPUT)util/color.o
 LIB_OBJS += $(OUTPUT)util/pager.o
 LIB_OBJS += $(OUTPUT)util/header.o
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 5d59398..000efb0 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1142,6 +1142,10 @@ static struct test {
.func = test__perf_pmu,
},
{
+   .desc = Test dso data interface,
+   .func = dso__test_data,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/util/dso-test-data.c b/tools/perf/util/dso-test-data.c
new file mode 100644
index 000..ec62977
--- /dev/null
+++ b/tools/perf/util/dso-test-data.c
@@ -0,0 +1,154 @@
+
+#include stdlib.h
+#include sys/types.h
+#include sys/stat.h
+#include fcntl.h
+#include string.h
+
+#include symbol.h
+
+#define TEST_ASSERT_VAL(text, cond) \
+do { \
+   if (!(cond)) { \
+   pr_debug(FAILED %s:%d %s\n, __FILE__, __LINE__, text); \
+   return -1; \
+   } \
+} while (0)
+
+static char *test_file(int size)
+{
+   static char buf_templ[] = /tmp/test-XX;
+   char *templ = buf_templ;
+   int fd, i;
+   unsigned char *buf;
+
+   fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC);
+
+   buf = malloc(size);
+   if (!buf) {
+   close(fd);
+   return NULL;
+   }
+
+   for (i = 0; i  size; i++)
+   buf[i] = (unsigned char) ((int) i % 10);
+
+   if (size != write(fd, buf, size))
+   templ = NULL;
+
+   close(fd);
+   return templ;
+}
+
+#define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20)
+
+struct test_data__offset {
+   off_t offset;
+   u8 data[10];
+   int size;
+};
+
+struct test_data__offset offsets[] = {
+   /* Fill first cache page. */
+   {
+   .offset = 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Read first cache page. */
+   {
+   .offset = 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Fill cache boundary pages. */
+   {
+   .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Read cache boundary pages. */
+   {
+   .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Fill final cache page. */
+   {
+   .offset = TEST_FILE_SIZE - 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Read final cache page. */
+   {
+   .offset = TEST_FILE_SIZE - 10,
+   .data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+   .size   = 10,
+   },
+   /* Read final cache page. */
+   {
+   .offset = TEST_FILE_SIZE - 3,
+   .data   = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 },
+   .size   = 3,
+   },
+};
+
+#define OFFSETS_CNT (sizeof(offsets) / sizeof(struct test_data__offset))
+
+int dso__test_data(void)
+{
+   struct machine machine;
+   struct dso *dso;
+   char *file = test_file(TEST_FILE_SIZE);
+   int i;
+
+   TEST_ASSERT_VAL(No test file, file);
+
+   memset(machine, 0, sizeof(machine));
+
+   dso = dso__new((const char *)file);
+
+   /* Basic 10 bytes tests. */
+   for (i = 0; i  (int) OFFSETS_CNT; i++) {
+   struct test_data__offset *data = offsets[i];
+   ssize_t size;
+   u8 buf[10];
+
+   memset(buf, 0, 10);
+   size = dso__data_read_offset(dso, machine, data-offset,
+buf, 10);
+
+   TEST_ASSERT_VAL(Wrong size, size == data-size);
+   TEST_ASSERT_VAL(Wrong data, !memcmp(buf, data-data, 10));
+   }
+
+   /* Read cross multiple cache pages. */
+   {
+   ssize_t size;
+   int c

[PATCH 16/17] perf, tool: Add dso data caching

2012-07-22 Thread Jiri Olsa
Adding dso data caching so we don't need to open/read/close,
each time we want dso data.

The DSO data caching affects following functions:
  dso__data_read_offset
  dso__data_read_addr

Each DSO read tries to find the data (based on offset) inside
the cache. If it's not present it fills the cache from file,
and returns the data. If it is present, data are returned
with no file read.

Each data read is cached by reading cache page sized/aligned
amount of DSO data. The cache page size is hardcoded to 4096.
The cache is using RB tree with file offset as a sort key.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/util/symbol.c |  154 --
 tools/perf/util/symbol.h |   11 +++
 2 files changed, 147 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ff4d603..d60490f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -29,6 +29,7 @@
 #define NT_GNU_BUILD_ID 3
 #endif
 
+static void dso_cache__free(struct rb_root *root);
 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
 static int elf_read_build_id(Elf *elf, void *bf, size_t size);
 static void dsos__add(struct list_head *head, struct dso *dso);
@@ -343,6 +344,7 @@ struct dso *dso__new(const char *name)
dso__set_short_name(dso, dso-name);
for (i = 0; i  MAP__NR_TYPES; ++i)
dso-symbols[i] = dso-symbol_names[i] = RB_ROOT;
+   dso-cache = RB_ROOT;
dso-symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
dso-data_type   = DSO_BINARY_TYPE__NOT_FOUND;
dso-loaded = 0;
@@ -378,6 +380,7 @@ void dso__delete(struct dso *dso)
free((char *)dso-short_name);
if (dso-lname_alloc)
free(dso-long_name);
+   dso_cache__free(dso-cache);
free(dso);
 }
 
@@ -3001,22 +3004,87 @@ int dso__data_fd(struct dso *dso, struct machine 
*machine)
return -EINVAL;
 }
 
-static ssize_t dso_cache_read(struct dso *dso __used, u64 offset __used,
- u8 *data __used, ssize_t size __used)
+static void
+dso_cache__free(struct rb_root *root)
 {
-   return -EINVAL;
+   struct rb_node *next = rb_first(root);
+
+   while (next) {
+   struct dso_cache *cache;
+
+   cache = rb_entry(next, struct dso_cache, rb_node);
+   next = rb_next(cache-rb_node);
+   rb_erase(cache-rb_node, root);
+   free(cache);
+   }
 }
 
-static int dso_cache_add(struct dso *dso __used, u64 offset __used,
-u8 *data __used, ssize_t size __used)
+static struct dso_cache*
+dso_cache__find(struct rb_root *root, u64 offset)
 {
-   return 0;
+   struct rb_node **p = root-rb_node;
+   struct rb_node *parent = NULL;
+   struct dso_cache *cache;
+
+   while (*p != NULL) {
+   u64 end;
+
+   parent = *p;
+   cache = rb_entry(parent, struct dso_cache, rb_node);
+   end = cache-offset + DSO__DATA_CACHE_SIZE;
+
+   if (offset  cache-offset)
+   p = (*p)-rb_left;
+   else if (offset = end)
+   p = (*p)-rb_right;
+   else
+   return cache;
+   }
+   return NULL;
+}
+
+static void
+dso_cache__insert(struct rb_root *root, struct dso_cache *new)
+{
+   struct rb_node **p = root-rb_node;
+   struct rb_node *parent = NULL;
+   struct dso_cache *cache;
+   u64 offset = new-offset;
+
+   while (*p != NULL) {
+   u64 end;
+
+   parent = *p;
+   cache = rb_entry(parent, struct dso_cache, rb_node);
+   end = cache-offset + DSO__DATA_CACHE_SIZE;
+
+   if (offset  cache-offset)
+   p = (*p)-rb_left;
+   else if (offset = end)
+   p = (*p)-rb_right;
+   }
+
+   rb_link_node(new-rb_node, parent, p);
+   rb_insert_color(new-rb_node, root);
+}
+
+static ssize_t
+dso_cache__memcpy(struct dso_cache *cache, u64 offset,
+ u8 *data, u64 size)
+{
+   u64 cache_offset = offset - cache-offset;
+   u64 cache_size   = min(cache-size - cache_offset, size);
+
+   memcpy(data, cache-data + cache_offset, cache_size);
+   return cache_size;
 }
 
-static ssize_t read_dso_data(struct dso *dso, struct machine *machine,
-u64 offset, u8 *data, ssize_t size)
+static ssize_t
+dso_cache__read(struct dso *dso, struct machine *machine,
+u64 offset, u8 *data, ssize_t size)
 {
-   ssize_t rsize = -1;
+   struct dso_cache *cache;
+   ssize_t ret;
int fd;
 
fd = dso__data_fd(dso, machine);
@@ -3024,28 +3092,78 @@ static ssize_t read_dso_data(struct dso *dso, struct 
machine *machine,
return -1;
 
do {
-   if (-1 == lseek(fd

[PATCH 13/17] perf, tool: Support user regs and stack in sample parsing

2012-07-22 Thread Jiri Olsa
Adding following info to be parsed out of the event sample:
 - user register set
 - user stack dump

Both are global and specific to all events within the session.
This info will be used in the unwind patches coming in shortly.

Adding simple output printout (report -D) for both register and
stack dumps.

Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 tools/perf/builtin-test.c |4 ++--
 tools/perf/util/event.h   |   16 +++-
 tools/perf/util/evlist.c  |8 
 tools/perf/util/evlist.h  |1 +
 tools/perf/util/evsel.c   |   30 +-
 tools/perf/util/header.c  |2 ++
 tools/perf/util/python.c  |3 ++-
 tools/perf/util/session.c |   36 
 tools/perf/util/session.h |8 ++--
 9 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 5ce3030..5d59398 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -564,7 +564,7 @@ static int test__basic_mmap(void)
}
 
err = perf_event__parse_sample(event, attr.sample_type, 
sample_size,
-  false, sample, false);
+  false, 0, sample, false);
if (err) {
pr_err(Can't parse sample, err = %d\n, err);
goto out_munmap;
@@ -790,7 +790,7 @@ static int test__PERF_RECORD(void)
 
err = perf_event__parse_sample(event, 
sample_type,
   sample_size, 
true,
-  sample, false);
+  0, sample, 
false);
if (err  0) {
if (verbose)
perf_event__fprintf(event, 
stderr);
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1b19728..ed978eb 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -69,6 +69,16 @@ struct sample_event {
u64 array[];
 };
 
+struct regs_dump {
+   u64 *regs;
+};
+
+struct stack_dump {
+   u16 offset;
+   u64 size;
+   char *data;
+};
+
 struct perf_sample {
u64 ip;
u32 pid, tid;
@@ -82,6 +92,8 @@ struct perf_sample {
void *raw_data;
struct ip_callchain *callchain;
struct branch_stack *branch_stack;
+   struct regs_dump  user_regs;
+   struct stack_dump user_stack;
 };
 
 #define BUILD_ID_SIZE 20
@@ -199,7 +211,9 @@ const char *perf_event__name(unsigned int id);
 
 int perf_event__parse_sample(const union perf_event *event, u64 type,
 int sample_size, bool sample_id_all,
-struct perf_sample *sample, bool swapped);
+u64 sample_regs_user, struct perf_sample *data,
+bool swapped);
+
 int perf_event__synthesize_sample(union perf_event *event, u64 type,
  const struct perf_sample *sample,
  bool swapped);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f74e956..02fd2e2b 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -689,6 +689,14 @@ bool perf_evlist__valid_sample_type(const struct 
perf_evlist *evlist)
return true;
 }
 
+u64 perf_evlist__sample_regs_user(const struct perf_evlist *evlist)
+{
+   struct perf_evsel *first;
+
+   first = list_entry(evlist-entries.next, struct perf_evsel, node);
+   return first-attr.sample_regs_user;
+}
+
 u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
 {
struct perf_evsel *first;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 40d4d3c..8dbf46c 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -124,6 +124,7 @@ u16 perf_evlist__id_hdr_size(const struct perf_evlist 
*evlist);
 
 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
+u64 perf_evlist__sample_regs_user(const struct perf_evlist *evlist);
 
 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
   struct list_head *list,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e817713..3a284b1 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -8,6 +8,7 @@
  */
 
 #include byteswap.h
+#include linux/bitops.h
 #include asm/bug.h
 #include evsel.h
 #include evlist.h
@@ -730,7 +731,8 @@ static bool sample_overlap(const union perf_event *event,
 
 int perf_event__parse_sample(const union perf_event *event, u64 type,
 int sample_size, bool sample_id_all

[PATCH 09/17] perf, tool: Factor DSO symtab types to generic binary types

2012-07-22 Thread Jiri Olsa
Adding interface to access DSOs so it could be used
from another place.

New DSO binary type is added - making current SYMTAB__*
types more general:
   DSO_BINARY_TYPE__* = SYMTAB__*

Following function is added to return path based on the specified
binary type:
   dso__binary_type_file

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 tools/perf/builtin-top.c   |2 +-
 tools/perf/util/annotate.c |2 +-
 tools/perf/util/symbol.c   |  209 ++--
 tools/perf/util/symbol.h   |   34 
 4 files changed, 145 insertions(+), 102 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e3cab5f..35e86c6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -125,7 +125,7 @@ static int perf_top__parse_source(struct perf_top *top, 
struct hist_entry *he)
/*
 * We can't annotate with just /proc/kallsyms
 */
-   if (map-dso-symtab_type == SYMTAB__KALLSYMS) {
+   if (map-dso-symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
pr_err(Can't annotate %s: No vmlinux file was found in the 
   path\n, sym-name);
sleep(1);
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 8069dfb..7d3641f 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -777,7 +777,7 @@ fallback:
free_filename = false;
}
 
-   if (dso-symtab_type == SYMTAB__KALLSYMS) {
+   if (dso-symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
char bf[BUILD_ID_SIZE * 2 + 16] =  with build id ;
char *build_id_msg = NULL;
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 50958bb..79fc779 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -48,6 +48,23 @@ struct symbol_conf symbol_conf = {
.symfs= ,
 };
 
+static enum dso_binary_type binary_type_symtab[] = {
+   DSO_BINARY_TYPE__KALLSYMS,
+   DSO_BINARY_TYPE__GUEST_KALLSYMS,
+   DSO_BINARY_TYPE__JAVA_JIT,
+   DSO_BINARY_TYPE__DEBUGLINK,
+   DSO_BINARY_TYPE__BUILD_ID_CACHE,
+   DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
+   DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
+   DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
+   DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+   DSO_BINARY_TYPE__GUEST_KMODULE,
+   DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+   DSO_BINARY_TYPE__NOT_FOUND,
+};
+
+#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
+
 int dso__name_len(const struct dso *dso)
 {
if (!dso)
@@ -318,7 +335,7 @@ struct dso *dso__new(const char *name)
dso__set_short_name(dso, dso-name);
for (i = 0; i  MAP__NR_TYPES; ++i)
dso-symbols[i] = dso-symbol_names[i] = RB_ROOT;
-   dso-symtab_type = SYMTAB__NOT_FOUND;
+   dso-symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
dso-loaded = 0;
dso-sorted_by_name = 0;
dso-has_build_id = 0;
@@ -806,9 +823,9 @@ int dso__load_kallsyms(struct dso *dso, const char 
*filename,
symbols__fixup_end(dso-symbols[map-type]);
 
if (dso-kernel == DSO_TYPE_GUEST_KERNEL)
-   dso-symtab_type = SYMTAB__GUEST_KALLSYMS;
+   dso-symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
else
-   dso-symtab_type = SYMTAB__KALLSYMS;
+   dso-symtab_type = DSO_BINARY_TYPE__KALLSYMS;
 
return dso__split_kallsyms(dso, map, filter);
 }
@@ -1660,32 +1677,110 @@ out:
 char dso__symtab_origin(const struct dso *dso)
 {
static const char origin[] = {
-   [SYMTAB__KALLSYMS]= 'k',
-   [SYMTAB__JAVA_JIT]= 'j',
-   [SYMTAB__DEBUGLINK]   = 'l',
-   [SYMTAB__BUILD_ID_CACHE]  = 'B',
-   [SYMTAB__FEDORA_DEBUGINFO]= 'f',
-   [SYMTAB__UBUNTU_DEBUGINFO]= 'u',
-   [SYMTAB__BUILDID_DEBUGINFO]   = 'b',
-   [SYMTAB__SYSTEM_PATH_DSO] = 'd',
-   [SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
-   [SYMTAB__GUEST_KALLSYMS]  =  'g',
-   [SYMTAB__GUEST_KMODULE]   =  'G',
+   [DSO_BINARY_TYPE__KALLSYMS] = 'k',
+   [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
+   [DSO_BINARY_TYPE__DEBUGLINK]= 'l',
+   [DSO_BINARY_TYPE__BUILD_ID_CACHE]   = 'B',
+   [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
+   [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
+   [DSO_BINARY_TYPE__BUILDID_DEBUGINFO]= 'b',
+   [DSO_BINARY_TYPE__SYSTEM_PATH_DSO]  = 'd',
+   [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]  = 'K',
+   [DSO_BINARY_TYPE__GUEST_KALLSYMS]   = 'g',
+   [DSO_BINARY_TYPE__GUEST_KMODULE]= 'G',
};
 
-   if (dso == NULL || dso-symtab_type

[PATCH 05/17] perf: Add perf_output_skip function to skip bytes in sample

2012-07-22 Thread Jiri Olsa
Introducing perf_output_skip function to be able to skip data
within the perf ring buffer.

When writing data into perf ring buffer we first reserve needed
place in ring buffer and then copy the actual data.

There's a possibility we won't be able to fill all the reserved
size with data, so we need a way to skip the remaining bytes.

This is going to be useful when storing the user stack dump,
where we might end up with less data than we originally requested.

Signed-off-by: Jiri Olsa jo...@redhat.com
Acked-by: Frederic Weisbecker fweis...@gmail.com
---
 include/linux/perf_event.h  |2 ++
 kernel/events/internal.h|4 
 kernel/events/ring_buffer.c |6 ++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 432227b..a4c53da 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1305,6 +1305,8 @@ extern int perf_output_begin(struct perf_output_handle 
*handle,
 extern void perf_output_end(struct perf_output_handle *handle);
 extern unsigned int perf_output_copy(struct perf_output_handle *handle,
 const void *buf, unsigned int len);
+extern unsigned int perf_output_skip(struct perf_output_handle *handle,
+unsigned int len);
 extern int perf_swevent_get_recursion_context(void);
 extern void perf_swevent_put_recursion_context(int rctx);
 extern void perf_event_enable(struct perf_event *event);
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index 2206a0f..be1ef29 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -114,6 +114,10 @@ static inline int memcpy_common(void *dst, const void 
*src, size_t n)
 
 DEFINE_OUTPUT_COPY(__output_copy, memcpy_common)
 
+#define MEMCPY_SKIP(dst, src, n) (n)
+
+DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
+
 #ifndef arch_perf_out_copy_user
 #define arch_perf_out_copy_user __copy_from_user_inatomic
 #endif
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index b4c2ad3..23cb34f 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -188,6 +188,12 @@ unsigned int perf_output_copy(struct perf_output_handle 
*handle,
return __output_copy(handle, buf, len);
 }
 
+unsigned int perf_output_skip(struct perf_output_handle *handle,
+ unsigned int len)
+{
+   return __output_skip(handle, NULL, len);
+}
+
 void perf_output_end(struct perf_output_handle *handle)
 {
perf_output_put_handle(handle);
-- 
1.7.7.6

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


[PATCHv7 00/17] perf: Add backtrace post dwarf unwind

2012-07-22 Thread Jiri Olsa
hi,

patches available also as tarball in here:
http://people.redhat.com/~jolsa/perf_post_unwind_v7.tar.bz2

v7 changes:
   - omitted v6 patches 9 and 15
 They need more work and will be sent separately. I dont want to hold off 
whole
 patchset because of them. We could miss some related backtraces (syscall, 
vdso)
 in this version.
   - v6 patch 11, 14, 20 already in

v6 changes:
   patch 01/23 - unrelated - ftrace stuff
   patch 03/23 - added PERF_SAMPLE_REGS_USER bit
   - added regs_user initialization
   patch 07/23 - added PERF_SAMPLE_STACK_USER bit
   - sample_stack_user changed to u32 and
 added size check
   new patches 1,9,10,20

v5 changes:
   patch 1/19 - having just one enum set of the perf registers
   patch 2/19 - using for_each_set_bit for scanning the mask
  - single regs enum for both 32 and 64 bits versions
  - using regs mask != 0 trigger to trigger the regs dump
   patch 5/19 - adding perf_output_skip so we can skip undumped part of the 
stack in RB
   patch 6/19 - using stack size != 0 trigger to trigger the stack dump
  - do not zero the memory for non retrieved part of the stack dump
   patch 7/19 - adding exclude_callchain_kernel attribute
   patch 8/19 - this could be taken without the rest of the series

v4 changes:
   - no real change from v3, just rebase
   - v3 patch 06/17 got already merged

v3 changes:
   patch 01/17
   - added HAVE_PERF_REGS config option
   patch 02/17, 04/17
   - regs and stack perf interface is more general now
   patch 06/17
   - unrelated online fix for i386 compilation
   patch 16/17
   - few namespace fixies

---
Adding the post unwinding user stack backtrace using dwarf unwind
via libunwind. The original work was done by Frederic. I mostly took
his patches and make them compile in current kernel code plus I added
some stuff here and there.

The main idea is to store user registers and portion of user
stack when the sample data during the record phase. Then during
the report, when the data is presented, perform the actual dwarf
dwarf unwind.

attached patches:
  01/17 perf: Unified API to record selective sets of arch registers
  02/17 perf: Add ability to attach user level registers dump to sample
  03/17 perf, x86: Add copy_from_user_nmi_nochk for best effort copy
  04/17 perf: Factor __output_copy to be usable with specific copy function
  05/17 perf: Add perf_output_skip function to skip bytes in sample
  06/17 perf: Add ability to attach user stack dump to sample
  07/17 perf: Add attribute to filter out callchains
  08/17 perf, tool: Adding PERF_ATTR_SIZE_VER2 to the header swap check
  09/17 perf, tool: Factor DSO symtab types to generic binary types
  10/17 perf, tool: Add interface to read DSO image data
  11/17 perf, tool: Add interface to arch registers sets
  12/17 perf, tool: Add libunwind dependency for dwarf cfi unwinding
  13/17 perf, tool: Support user regs and stack in sample parsing
  14/17 perf, tool: Support for dwarf cfi unwinding on post processing
  15/17 perf, tool: Support for dwarf mode callchain on perf record
  16/17 perf, tool: Add dso data caching
  17/17 perf, tool: Add dso data caching tests


I tested on Fedora. There was not much gain on i386, because the
binaries are compiled with frame pointers. Thought the dwarf
backtrace is more accurate and unwraps calls in more details
(functions that do not set the frame pointers).

I could see some improvement on x86_64, where I got full backtrace
where current code could got just the first address out of the
instruction pointer.

Example on x86_64:
[dwarf]
   perf record -g dwarf -e syscalls:sys_enter_write date

   100.00% date  libc-2.14.90.so  [.] __GI___libc_write
   |
   --- __GI___libc_write
   _IO_file_write@@GLIBC_2.2.5
   new_do_write
   _IO_do_write@@GLIBC_2.2.5
   _IO_file_overflow@@GLIBC_2.2.5
   0x4022cd
   0x401ee6
   __libc_start_main
   0x4020b9


[frame pointer]
   perf record -g fp -e syscalls:sys_enter_write date

   100.00% date  libc-2.14.90.so  [.] __GI___libc_write
   |
   --- __GI___libc_write

Also I tested on coreutils binaries mainly, but I could see
getting wider backtraces with dwarf unwind for more complex
application like firefox.

Attached patches should work on both x86 and x86_64.

The unwind backtrace can be interrupted by following reasons:
- bug in unwind information of processed shared library
- bug in unwind processing code (most likely ;) )
- insufficient dump stack size
- until full syscall register storage and vdso support
  we could miss some related backtraces 

jirka
---
 arch/Kconfig   |6 +
 arch/x86/Kconfig   |1 +
 arch/x86/include/asm/perf_event.h  | 

[PATCH 04/17] perf: Factor __output_copy to be usable with specific copy function

2012-07-22 Thread Jiri Olsa
From: Frederic Weisbecker fweis...@gmail.com

Adding a generic way to use __output_copy function with
specific copy function via DEFINE_PERF_OUTPUT_COPY macro.

Using this to add new __output_copy_user function, that provides
output copy from user pointers. For x86 the copy_from_user_nmi_nochk
function is used and __copy_from_user_inatomic for the rest
of the architectures.

This new function will be used in user stack dump on sample,
coming in next patches.

Signed-off-by: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/include/asm/perf_event.h |2 +
 include/linux/perf_event.h|2 +-
 kernel/events/internal.h  |   62 
 kernel/events/ring_buffer.c   |4 +-
 4 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h 
b/arch/x86/include/asm/perf_event.h
index c78f14a..ada1cab 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -257,4 +257,6 @@ static inline void perf_check_microcode(void) { }
  static inline void amd_pmu_disable_virt(void) { }
 #endif
 
+#define arch_perf_out_copy_user copy_from_user_nmi_nochk
+
 #endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 57f209d..432227b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1303,7 +1303,7 @@ static inline bool has_branch_stack(struct perf_event 
*event)
 extern int perf_output_begin(struct perf_output_handle *handle,
 struct perf_event *event, unsigned int size);
 extern void perf_output_end(struct perf_output_handle *handle);
-extern void perf_output_copy(struct perf_output_handle *handle,
+extern unsigned int perf_output_copy(struct perf_output_handle *handle,
 const void *buf, unsigned int len);
 extern int perf_swevent_get_recursion_context(void);
 extern void perf_swevent_put_recursion_context(int rctx);
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index b0b107f..2206a0f 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -2,6 +2,7 @@
 #define _KERNEL_EVENTS_INTERNAL_H
 
 #include linux/hardirq.h
+#include linux/uaccess.h
 
 /* Buffer handling */
 
@@ -76,30 +77,49 @@ static inline unsigned long perf_data_size(struct 
ring_buffer *rb)
return rb-nr_pages  (PAGE_SHIFT + page_order(rb));
 }
 
-static inline void
-__output_copy(struct perf_output_handle *handle,
-  const void *buf, unsigned int len)
+#define DEFINE_OUTPUT_COPY(func_name, memcpy_func) \
+static inline unsigned int \
+func_name(struct perf_output_handle *handle,   \
+ const void *buf, unsigned int len)\
+{  \
+   unsigned long size, written;\
+   \
+   do {\
+   size = min_t(unsigned long, handle-size, len); \
+   \
+   written = memcpy_func(handle-addr, buf, size); \
+   \
+   len -= written; \
+   handle-addr += written;\
+   buf += written; \
+   handle-size -= written;\
+   if (!handle-size) {\
+   struct ring_buffer *rb = handle-rb;\
+   \
+   handle-page++; \
+   handle-page = rb-nr_pages - 1;   \
+   handle-addr = rb-data_pages[handle-page];\
+   handle-size = PAGE_SIZE  page_order(rb); \
+   }   \
+   } while (len  written == size);   \
+   \
+   return len; \
+}
+
+static inline int memcpy_common(void *dst, const void *src, size_t n)
 {
-   do {
-   unsigned long size = min_t(unsigned long, handle-size, len);
-
-   memcpy(handle-addr, buf, size);
-
-   len -= size;
-   handle-addr += size;
-   buf += size;
-   handle-size -= size;
-   if (!handle-size) {
-   struct

[PATCH 03/17] perf, x86: Add copy_from_user_nmi_nochk for best effort copy

2012-07-22 Thread Jiri Olsa
Adding copy_from_user_nmi_nochk that provides the best effort
copy regardless the requesting size crossing the task boundary.

This is going to be useful for stack dump we need in post
DWARF CFI based unwind, where we have predefined size of
the user stack to dump, and we need to store the most of
the requested dump size, regardless this size is crossing
the task boundary.

Signed-off-by: Jiri Olsa jo...@redhat.com
---
 arch/x86/include/asm/uaccess.h |2 ++
 arch/x86/lib/usercopy.c|   15 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index e1f3a17..d8d6bcd 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -562,6 +562,8 @@ struct __large_struct { unsigned long buf[100]; };
 #endif /* CONFIG_X86_WP_WORKS_OK */
 
 extern unsigned long
+copy_from_user_nmi_nochk(void *to, const void __user *from, unsigned long n);
+extern unsigned long
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
 extern __must_check long
 strncpy_from_user(char *dst, const char __user *src, long count);
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c
index 4f74d94..29ca1c7 100644
--- a/arch/x86/lib/usercopy.c
+++ b/arch/x86/lib/usercopy.c
@@ -14,7 +14,7 @@
  * best effort, GUP based copy_from_user() that is NMI-safe
  */
 unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+copy_from_user_nmi_nochk(void *to, const void __user *from, unsigned long n)
 {
unsigned long offset, addr = (unsigned long)from;
unsigned long size, len = 0;
@@ -22,9 +22,6 @@ copy_from_user_nmi(void *to, const void __user *from, 
unsigned long n)
void *map;
int ret;
 
-   if (__range_not_ok(from, n, TASK_SIZE))
-   return len;
-
do {
ret = __get_user_pages_fast(addr, 1, 0, page);
if (!ret)
@@ -46,4 +43,14 @@ copy_from_user_nmi(void *to, const void __user *from, 
unsigned long n)
 
return len;
 }
+EXPORT_SYMBOL_GPL(copy_from_user_nmi_nochk);
+
+unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+   if (__range_not_ok(from, n, TASK_SIZE) == 0)
+   return 0;
+
+   return copy_from_user_nmi_nochk(to, from, n);
+}
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
-- 
1.7.7.6

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


Re: [PATCH 04/11] perf kvm: fix bug resolving guest kernel syms - v2

2012-07-25 Thread Jiri Olsa
On Fri, Jul 20, 2012 at 05:25:49PM -0600, David Ahern wrote:
 Guest kernel symbols are not resolved despite passing the information
 needed to resolve them. e.g.,
 
 perf kvm --guest --guestmount=/tmp/guest-mount record -a -- sleep 1
 perf kvm --guest --guestmount=/tmp/guest-mount report --stdio
 
 36.55%  [guest/11399]  [unknown] [g] 0x81600bc8
 33.19%  [guest/10474]  [unknown] [g] 0xc0116e00
 30.26%  [guest/11094]  [unknown] [g] 0x8100a288
 43.69%  [guest/10474]  [unknown] [g] 0xc0103d90
 37.38%  [guest/11399]  [unknown] [g] 0x81600bc8
 12.24%  [guest/11094]  [unknown] [g] 0x810aa91d
  6.69%  [guest/11094]  [unknown] [u] 0x7fa784d721c3
 
 which is just pathetic.
 
 After a maddening 2 days sifting through perf minutia I found it --
 id_hdr_size is not initialized for guest machines. This shows up on the
 report side as random garbage for the cpu and timestamp, e.g.,
 
 29816 7310572949125804849 0x1ac0 [0x50]: PERF_RECORD_MMAP ...
 
 That messes up the sample sorting such that synthesized guest maps are
 processed last.
 
 With this patch you get a much more helpful report:
 
   12.11%  [guest/11399]  [guest.kernel.kallsyms.11399]  [g] 
 irqtime_account_process_tick
   10.58%  [guest/11399]  [guest.kernel.kallsyms.11399]  [g] run_timer_softirq
6.95%  [guest/11094]  [guest.kernel.kallsyms.11094]  [g] printk_needs_cpu
6.50%  [guest/11094]  [guest.kernel.kallsyms.11094]  [g] do_timer
6.45%  [guest/11399]  [guest.kernel.kallsyms.11399]  [g] idle_balance
4.90%  [guest/11094]  [guest.kernel.kallsyms.11094]  [g] native_read_tsc
 ...
 
 v2:
 - changed rbtree walk to use rb_first per Namhyung's suggestion
 
 Signed-off-by: David Ahern dsah...@gmail.com
 Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
 Cc: Ingo Molnar mi...@kernel.org
 Cc: Jiri Olsa jo...@redhat.com

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


Re: [PATCH 02/11] perf kvm: set name for VM process in guest machine

2012-07-25 Thread Jiri Olsa
On Fri, Jul 20, 2012 at 05:25:47PM -0600, David Ahern wrote:
 COMM events are not generated in the context of a guest machine, so the
 thread name is never set for the VMM process. For example, the qemu-kvm
 name applies to the process in the host machine, not the guest machine.
 So, samples for guest machines are currently displayed as:
 
 99.67% :5671  [unknown] [g] 0x81366b41
 
 where 5671 is the pid of the VMM. With this patch the samples in the guest
 machine are shown as:
 
 18.43%  [guest/5671]  [unknown]   [g] 0x810d68b7

Tested-by: Jiri Olsa jo...@redhat.com


 
 Signed-off-by: David Ahern dsah...@gmail.com
 Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
 Cc: Ingo Molnar mi...@kernel.org
 Cc: Jiri Olsa jo...@redhat.com
 Cc: Namhyung Kim namhy...@kernel.org
 Cc: Frederic Weisbecker fweis...@gmail.com
 Cc: Peter Zijlstra pet...@infradead.org
 ---
  tools/perf/util/map.c |   17 -
  1 file changed, 16 insertions(+), 1 deletion(-)
 
 diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
 index a1f4e36..8668569 100644
 --- a/tools/perf/util/map.c
 +++ b/tools/perf/util/map.c
 @@ -7,6 +7,7 @@
  #include stdio.h
  #include unistd.h
  #include map.h
 +#include thread.h
  
  const char *map_type__name[MAP__NR_TYPES] = {
   [MAP__FUNCTION] = Functions,
 @@ -585,7 +586,21 @@ int machine__init(struct machine *self, const char 
 *root_dir, pid_t pid)
   self-kmaps.machine = self;
   self-pid   = pid;
   self-root_dir  = strdup(root_dir);
 - return self-root_dir == NULL ? -ENOMEM : 0;
 + if (self-root_dir == NULL)
 + return -ENOMEM;
 +
 + if (pid != HOST_KERNEL_ID) {
 + struct thread *thread = machine__findnew_thread(self, pid);
 + char comm[64];
 +
 + if (thread == NULL)
 + return -ENOMEM;
 +
 + snprintf(comm, sizeof(comm), [guest/%d], pid);
 + thread__set_comm(thread, comm);
 + }
 +
 + return 0;
  }
  
  static void dsos__delete(struct list_head *self)
 -- 
 1.7.10.1
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] perf kvm: guest userspace samples should not be lumped with host uspace

2012-07-25 Thread Jiri Olsa
On Fri, Jul 20, 2012 at 05:25:48PM -0600, David Ahern wrote:
 e.g., perf kvm --host  --guest report -i perf.data --stdio -D
 shows:
 
 1 599127912065356 0x143b8 [0x48]: PERF_RECORD_SAMPLE(IP, 5): 5671/5676: 
 0x7fdf95a061c0 period: 1 addr: 0
 ... chain: nr:2
 .  0: ff80
 .  1: fe00
  ... thread: qemu-kvm:5671
  .. dso: not found
 
 (IP, 5) means sample in guest userspace. Those samples should not be lumped
 into the VMM's host thread. i.e, the report output:
 
 56.86%  qemu-kvm  [unknown] [u] 0x7fdf95a061c0
 
 With this patch the output emphasizes it is a guest userspace hit:
 
 56.86%  [guest/5671]  [unknown] [u] 0x7fdf95a061c0
 
 Looking at 3 VMs (2 64-bit, 1 32-bit) with each running a CPU bound
 process (openssl speed), perf report currently shows:
 
   93.84%  117726   qemu-kvm  [unknown]   [u] 0x7fd7dcaea8e5
 
 which is wrong. With this patch you get:
 
   31.50%   39258   [guest/18772]  [unknown]   [u] 0x7fd7dcaea8e5
   31.50%   39236   [guest/11230]  [unknown]   [u] 0x00a57340
   30.84%   39232   [guest/18395]  [unknown]   [u] 0x7f66f641e107

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


Re: [PATCH 06/12] perf header: Reconstruct group relationship by parsing cmdline

2012-07-25 Thread Jiri Olsa
On Tue, Jul 24, 2012 at 06:01:27PM +0900, Namhyung Kim wrote:
 In order to support the event group viewer, their group relationship
 is needed. Since it's not recorded explicitly anywhere in the perf.data
 we should parse saved cmdline and apply the result to the evlist. It is
 assumed that parsed entries are in a same order with the originals.
 
 I know it's fragile but hard to find other way to do it in the current
 condition. :(

How about storing grouping details in new perf.data feature?
As you said reparsing looks too fragile.

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


Re: [PATCH 2/3] perf hists: Link hist entries before inserting to an output tree

2012-12-05 Thread Jiri Olsa
On Wed, Dec 05, 2012 at 03:56:42PM +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com
 

SNIP

 - struct rb_node *next = rb_first(hists-entries);
 + struct rb_root *root;
 + struct rb_node *next;
 +
 + if (sort__need_collapse)
 + root = hists-entries_collapsed;
 + else
 + root = hists-entries_in;
  
 + next = rb_first(root);
   while (next != NULL) {
 - struct hist_entry *he = rb_entry(next, struct hist_entry, 
 rb_node);
 + struct hist_entry *he = rb_entry(next, struct hist_entry, 
 rb_node_in);
  
 - next = rb_next(he-rb_node);
 + next = rb_next(he-rb_node_in);
   if (!hist_entry__next_pair(he)) {
 - rb_erase(he-rb_node, hists-entries);
 + rb_erase(he-rb_node_in, root);
   hist_entry__free(he);
   }
   }
 @@ -481,6 +459,11 @@ static void hists__process(struct hists *old, struct 
 hists *new)
   else
   hists__link(new, old);
  
 + hists__output_resort(new);
 +
 + if (show_displacement)
 + hists__compute_position(new);
 +

Computing the position after hists__link screws up the position data,
because we likely have new entries in.

However, I wonder if anyone is actualy using displacement info..?

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


Re: [PATCH 2/3] perf hists: Link hist entries before inserting to an output tree

2012-12-05 Thread Jiri Olsa
On Wed, Dec 05, 2012 at 08:06:46PM +0100, Jiri Olsa wrote:
 On Wed, Dec 05, 2012 at 03:56:42PM +0900, Namhyung Kim wrote:
  From: Namhyung Kim namhyung@lge.com
  
 
 SNIP
 
  -   struct rb_node *next = rb_first(hists-entries);
  +   struct rb_root *root;
  +   struct rb_node *next;
  +
  +   if (sort__need_collapse)
  +   root = hists-entries_collapsed;
  +   else
  +   root = hists-entries_in;
   
  +   next = rb_first(root);
  while (next != NULL) {
  -   struct hist_entry *he = rb_entry(next, struct hist_entry, 
  rb_node);
  +   struct hist_entry *he = rb_entry(next, struct hist_entry, 
  rb_node_in);
   
  -   next = rb_next(he-rb_node);
  +   next = rb_next(he-rb_node_in);
  if (!hist_entry__next_pair(he)) {
  -   rb_erase(he-rb_node, hists-entries);
  +   rb_erase(he-rb_node_in, root);
  hist_entry__free(he);
  }
  }
  @@ -481,6 +459,11 @@ static void hists__process(struct hists *old, struct 
  hists *new)
  else
  hists__link(new, old);
   
  +   hists__output_resort(new);
  +
  +   if (show_displacement)
  +   hists__compute_position(new);
  +
 
 Computing the position after hists__link screws up the position data,
 because we likely have new entries in.
 
 However, I wonder if anyone is actualy using displacement info..?

hum,

the point of the displacement is to show how far is the matching entry
in baseline wrt report output - after hists__output_resort.. that goes
in opposite way of what we try do to in here.

Anyone else in favour of removing 'Displ.' column? ;-)

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


[PATCH] perf diff: Removing displacement output option

2012-12-06 Thread Jiri Olsa
On Wed, Dec 05, 2012 at 04:12:09PM -0300, Arnaldo Carvalho de Melo wrote:
 Em Wed, Dec 05, 2012 at 08:06:46PM +0100, Jiri Olsa escreveu:
  On Wed, Dec 05, 2012 at 03:56:42PM +0900, Namhyung Kim wrote:
   From: Namhyung Kim namhyung@lge.com
   @@ -481,6 +459,11 @@ static void hists__process(struct hists *old, struct 
   hists *new)
 else
 hists__link(new, old);

   + hists__output_resort(new);
   +
   + if (show_displacement)
   + hists__compute_position(new);
   +
  
  Computing the position after hists__link screws up the position data,
  because we likely have new entries in.
  
  However, I wonder if anyone is actualy using displacement info..?
 
 IIRC that was used long ago in the first version of 'perf diff', that
 is not the default, probably we can just ditch it to simplify things,
 can you check?

you're right, it's there since vert beggining.. and now it's gone ;) attached

jirka


---
Removing displacement output option. It seems not very useful,
because it's possible and event more convenient to lookup related
symbol by name. Also the output value for both 'baseline' and
'new' data is quite apparent from diff output.

And above all it complicates hist code factoring ;)

Ditching out PERF_HPP__DISPL column with related output functions.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@redhat.com
Cc: Namhyung Kim namhy...@kernel.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Ingo Molnar mi...@elte.hu
Cc: Namhyung Kim namhy...@kernel.org
Cc: Paul Mackerras pau...@samba.org
Cc: Peter Zijlstra a.p.zijls...@chello.nl
---
 tools/perf/Documentation/perf-diff.txt |  4 
 tools/perf/builtin-diff.c  | 29 +++--
 tools/perf/ui/hist.c   | 25 -
 tools/perf/util/hist.h |  1 -
 4 files changed, 7 insertions(+), 52 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt 
b/tools/perf/Documentation/perf-diff.txt
index 194f37d..5b3123d 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -22,10 +22,6 @@ specified perf.data files.
 
 OPTIONS
 ---
--M::
---displacement::
-Show position displacement relative to baseline.
-
 -D::
 --dump-raw-trace::
 Dump raw trace in ASCII.
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index d869029..b2e7d39 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -23,7 +23,6 @@ static char const *input_old = perf.data.old,
  *input_new = perf.data;
 static char  diff__default_sort_order[] = dso,symbol;
 static bool  force;
-static bool show_displacement;
 static bool show_period;
 static bool show_formula;
 static bool show_baseline_only;
@@ -296,9 +295,8 @@ static void insert_hist_entry_by_name(struct rb_root *root,
rb_insert_color(he-rb_node, root);
 }
 
-static void hists__name_resort(struct hists *self, bool sort)
+static void hists__name_resort(struct hists *self)
 {
-   unsigned long position = 1;
struct rb_root tmp = RB_ROOT;
struct rb_node *next = rb_first(self-entries);
 
@@ -306,16 +304,12 @@ static void hists__name_resort(struct hists *self, bool 
sort)
struct hist_entry *n = rb_entry(next, struct hist_entry, 
rb_node);
 
next = rb_next(n-rb_node);
-   n-position = position++;
 
-   if (sort) {
-   rb_erase(n-rb_node, self-entries);
-   insert_hist_entry_by_name(tmp, n);
-   }
+   rb_erase(n-rb_node, self-entries);
+   insert_hist_entry_by_name(tmp, n);
}
 
-   if (sort)
-   self-entries = tmp;
+   self-entries = tmp;
 }
 
 static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
@@ -339,12 +333,8 @@ static void perf_evlist__resort_hists(struct perf_evlist 
*evlist, bool name)
 
hists__output_resort(hists);
 
-   /*
-* The hists__name_resort only sets possition
-* if name is false.
-*/
-   if (name || ((!name)  show_displacement))
-   hists__name_resort(hists, name);
+   if (name)
+   hists__name_resort(hists);
}
 }
 
@@ -549,8 +539,6 @@ static const char * const diff_usage[] = {
 static const struct option options[] = {
OPT_INCR('v', verbose, verbose,
be more verbose (show symbol address, etc)),
-   OPT_BOOLEAN('M', displacement, show_displacement,
-   Show position displacement relative to baseline),
OPT_BOOLEAN('b', baseline-only, show_baseline_only,
Show only items with match in baseline),
OPT_CALLBACK('c', compute, compute,
@@ -585,7 +573,7 @@ static const struct option options[] = {
 static void ui_init(void

Re: [PATCH 3/5] perf hists: Link hist entries before inserting to an output tree

2012-12-06 Thread Jiri Olsa
On Fri, Dec 07, 2012 at 12:09:39AM +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com
 
 For matching and/or linking hist entries, they need to be sorted by
 given sort keys.  However current hists__match/link did this on the
 output trees, so that the entries in the output tree need to be resort
 before doing it.
 
 This looks not so good since we have trees for collecting or
 collapsing entries before passing them to an output tree and they're
 already sorted by the given sort keys.  Since we don't need to print
 anything at the time of matching/linking, we can use these internal
 trees directly instead of bothering with double resort on the output
 tree.

this patch also makes diff working over collapsed entries,
which was not possible before.. nice ;)

outputs like:

[jolsa@krava perf]$ ./perf diff  -s comm
# Event 'cycles:u'
#
# BaselineDelta  Command
#   ...  ...
#
 5.24%  +68.96%  firefox
 2.34%   +5.66%X
48.51%  -41.53% mocp
14.98%  -11.53%skype
18.01%  -15.35%  plugin-containe
 1.03%   +1.48%xchat
 5.54%   -4.61%  gkrellm
 1.41%   -0.93%xterm
 +0.33%  xmonad-x86_64-l
 +0.23%  vim
 +0.07% xscreensaver
 0.19%   -0.14%  swapper
 1.00%   -0.97%   NetworkManager
 0.28%   -0.25%  ssh
 0.11%   -0.09%sleep
 0.84%   -0.83%  dbus-daemon
 0.02%   -0.01% perf
 0.40%   -0.40%   wpa_supplicant
 0.05%   -0.05%  gpm
 0.04%   -0.04%crond


small nitpick below, otherwise

Acked-by: Jiri Olsa jo...@redhat.com


 
 Its only user - at the time of this writing - perf diff can be easily
 converted to use the internal tree and can save some lines too by
 getting rid of unnecessary resorting codes.
 
 Cc: Jiri Olsa jo...@redhat.com
 Cc: Stephane Eranian eran...@google.com
 Signed-off-by: Namhyung Kim namhy...@kernel.org
 ---
  tools/perf/builtin-diff.c |   65 
 -
  tools/perf/util/hist.c|   49 +-
  2 files changed, 54 insertions(+), 60 deletions(-)
 
 diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
 index b2e7d39f099b..044ad99dcc90 100644
 --- a/tools/perf/builtin-diff.c
 +++ b/tools/perf/builtin-diff.c
 @@ -275,43 +275,6 @@ static struct perf_tool tool = {
   return NULL;A

SNIP

  }
  
 -static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
 +static void perf_evlist__resort_hists(struct perf_evlist *evlist)

this could be called 'perf_evlist__collapse_resort' now

  {
   struct perf_evsel *evsel;
  
   list_for_each_entry(evsel, evlist-entries, node) {
   struct hists *hists = evsel-hists;
  
 - hists__output_resort(hists);
 -
 - if (name)
 - hists__name_resort(hists);
 + hists__collapse_resort(hists);
   }
  }

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


Re: [PATCH 4/5] perf diff: Use internal rb tree for compute resort

2012-12-06 Thread Jiri Olsa
On Fri, Dec 07, 2012 at 12:09:40AM +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com
 
 There's no reason to run hists_compute_resort() using output tree.
 Convert it to use internal tree so that it can remove unnecessary
 _output_resort.

I have another patch in queue ommiting dummy entries to display
number in the compute column, so we don't have confusing 'sorted'
outputs like:

[jolsa@krava perf]$ ./perf diff -c+delta
# Event 'cycles:u'
#
# BaselineDelta  Shared Object  Symbol
#   ...  .  ..
#
17.92%  -17.92%  libc-2.15.so   [.] _IO_link_in   
+77.54%  libc-2.15.so   [.] __fprintf_chk 
15.64%  -15.64%  libc-2.15.so   [.] _dl_addr  
 0.08%   +0.61%  ld-2.15.so [.] _start
12.16%  -12.16%  ld-2.15.so [.] dl_main   
15.39%  -15.39%  ld-2.15.so [.] _dl_check_map_versions
38.81%  -17.04%  [kernel.kallsyms]  [k] page_fault

just in case anyone actualy tries and wonders ;)


We need following change as well, because output resort does
also col width recalc. Please add it if you respin, or I can
send it later.

other than that:

Acked-by: Jiri Olsa jo...@redhat.com

thanks,
jirka

---
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index f66968e..6f56f78 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -425,12 +425,15 @@ static void hists__compute_resort(struct hists *hists)
hists-entries = RB_ROOT;
next = rb_first(root);
 
+   hists__reset_col_len(hists);
+
while (next != NULL) {
struct hist_entry *he;
 
he = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(he-rb_node_in);
 
+   hists__calc_col_len(hists, he);
insert_hist_entry_by_compute(hists-entries, he, compute);
}
 }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/5] perf hists: Exchange order of comparing items when collapsing hists

2012-12-06 Thread Jiri Olsa
On Fri, Dec 07, 2012 at 12:09:38AM +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com
 
 When comparing entries for collapsing put the given entry first, and
 then the iterated entry.  This is not the case of hist_entry__cmp()
 when called if given sort keys don't require collapsing.  So change
 the order for the sake of consistency.  It will be required for
 matching and/or linking multiple hist entries.

As discussed with Arnadlo, this change seems like changing the
sort order... could you ellaborate how it is usefull in future?

thanks,
jirka

 
 Cc: Jiri Olsa jo...@redhat.com
 Cc: Stephane Eranian eran...@google.com
 Signed-off-by: Namhyung Kim namhy...@kernel.org
 ---
  tools/perf/util/hist.c |6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
 index 82df1b26f0d4..d4471c21ed17 100644
 --- a/tools/perf/util/hist.c
 +++ b/tools/perf/util/hist.c
 @@ -285,7 +285,7 @@ static struct hist_entry *add_hist_entry(struct hists 
 *hists,
   parent = *p;
   he = rb_entry(parent, struct hist_entry, rb_node_in);
  
 - cmp = hist_entry__cmp(entry, he);
 + cmp = hist_entry__cmp(he, entry);
  
   if (!cmp) {
   he_stat__add_period(he-stat, period);
 @@ -729,7 +729,7 @@ static struct hist_entry *hists__add_dummy_entry(struct 
 hists *hists,
   parent = *p;
   he = rb_entry(parent, struct hist_entry, rb_node);
  
 - cmp = hist_entry__cmp(pair, he);
 + cmp = hist_entry__cmp(he, pair);
  
   if (!cmp)
   goto out;
 @@ -759,7 +759,7 @@ static struct hist_entry *hists__find_entry(struct hists 
 *hists,
  
   while (n) {
   struct hist_entry *iter = rb_entry(n, struct hist_entry, 
 rb_node);
 - int64_t cmp = hist_entry__cmp(he, iter);
 + int64_t cmp = hist_entry__cmp(iter, he);
  
   if (cmp  0)
   n = n-rb_left;
 -- 
 1.7.9.2
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/5] perf hists: Exchange order of comparing items when collapsing hists

2012-12-07 Thread Jiri Olsa
On Fri, Dec 07, 2012 at 05:38:22PM +0900, Namhyung Kim wrote:
 Hi Arnaldo,
 

SNIP

 @@ -739,6 +739,10 @@ static struct hist_entry *hists__add_dummy_entry(struct 
 hists *hists,
  
 cmp = hist_entry__collapse(he, pair);
  
 +   if (sort__need_collapse)
 +   cmp = hist_entry__collapse(he, pair);
 +   else
 +   cmp = hist_entry__cmp(pair, he);
 if (!cmp)
 goto out;
  
 @@ -772,7 +776,12 @@ static struct hist_entry *hists__find_entry(struct hists 
 *hists,
  
 while (n) {
 struct hist_entry *iter = rb_entry(n, struct hist_entry, 
 rb_node_in);
 -   int64_t cmp = hist_entry__collapse(iter, he);
 +   int64_t cmp;
 +
 +   if (sort__need_collapse)
 +   cmp = hist_entry__collapse(iter, he);
 +   else
 +   cmp = hist_entry__cmp(he, iter);
  
 if (cmp  0)
 n = n-rb_left;
 
 It doesn't look good, especially hist_entry__collapse will be same as
 hist_entry__cmp if 'sort__need_collapse' is false.  If we can make the
 order consistent, it'd be converted to a sigle _collapse() call
 without the conditional.
 
 Thanks,
 Namhyung

I've got non matching entries in diff after applying just patch 2/5,
and it's caused by missing he/iter swap in initial name resort in
insert_hist_entry_by_name function.

I understand that function goes away in your next patch while
add_hist_entry (swap ok) being the one doing initial name resort,
but still.. took me some time to figure this out ;)

jirka

---
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index b2e7d39..4dda6f4 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -285,7 +285,7 @@ static void insert_hist_entry_by_name(struct rb_root *root,
while (*p != NULL) {
parent = *p;
iter = rb_entry(parent, struct hist_entry, rb_node);
-   if (hist_entry__cmp(he, iter)  0)
+   if (hist_entry__cmp(iter, he)  0)
p = (*p)-rb_left;
else
p = (*p)-rb_right;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] perf hists: Exchange order of comparing items when collapsing hists

2012-12-10 Thread Jiri Olsa
On Mon, Dec 10, 2012 at 05:29:54PM +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com
 
 When comparing entries for collapsing put the given entry first, and
 then the iterated entry.  This is not the case of hist_entry__cmp()
 when called if given sort keys don't require collapsing.  So change
 the order for the sake of consistency.  It will be required for
 matching and/or linking multiple hist entries.
 
 Cc: Jiri Olsa jo...@redhat.com
 Cc: Stephane Eranian eran...@google.com
 Signed-off-by: Namhyung Kim namhy...@kernel.org

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


[PATCH 01/14] perf tool: Introduce perf_hpp__list for period related columns

2012-11-28 Thread Jiri Olsa
Adding perf_hpp__list list to register and contain all period
related columns the command is interested in.

This way we get rid of static array holding all possible
columns and enable commands to register their own columns.

It'll be handy for diff command in future to process and display
data for multiple files.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c  | 21 -
 tools/perf/builtin-report.c|  1 +
 tools/perf/ui/browsers/hists.c | 18 +---
 tools/perf/ui/gtk/browser.c| 28 +---
 tools/perf/ui/hist.c   | 96 +++---
 tools/perf/ui/setup.c  |  1 +
 tools/perf/ui/stdio/hist.c | 17 +++-
 tools/perf/util/hist.h | 11 -
 8 files changed, 99 insertions(+), 94 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 93b852f..9fbbc01 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -597,40 +597,35 @@ static const struct option options[] = {
 
 static void ui_init(void)
 {
-   perf_hpp__init();
-
-   /* No overhead column. */
-   perf_hpp__column_enable(PERF_HPP__OVERHEAD, false);
-
/*
 * Display baseline/delta/ratio/displacement/
 * formula/periods columns.
 */
-   perf_hpp__column_enable(PERF_HPP__BASELINE, true);
+   perf_hpp__column_enable(PERF_HPP__BASELINE);
 
switch (compute) {
case COMPUTE_DELTA:
-   perf_hpp__column_enable(PERF_HPP__DELTA, true);
+   perf_hpp__column_enable(PERF_HPP__DELTA);
break;
case COMPUTE_RATIO:
-   perf_hpp__column_enable(PERF_HPP__RATIO, true);
+   perf_hpp__column_enable(PERF_HPP__RATIO);
break;
case COMPUTE_WEIGHTED_DIFF:
-   perf_hpp__column_enable(PERF_HPP__WEIGHTED_DIFF, true);
+   perf_hpp__column_enable(PERF_HPP__WEIGHTED_DIFF);
break;
default:
BUG_ON(1);
};
 
if (show_displacement)
-   perf_hpp__column_enable(PERF_HPP__DISPL, true);
+   perf_hpp__column_enable(PERF_HPP__DISPL);
 
if (show_formula)
-   perf_hpp__column_enable(PERF_HPP__FORMULA, true);
+   perf_hpp__column_enable(PERF_HPP__FORMULA);
 
if (show_period) {
-   perf_hpp__column_enable(PERF_HPP__PERIOD, true);
-   perf_hpp__column_enable(PERF_HPP__PERIOD_BASELINE, true);
+   perf_hpp__column_enable(PERF_HPP__PERIOD);
+   perf_hpp__column_enable(PERF_HPP__PERIOD_BASELINE);
}
 }
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index fc25100..5134acf 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -692,6 +692,7 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
setup_browser(true);
else {
use_browser = 0;
+   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
perf_hpp__init();
}
 
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ccc4bd1..96fdbc8 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -587,6 +587,8 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
 
 void hist_browser__init_hpp(void)
 {
+   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
+
perf_hpp__init();
 
perf_hpp__format[PERF_HPP__OVERHEAD].color =
@@ -607,12 +609,13 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
 {
char s[256];
double percent;
-   int i, printed = 0;
+   int printed = 0;
int width = browser-b.width;
char folded_sign = ' ';
bool current_entry = ui_browser__is_current_entry(browser-b, row);
off_t row_offset = entry-row_offset;
bool first = true;
+   struct perf_hpp_fmt *fmt;
 
if (current_entry) {
browser-he_selection = entry;
@@ -629,12 +632,11 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
.buf= s,
.size   = sizeof(s),
};
+   int i = 0;
 
ui_browser__gotorc(browser-b, row, 0);
 
-   for (i = 0; i  PERF_HPP__MAX_INDEX; i++) {
-   if (!perf_hpp__format[i].cond)
-   continue;
+   perf_hpp__for_each_format(fmt) {
 
if (!first) {
slsmg_printf(  );
@@ -642,10 +644,10 @@ static int hist_browser__show_entry

[PATCH 04/14] perf diff: Remove displacement from struct hist_entry_diff

2012-11-28 Thread Jiri Olsa
Removing displacement from struct hist_entry_diff, because
it's not used. Displacement is not used for sorting, so
there's no reason to pre-calculate it.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/sort.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index b4e8c3b..a884be2 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -55,9 +55,6 @@ struct he_stat {
 struct hist_entry_diff {
boolcomputed;
 
-   /* PERF_HPP__DISPL */
-   int displacement;
-
/* PERF_HPP__DELTA */
double  period_ratio_delta;
 
-- 
1.7.11.7

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


[PATCH 02/14] perf tool: Add struct perf_hpp_fmt into hpp callbacks

2012-11-28 Thread Jiri Olsa
Adding 'struct perf_hpp_fmt' into hpp callbacks, so commands
can access their private data.

It'll be handy for diff command in future to be able to access
file related data for each column.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c |  10 ++-
 tools/perf/ui/hist.c   | 169 +++--
 tools/perf/ui/stdio/hist.c |   4 +-
 tools/perf/util/hist.h |  10 ++-
 4 files changed, 127 insertions(+), 66 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 96fdbc8..4e06ba5 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -568,8 +568,10 @@ static int hist_browser__show_callchain(struct 
hist_browser *browser,
 }
 
 #define HPP__COLOR_FN(_name, _field)   \
-static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
-struct hist_entry *he) \
+static int hist_browser__hpp_color_ ## _name(  \
+   struct perf_hpp_fmt *fmt __maybe_unused,\
+   struct perf_hpp *hpp,   \
+   struct hist_entry *he)  \
 {  \
struct hists *hists = he-hists;\
double percent = 100.0 * he-stat._field / hists-stats.total_period; \
@@ -647,7 +649,7 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
if (fmt-color) {
hpp.ptr = percent;
/* It will set percent for us. See 
HPP__COLOR_FN above. */
-   width -= fmt-color(hpp, entry);
+   width -= fmt-color(fmt, hpp, entry);
 
ui_browser__set_percent_color(browser-b, 
percent, current_entry);
 
@@ -661,7 +663,7 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
if (!current_entry || !browser-b.navkeypressed)
ui_browser__set_color(browser-b, 
HE_COLORSET_NORMAL);
} else {
-   width -= fmt-entry(hpp, entry);
+   width -= fmt-entry(fmt, hpp, entry);
slsmg_printf(%s, s);
}
 
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 0a5281f..5452960 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -6,17 +6,20 @@
 
 
 /* hist period print (hpp) functions */
-static int hpp__header_overhead(struct perf_hpp *hpp)
+static int hpp__header_overhead(struct perf_hpp_fmt *fmt __maybe_unused,
+   struct perf_hpp *hpp)
 {
return scnprintf(hpp-buf, hpp-size, Overhead);
 }
 
-static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
+static int hpp__width_overhead(struct perf_hpp_fmt *fmt __maybe_unused,
+  struct perf_hpp *hpp __maybe_unused)
 {
return 8;
 }
 
-static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
+static int hpp__color_overhead(struct perf_hpp_fmt *fmt __maybe_unused,
+  struct perf_hpp *hpp, struct hist_entry *he)
 {
struct hists *hists = he-hists;
double percent = 100.0 * he-stat.period / hists-stats.total_period;
@@ -24,7 +27,8 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
 }
 
-static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
+static int hpp__entry_overhead(struct perf_hpp_fmt *_fmt __maybe_unused,
+  struct perf_hpp *hpp, struct hist_entry *he)
 {
struct hists *hists = he-hists;
double percent = 100.0 * he-stat.period / hists-stats.total_period;
@@ -33,19 +37,22 @@ static int hpp__entry_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
return scnprintf(hpp-buf, hpp-size, fmt, percent);
 }
 
-static int hpp__header_overhead_sys(struct perf_hpp *hpp)
+static int hpp__header_overhead_sys(struct perf_hpp_fmt *_fmt __maybe_unused,
+   struct perf_hpp *hpp)
 {
const char *fmt = symbol_conf.field_sep ? %s : %7s;
 
return scnprintf(hpp-buf, hpp-size, fmt, sys);
 }
 
-static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused)
+static int hpp__width_overhead_sys(struct perf_hpp_fmt *fmt

[PATCH 09/14] perf diff: Update perf diff documentation for multiple data comparison

2012-11-28 Thread Jiri Olsa
Updating perf diff documentation to include multiple perf data
files comparison.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Documentation/perf-diff.txt | 73 +-
 1 file changed, 64 insertions(+), 9 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt 
b/tools/perf/Documentation/perf-diff.txt
index 194f37d..ab5b79e 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -3,17 +3,17 @@ perf-diff(1)
 
 NAME
 
-perf-diff - Read two perf.data files and display the differential profile
+perf-diff - Read perf.data files and display the differential profile
 
 SYNOPSIS
 
 [verse]
-'perf diff' [oldfile] [newfile]
+'perf diff' [baseline file] [data file1] [[data file2] ... ]
 
 DESCRIPTION
 ---
-This command displays the performance difference amongst two perf.data files
-captured via perf record.
+This command displays the performance difference amongst two or more perf.data
+files captured via perf record.
 
 If no parameters are passed it will assume perf.data.old and perf.data.
 
@@ -91,6 +91,59 @@ OPTIONS
 --formula::
 Show formula for given computation.
 
+COMPARISON
+--
+The comparison is governed by the baseline file. The baseline perf.data
+file is iterated for samples. All other perf.data files specified on
+the command line are searched for the baseline sample pair. If the pair
+is found, specified computation is made and result is displayed.
+
+All samples from non-baseline perf.data files, that do not match any
+baseline entry, are displayed with empty space within baseline column
+and possible computation results (delta) in their related column.
+
+Example files samples:
+- file A with samples f1, f2, f3, f4,f6
+- file B with samples f2, f4, f5
+- file C with samples f1, f2, f5
+
+Example output:
+  x - computation takes place for pair
+  b - baseline sample percentage
+
+- perf diff A B C
+
+  baseline/A compute/B compute/C  samples
+  ---
+  bx  f1
+  b  x x  f2
+  b   f3
+  b  xf4
+  b   f6
+ x x  f5
+
+- perf diff B A C
+
+  baseline/B compute/A compute/C  samples
+  ---
+  b  x x  f2
+  b  xf4
+  bx  f5
+ x x  f1
+ xf3
+ xf6
+
+- perf diff C B A
+
+  baseline/C compute/B compute/A  samples
+  ---
+  bx  f1
+  b  x x  f2
+  b  xf5
+   x  f3
+ x x  f4
+   x  f6
+
 COMPARISON METHODS
 --
 delta
@@ -100,7 +153,7 @@ If specified the 'Delta' column is displayed with value 'd' 
computed as:
   d = A-period_percent - B-period_percent
 
 with:
-  - A/B being matching hist entry from first/second file specified
+  - A/B being matching hist entry from data/baseline file specified
 (or perf.data/perf.data.old) respectively.
 
   - period_percent being the % of the hist entry period value within
@@ -113,24 +166,26 @@ If specified the 'Ratio' column is displayed with value 
'r' computed as:
   r = A-period / B-period
 
 with:
-  - A/B being matching hist entry from first/second file specified
+  - A/B being matching hist entry from data/baseline file specified
 (or perf.data/perf.data.old) respectively.
 
   - period being the hist entry period value
 
-wdiff
-~
+wdiff:WEIGHT-B,WEIGHT-A
+~~~
 If specified the 'Weighted diff' column is displayed with value 'd' computed 
as:
 
d = B-period * WEIGHT-A - A-period * WEIGHT-B
 
-  - A/B being matching hist entry from first/second file specified
+  - A/B being matching hist entry from data/baseline file specified
 (or perf.data/perf.data.old) respectively.
 
   - period being the hist entry period value
 
   - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option
 behind ':' separator like '-c wdiff:1,2'.
+- WIEGHT-A being the weight of the data file
+- WIEGHT-B being the weight of the baseline data file
 
 SEE ALSO
 
-- 
1.7.11.7

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

[PATCH 11/14] perf diff: Making compute functions static

2012-11-28 Thread Jiri Olsa
All compute functions are now local to the diff command,
making them static.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 24 
 tools/perf/util/hist.h|  6 --
 2 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 9f4ef76..81f7529 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -233,7 +233,7 @@ static double get_period_percent(struct hist_entry *he, u64 
period)
return (period * 100.0) / total;
 }
 
-double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair)
+static double compute_delta(struct hist_entry *he, struct hist_entry *pair)
 {
double old_percent = get_period_percent(he, he-stat.period);
double new_percent = get_period_percent(pair, pair-stat.period);
@@ -243,7 +243,7 @@ double perf_diff__compute_delta(struct hist_entry *he, 
struct hist_entry *pair)
return pair-diff.period_ratio_delta;
 }
 
-double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry *pair)
+static double compute_ratio(struct hist_entry *he, struct hist_entry *pair)
 {
double old_period = he-stat.period ?: 1;
double new_period = pair-stat.period;
@@ -253,7 +253,7 @@ double perf_diff__compute_ratio(struct hist_entry *he, 
struct hist_entry *pair)
return pair-diff.period_ratio;
 }
 
-s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
+static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
 {
u64 old_period = he-stat.period;
u64 new_period = pair-stat.period;
@@ -295,8 +295,8 @@ static int formula_wdiff(struct hist_entry *he, struct 
hist_entry *pair,
  new_period, compute_wdiff_w1, old_period, compute_wdiff_w2);
 }
 
-int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair,
-  char *buf, size_t size)
+static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
+  char *buf, size_t size)
 {
switch (compute) {
case COMPUTE_DELTA:
@@ -457,13 +457,13 @@ static void __hists__precompute(struct hist_entry *he)
 
switch (compute) {
case COMPUTE_DELTA:
-   perf_diff__compute_delta(he, pair);
+   compute_delta(he, pair);
break;
case COMPUTE_RATIO:
-   perf_diff__compute_ratio(he, pair);
+   compute_ratio(he, pair);
break;
case COMPUTE_WEIGHTED_DIFF:
-   perf_diff__compute_wdiff(he, pair);
+   compute_wdiff(he, pair);
break;
default:
BUG_ON(1);
@@ -834,7 +834,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry 
*pair,
if (pair-diff.computed)
diff = pair-diff.period_ratio_delta;
else
-   diff = perf_diff__compute_delta(he, pair);
+   diff = compute_delta(he, pair);
 
if (fabs(diff) = 0.01)
scnprintf(buf, size, %+4.2F%%, diff);
@@ -844,7 +844,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry 
*pair,
if (pair-diff.computed)
ratio = pair-diff.period_ratio;
else
-   ratio = perf_diff__compute_ratio(he, pair);
+   ratio = compute_ratio(he, pair);
 
if (ratio  0.0)
scnprintf(buf, size, %14.6F, ratio);
@@ -854,7 +854,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry 
*pair,
if (pair-diff.computed)
wdiff = pair-diff.wdiff;
else
-   wdiff = perf_diff__compute_wdiff(he, pair);
+   wdiff = compute_wdiff(he, pair);
 
if (wdiff != 0)
scnprintf(buf, size, %14ld, wdiff);
@@ -868,7 +868,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry 
*pair,
break;
 
case PERF_HPP_DIFF__FORMULA:
-   perf_diff__formula(he, pair, buf, size);
+   formula_fprintf(he, pair, buf, size);
break;
 
case PERF_HPP_DIFF__PERIOD:
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index d4f19eb..e00b6b9 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -225,10 +225,4 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist 
*evlist __maybe_unused,
 #endif
 
 unsigned

[PATCH 12/14] perf diff: Display data file info ahead of the diff output

2012-11-28 Thread Jiri Olsa
Data files are referenced through the index of the file
on the command line. Adding list of data files for each
index to ease up navigation.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 81f7529..50e1ea3 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -632,6 +632,19 @@ static void hists__process(struct hists *hists)
hists__fprintf(hists, true, 0, 0, stdout);
 }
 
+static void data_fprintf(void)
+{
+   struct diff_data *d;
+   int i;
+
+   fprintf(stdout, # Data files:\n);
+
+   for_each_data(i, d)
+   fprintf(stdout, #  [%d] %s\n, d-idx, d-file);
+
+   fprintf(stdout, #\n);
+}
+
 static int data_process(void)
 {
struct perf_evlist *evlist_base = data[0].session-evlist;
@@ -662,6 +675,9 @@ static int data_process(void)
fprintf(stdout, %s# Event '%s'\n#\n, first ?  : \n,
perf_evsel__name(evsel_base));
 
+   if (data_cnt  2)
+   data_fprintf();
+
hists__process(evsel_base-hists);
 
first = false;
-- 
1.7.11.7

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


[PATCH 14/14] perf diff: Add generic order option for compute sorting

2012-11-28 Thread Jiri Olsa
Adding option 'o' to allow sorting based on the
input file number.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Documentation/perf-diff.txt |  4 +++
 tools/perf/builtin-diff.c  | 53 +++---
 2 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt 
b/tools/perf/Documentation/perf-diff.txt
index ab5b79e..1402e14 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -91,6 +91,10 @@ OPTIONS
 --formula::
 Show formula for given computation.
 
+-o::
+--order::
+   Specify compute sorting column number.
+
 COMPARISON
 --
 The comparison is governed by the baseline file. The baseline perf.data
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index b801d0c..1f98786 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -65,7 +65,7 @@ static bool show_displacement;
 static bool show_period;
 static bool show_formula;
 static bool show_baseline_only;
-static bool sort_compute;
+static unsigned int sort_compute;
 
 static s64 compute_wdiff_w1;
 static s64 compute_wdiff_w2;
@@ -191,13 +191,6 @@ static int setup_compute(const struct option *opt, const 
char *str,
return 0;
}
 
-   if (*str == '+') {
-   sort_compute = true;
-   cstr = (char *) ++str;
-   if (!*str)
-   return 0;
-   }
-
option = strchr(str, ':');
if (option) {
unsigned len = option++ - str;
@@ -533,31 +526,27 @@ static int64_t
 hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
int c)
 {
-   int i;
+   struct hist_entry **pairs_left  = left-pairs;
+   struct hist_entry **pairs_right = right-pairs;
+   struct hist_entry *p_right, *p_left;
+   static int64_t cmp;
 
-   for (i = 0; i  data_cnt; i++) {
-   struct hist_entry **pairs_left  = left-pairs;
-   struct hist_entry **pairs_right = right-pairs;
-   struct hist_entry *p_right, *p_left;
-   static int64_t cmp;
+   if (!pairs_left || !pairs_right)
+   return pairs_left ? -1 : 1;
 
-   if (!pairs_left || !pairs_right)
-   return pairs_right - pairs_left;
+   p_right = pairs_right[sort_compute];
+   p_left  = pairs_left[sort_compute];
 
-   p_right = pairs_right[i];
-   p_left  = pairs_left[i];
+   if (!p_left || !p_right)
+   return p_left ? -1 : 1;
 
-   if (!p_left || !p_right)
-   return p_right - p_left;
-
-   /*
-* If we differ, we are done, otherwise continue until all
-* is processed or we find a difference.
-*/
-   cmp = __hist_entry__cmp_compute(p_left, p_right, c);
-   if (cmp)
-   return cmp;
-   }
+   /*
+* If we differ, we are done, otherwise continue until all
+* is processed or we find a difference.
+*/
+   cmp = __hist_entry__cmp_compute(p_left, p_right, c);
+   if (cmp)
+   return cmp;
 
return 0;
 }
@@ -759,6 +748,7 @@ static const struct option options[] = {
   columns '.' is reserved.),
OPT_STRING(0, symfs, symbol_conf.symfs, directory,
Look for files with symbols relative to this directory),
+   OPT_UINTEGER('o', order, sort_compute, Specify compute sorting.),
OPT_END()
 };
 
@@ -1087,6 +1077,11 @@ static int data_init(int argc, const char **argv)
d-idx  = i;
}
 
+   if (sort_compute = (unsigned int) data_cnt) {
+   pr_err(Order option out of limit.\n);
+   return -EINVAL;
+   }
+
return 0;
 }
 
-- 
1.7.11.7

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


[PATCH 08/14] perf diff: Change diff command to work over multiple data files

2012-11-28 Thread Jiri Olsa
Adding diff command the flexibility to specify multiple data
files on input. If not input file is given the standard behaviour
stands and diff inspects 'perf.data' and 'perf.data.old' files.

Also changing the processing and output display for data files.

For 'perf diff A B' command:

  - the current way is to iterate over B data and display
A (baseline) data (symbol samples) only if found in B

  - this patch iterates over A (baseline) data and display
B data (symbol samples) only if found in A

For 'perf diff A B C' command, the diff now iterates the
A (baseline) data and display B and C data (symbol samples)
only if they found in A (baseline)

All other standard diff command computation features
(delta,ratio,wdiff) stays.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 663 ++
 tools/perf/ui/hist.c  | 242 -
 tools/perf/util/hist.c|   6 +-
 tools/perf/util/hist.h|   9 +-
 tools/perf/util/sort.h|  32 +--
 5 files changed, 560 insertions(+), 392 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 6361b55..9f4ef76 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -18,11 +18,49 @@
 #include util/util.h
 
 #include stdlib.h
+#include math.h
 
-static char const *input_old = perf.data.old,
- *input_new = perf.data;
-static char  diff__default_sort_order[] = dso,symbol;
-static bool  force;
+/* Diff command specific HPP columns. */
+enum {
+   PERF_HPP_DIFF__BASELINE,
+   PERF_HPP_DIFF__PERIOD,
+   PERF_HPP_DIFF__PERIOD_BASELINE,
+   PERF_HPP_DIFF__DELTA,
+   PERF_HPP_DIFF__RATIO,
+   PERF_HPP_DIFF__WEIGHTED_DIFF,
+   PERF_HPP_DIFF__DISPL,
+   PERF_HPP_DIFF__FORMULA,
+
+   PERF_HPP_DIFF__MAX_INDEX
+};
+
+struct diff_data__fmt {
+   struct perf_hpp_fmt fmt;
+   int idx;
+
+   char*header;
+   int  header_width;
+};
+
+struct diff_data {
+   struct perf_session *session;
+   const char  *file;
+   int  idx;
+
+   struct diff_data__fmtfmt[PERF_HPP_DIFF__MAX_INDEX];
+};
+
+static struct diff_data *data;
+static int data_cnt;
+
+#define for_each_data(i, d) \
+   for (i = 0, d = data[0]; i  data_cnt; i++, d = data[i])
+
+#define for_each_data_new(i, d) \
+   for (i = 1, d = data[1]; i  data_cnt; i++, d = data[i])
+
+static const char diff__default_sort_order[] = dso,symbol;
+static bool force;
 static bool show_displacement;
 static bool show_period;
 static bool show_formula;
@@ -39,12 +77,55 @@ enum {
COMPUTE_MAX,
 };
 
+static int compute_2_hpp[COMPUTE_MAX] = {
+   [COMPUTE_DELTA] = PERF_HPP_DIFF__DELTA,
+   [COMPUTE_RATIO] = PERF_HPP_DIFF__RATIO,
+   [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF,
+};
+
+
 const char *compute_names[COMPUTE_MAX] = {
[COMPUTE_DELTA] = delta,
[COMPUTE_RATIO] = ratio,
[COMPUTE_WEIGHTED_DIFF] = wdiff,
 };
 
+static struct header_column {
+   const char *name;
+   int width;
+} columns[PERF_HPP_DIFF__MAX_INDEX] = {
+   [PERF_HPP_DIFF__BASELINE] = {
+   .name = Baseline,
+   },
+   [PERF_HPP_DIFF__PERIOD] = {
+   .name = Period,
+   },
+   [PERF_HPP_DIFF__PERIOD_BASELINE] = {
+   .name = Base period,
+   },
+   [PERF_HPP_DIFF__DELTA] = {
+   .name  = Delta,
+   .width = 7,
+   },
+   [PERF_HPP_DIFF__RATIO] = {
+   .name  = Ratio,
+   .width = 14,
+   },
+   [PERF_HPP_DIFF__WEIGHTED_DIFF] = {
+   .name  = Weighted diff,
+   .width = 14,
+   },
+   [PERF_HPP_DIFF__DISPL] = {
+   .name = Displ,
+   },
+   [PERF_HPP_DIFF__FORMULA] = {
+   .name  = Formula,
+   .width = 70,
+   }
+};
+
+#define MAX_COL_WIDTH 70
+
 static int compute;
 
 static int setup_compute_opt_wdiff(char *opt)
@@ -146,7 +227,7 @@ static int setup_compute(const struct option *opt, const 
char *str,
return -EINVAL;
 }
 
-double perf_diff__period_percent(struct hist_entry *he, u64 period)
+static double get_period_percent(struct hist_entry *he, u64 period)
 {
u64 total = he-hists-stats.total_period;
return (period * 100.0) / total;
@@ -154,34 +235,34 @@ double perf_diff__period_percent(struct hist_entry *he, 
u64 period)
 
 double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair)
 {
-   double new_percent = perf_diff__period_percent(he, he

[PATCH 13/14] perf diff: Display zero calculation results

2012-11-28 Thread Jiri Olsa
Forcing zero calculation outputs to appear in final output,
so we can differ between zero output calculation result and
empty space for missing pair of baseline hist_entry.

Also skipping the compute and period output for dummy entries.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 24 +++-
 tools/perf/util/hist.c|  1 +
 tools/perf/util/sort.h|  3 +++
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 50e1ea3..b801d0c 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -779,13 +779,15 @@ static int hpp__color_baseline(struct perf_hpp_fmt *fmt 
__maybe_unused,
container_of(fmt, struct diff_data__fmt, fmt);
char pfmt[20] =  ;
 
-   if (percent) {
+   if (!he-dummy) {
scnprintf(pfmt, 20, %%%d.2f, dfmt-header_width - 1);
return percent_color_snprintf(hpp-buf, hpp-size,
  pfmt, percent);
} else
return scnprintf(hpp-buf, hpp-size, %*s,
 dfmt-header_width, pfmt);
+
+   return percent_color_snprintf(hpp-buf, hpp-size, pfmt, percent);
 }
 
 static int hpp__entry_baseline(struct perf_hpp_fmt *_fmt, struct perf_hpp *hpp,
@@ -797,7 +799,7 @@ static int hpp__entry_baseline(struct perf_hpp_fmt *_fmt, 
struct perf_hpp *hpp,
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
char buf[32] =  ;
 
-   if ((percent  he-pairs) || symbol_conf.field_sep)
+   if ((he-pairs) || symbol_conf.field_sep)
return scnprintf(hpp-buf, hpp-size, fmt, percent);
else
return scnprintf(hpp-buf, hpp-size, %*s,
@@ -828,7 +830,8 @@ hpp__entry_unpair(struct hist_entry *he, int idx, char 
*buf, size_t size)
 {
switch (idx) {
case PERF_HPP_DIFF__PERIOD_BASELINE:
-   scnprintf(buf, size, % PRIu64, he-stat.period);
+   if (!he-dummy)
+   scnprintf(buf, size, % PRIu64, he-stat.period);
break;
 
default:
@@ -852,28 +855,31 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry 
*pair,
else
diff = compute_delta(he, pair);
 
-   if (fabs(diff) = 0.01)
-   scnprintf(buf, size, %+4.2F%%, diff);
+   scnprintf(buf, size, %+4.2F%%, diff);
break;
 
case PERF_HPP_DIFF__RATIO:
+   if (he-dummy)
+   break;
+
if (pair-diff.computed)
ratio = pair-diff.period_ratio;
else
ratio = compute_ratio(he, pair);
 
-   if (ratio  0.0)
-   scnprintf(buf, size, %14.6F, ratio);
+   scnprintf(buf, size, %14.6F, ratio);
break;
 
case PERF_HPP_DIFF__WEIGHTED_DIFF:
+   if (he-dummy)
+   break;
+
if (pair-diff.computed)
wdiff = pair-diff.wdiff;
else
wdiff = compute_wdiff(he, pair);
 
-   if (wdiff != 0)
-   scnprintf(buf, size, %14ld, wdiff);
+   scnprintf(buf, size, %14ld, wdiff);
break;
 
case PERF_HPP_DIFF__DISPL:
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 25f94a4..531b5dc 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -745,6 +745,7 @@ static struct hist_entry *hists__add_dummy_entry(struct 
hists *hists,
rb_link_node(he-rb_node, parent, p);
rb_insert_color(he-rb_node, hists-entries);
hists__inc_nr_entries(hists, he);
+   he-dummy = true;
}
 out:
return he;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 377b144..0e06872 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -93,6 +93,9 @@ struct hist_entry {
unsigned long   position;
struct rb_root  sorted_chain;
 
+   /* Added by hists__add_dummy_entry via hists__link */
+   booldummy;
+
/* diff related */
union {
struct hist_entry   **pairs;
-- 
1.7.11.7

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


[PATCH 03/14] perf tool: Fix period symbol_conf.field_sep display

2012-11-28 Thread Jiri Olsa
Currently we don't properly display hist data with
symbol_conf.field_sep separator. We need to display
either space or separator.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/hist.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 5452960..20a4392 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -523,17 +523,13 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, 
struct hist_entry *he,
struct perf_hpp_fmt *fmt;
char *start = hpp-buf;
int ret;
-   bool first = true;
 
if (symbol_conf.exclude_other  !he-parent)
return 0;
 
perf_hpp__for_each_format(fmt) {
-   if (!sep || !first) {
-   ret = scnprintf(hpp-buf, hpp-size, %s, sep ?:   );
-   advance_hpp(hpp, ret);
-   first = false;
-   }
+   ret = scnprintf(hpp-buf, hpp-size, %s, sep ?:   );
+   advance_hpp(hpp, ret);
 
if (color  fmt-color)
ret = fmt-color(fmt, hpp, he);
-- 
1.7.11.7

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


[PATCH 05/14] perf diff: Change compute methods to work with pair directly

2012-11-28 Thread Jiri Olsa
Changing compute methods to operate over hist entry and its
pair directly. This makes the code more obvious and readable,
instead of all time checking for pair being != NULL.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 38 +-
 tools/perf/ui/hist.c  | 40 +---
 tools/perf/util/hist.h|  7 ---
 3 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 9fbbc01..342085a 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -146,47 +146,40 @@ static int setup_compute(const struct option *opt, const 
char *str,
return -EINVAL;
 }
 
-static double get_period_percent(struct hist_entry *he, u64 period)
+double perf_diff__period_percent(struct hist_entry *he, u64 period)
 {
u64 total = he-hists-stats.total_period;
return (period * 100.0) / total;
 }
 
-double perf_diff__compute_delta(struct hist_entry *he)
+double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
-   double new_percent = get_period_percent(he, he-stat.period);
-   double old_percent = pair ? get_period_percent(pair, pair-stat.period) 
: 0.0;
+   double new_percent = perf_diff__period_percent(he, he-stat.period);
+   double old_percent = perf_diff__period_percent(pair, pair-stat.period);
 
he-diff.period_ratio_delta = new_percent - old_percent;
he-diff.computed = true;
return he-diff.period_ratio_delta;
 }
 
-double perf_diff__compute_ratio(struct hist_entry *he)
+double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry *pair)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
double new_period = he-stat.period;
-   double old_period = pair ? pair-stat.period : 0;
+   double old_period = pair-stat.period;
 
he-diff.computed = true;
-   he-diff.period_ratio = pair ? (new_period / old_period) : 0;
+   he-diff.period_ratio = new_period / old_period;
return he-diff.period_ratio;
 }
 
-s64 perf_diff__compute_wdiff(struct hist_entry *he)
+s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
u64 new_period = he-stat.period;
-   u64 old_period = pair ? pair-stat.period : 0;
+   u64 old_period = pair-stat.period;
 
he-diff.computed = true;
-
-   if (!pair)
-   he-diff.wdiff = 0;
-   else
-   he-diff.wdiff = new_period * compute_wdiff_w2 -
-old_period * compute_wdiff_w1;
+   he-diff.wdiff = new_period * compute_wdiff_w2 -
+old_period * compute_wdiff_w1;
 
return he-diff.wdiff;
 }
@@ -385,18 +378,21 @@ static void hists__precompute(struct hists *hists)
 
while (next != NULL) {
struct hist_entry *he = rb_entry(next, struct hist_entry, 
rb_node);
+   struct hist_entry *pair = hist_entry__next_pair(he);
 
next = rb_next(he-rb_node);
+   if (!pair)
+   continue;
 
switch (compute) {
case COMPUTE_DELTA:
-   perf_diff__compute_delta(he);
+   perf_diff__compute_delta(he, pair);
break;
case COMPUTE_RATIO:
-   perf_diff__compute_ratio(he);
+   perf_diff__compute_ratio(he, pair);
break;
case COMPUTE_WEIGHTED_DIFF:
-   perf_diff__compute_wdiff(he);
+   perf_diff__compute_wdiff(he, pair);
break;
default:
BUG_ON(1);
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 20a4392..a64c7f9 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -314,14 +314,18 @@ static int hpp__width_delta(struct perf_hpp_fmt *fmt 
__maybe_unused,
 static int hpp__entry_delta(struct perf_hpp_fmt *_fmt __maybe_unused,
struct perf_hpp *hpp, struct hist_entry *he)
 {
+   struct hist_entry *pair = hist_entry__next_pair(he);
const char *fmt = symbol_conf.field_sep ? %s : %7.7s;
char buf[32] =  ;
-   double diff;
+   double diff = 0.0;
 
-   if (he-diff.computed)
-   diff = he-diff.period_ratio_delta;
-   else
-   diff = perf_diff__compute_delta(he);
+   if (pair) {
+   if (he-diff.computed

[PATCH 10/14] perf tool: Centralize default columns init in perf_hpp__init

2012-11-28 Thread Jiri Olsa
Now when diff command is separated from other standard outputs,
we can use perf_hpp__init to initialize all standard columns.

Moving PERF_HPP__OVERHEAD column init back to perf_hpp__init,
and removing extra enable calls.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c| 1 -
 tools/perf/ui/browsers/hists.c | 2 --
 tools/perf/ui/gtk/browser.c| 2 --
 tools/perf/ui/hist.c   | 2 ++
 tools/perf/ui/setup.c  | 1 -
 5 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5134acf..fc25100 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -692,7 +692,6 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
setup_browser(true);
else {
use_browser = 0;
-   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
perf_hpp__init();
}
 
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 4e06ba5..9463280 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -589,8 +589,6 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
 
 void hist_browser__init_hpp(void)
 {
-   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
-
perf_hpp__init();
 
perf_hpp__format[PERF_HPP__OVERHEAD].color =
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index c4aac7b..489a053 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -74,8 +74,6 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
 
 void perf_gtk__init_hpp(void)
 {
-   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
-
perf_hpp__init();
 
perf_hpp__format[PERF_HPP__OVERHEAD].color =
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index a004f57..bec5299 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -253,6 +253,8 @@ LIST_HEAD(perf_hpp__list);
 
 void perf_hpp__init(void)
 {
+   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
+
if (symbol_conf.show_cpu_utilization) {
perf_hpp__column_enable(PERF_HPP__OVERHEAD_SYS);
perf_hpp__column_enable(PERF_HPP__OVERHEAD_US);
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 166f13d..ebb4cc1 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -30,7 +30,6 @@ void setup_browser(bool fallback_to_pager)
if (fallback_to_pager)
setup_pager();
 
-   perf_hpp__column_enable(PERF_HPP__OVERHEAD);
perf_hpp__init();
break;
}
-- 
1.7.11.7

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


[PATCH 06/14] perf diff: Change formula methods to work with pair directly

2012-11-28 Thread Jiri Olsa
Changing formula methods to operate over hist entry and its
pair directly. This makes the code more obvious and readable,
instead of all time checking for pair being != NULL.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 35 +--
 tools/perf/ui/hist.c  |  5 -
 tools/perf/util/hist.h|  3 ++-
 3 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 342085a..d869029 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -184,13 +184,9 @@ s64 perf_diff__compute_wdiff(struct hist_entry *he, struct 
hist_entry *pair)
return he-diff.wdiff;
 }
 
-static int formula_delta(struct hist_entry *he, char *buf, size_t size)
+static int formula_delta(struct hist_entry *he, struct hist_entry *pair,
+char *buf, size_t size)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
-
-   if (!pair)
-   return -1;
-
return scnprintf(buf, size,
 (% PRIu64  * 100 / % PRIu64 ) - 
 (% PRIu64  * 100 / % PRIu64 ),
@@ -198,41 +194,36 @@ static int formula_delta(struct hist_entry *he, char 
*buf, size_t size)
  pair-stat.period, pair-hists-stats.total_period);
 }
 
-static int formula_ratio(struct hist_entry *he, char *buf, size_t size)
+static int formula_ratio(struct hist_entry *he, struct hist_entry *pair,
+char *buf, size_t size)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
double new_period = he-stat.period;
-   double old_period = pair ? pair-stat.period : 0;
-
-   if (!pair)
-   return -1;
+   double old_period = pair-stat.period;
 
return scnprintf(buf, size, %.0F / %.0F, new_period, old_period);
 }
 
-static int formula_wdiff(struct hist_entry *he, char *buf, size_t size)
+static int formula_wdiff(struct hist_entry *he, struct hist_entry *pair,
+char *buf, size_t size)
 {
-   struct hist_entry *pair = hist_entry__next_pair(he);
u64 new_period = he-stat.period;
-   u64 old_period = pair ? pair-stat.period : 0;
-
-   if (!pair)
-   return -1;
+   u64 old_period = pair-stat.period;
 
return scnprintf(buf, size,
  (% PRIu64  *  % PRId64 ) - (% PRIu64  *  % PRId64 
),
  new_period, compute_wdiff_w2, old_period, compute_wdiff_w1);
 }
 
-int perf_diff__formula(char *buf, size_t size, struct hist_entry *he)
+int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair,
+  char *buf, size_t size)
 {
switch (compute) {
case COMPUTE_DELTA:
-   return formula_delta(he, buf, size);
+   return formula_delta(he, pair, buf, size);
case COMPUTE_RATIO:
-   return formula_ratio(he, buf, size);
+   return formula_ratio(he, pair, buf, size);
case COMPUTE_WEIGHTED_DIFF:
-   return formula_wdiff(he, buf, size);
+   return formula_wdiff(he, pair, buf, size);
default:
BUG_ON(1);
}
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index a64c7f9..d6fdb00 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -446,10 +446,13 @@ static int hpp__width_formula(struct perf_hpp_fmt *fmt 
__maybe_unused,
 static int hpp__entry_formula(struct perf_hpp_fmt *_fmt __maybe_unused,
  struct perf_hpp *hpp, struct hist_entry *he)
 {
+   struct hist_entry *pair = hist_entry__next_pair(he);
const char *fmt = symbol_conf.field_sep ? %s : %-70s;
char buf[96] =  ;
 
-   perf_diff__formula(buf, sizeof(buf), he);
+   if (pair)
+   perf_diff__formula(he, pair, buf, sizeof(buf));
+
return scnprintf(hpp-buf, hpp-size, fmt, buf);
 }
 
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 53a1679..7f5cce8 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -231,6 +231,7 @@ unsigned int hists__sort_list_width(struct hists *self);
 double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry 
*pair);
 double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry 
*pair);
 s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair);
-int perf_diff__formula(char *buf, size_t size, struct hist_entry *he);
+int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair,
+  char *buf, size_t size);
 double perf_diff__period_percent(struct hist_entry *he, u64 period);
 #endif

[PATCH 07/14] perf diff: Add callback to hists__match/hists__link functions

2012-11-28 Thread Jiri Olsa
It's possible different users of hists__match/hists__link will need
specific processing of matching hists_entry data.

Adding callback to hists__match/hists__link functions to allow that.

Signed-off-by: Jiri Olsa jo...@redhat.com
Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c | 11 +--
 tools/perf/util/hist.c| 24 +---
 tools/perf/util/hist.h|  8 ++--
 3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index d869029..6361b55 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -472,14 +472,21 @@ static void hists__compute_resort(struct hists *hists)
hists-entries = tmp;
 }
 
+static int match_cb(struct hist_entry *a, struct hist_entry *b,
+   void *data __maybe_unused)
+{
+   hist__entry_add_pair(a, b);
+   return 0;
+}
+
 static void hists__process(struct hists *old, struct hists *new)
 {
-   hists__match(new, old);
+   hists__match(new, old, match_cb, NULL);
 
if (show_baseline_only)
hists__baseline_only(new);
else
-   hists__link(new, old);
+   hists__link(new, old, match_cb, NULL);
 
if (sort_compute) {
hists__precompute(new);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cb17e2a..0c5843b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -775,18 +775,24 @@ static struct hist_entry *hists__find_entry(struct hists 
*hists,
 /*
  * Look for pairs to link to the leader buckets (hist_entries):
  */
-void hists__match(struct hists *leader, struct hists *other)
+int hists__match(struct hists *leader, struct hists *other,
+hists__entry_cb cb, void *data)
 {
struct rb_node *nd;
struct hist_entry *pos, *pair;
+   int ret = 0;
 
-   for (nd = rb_first(leader-entries); nd; nd = rb_next(nd)) {
+   BUG_ON(!cb);
+
+   for (nd = rb_first(leader-entries); nd  !ret; nd = rb_next(nd)) {
pos  = rb_entry(nd, struct hist_entry, rb_node);
pair = hists__find_entry(other, pos);
 
if (pair)
-   hist__entry_add_pair(pos, pair);
+   ret = cb(pos, pair, data);
}
+
+   return ret;
 }
 
 /*
@@ -794,21 +800,25 @@ void hists__match(struct hists *leader, struct hists 
*other)
  * we find them, just add a dummy entry on the leader hists, with period=0,
  * nr_events=0, to serve as the list header.
  */
-int hists__link(struct hists *leader, struct hists *other)
+int hists__link(struct hists *leader, struct hists *other,
+   hists__entry_cb cb, void *data)
 {
struct rb_node *nd;
struct hist_entry *pos, *pair;
+   int ret = 0;
 
-   for (nd = rb_first(other-entries); nd; nd = rb_next(nd)) {
+   BUG_ON(!cb);
+
+   for (nd = rb_first(other-entries); nd  !ret; nd = rb_next(nd)) {
pos = rb_entry(nd, struct hist_entry, rb_node);
 
if (!hist_entry__has_pairs(pos)) {
pair = hists__add_dummy_entry(leader, pos);
if (pair == NULL)
return -1;
-   hist__entry_add_pair(pair, pos);
+   ret = cb(pos, pair, data);
}
}
 
-   return 0;
+   return ret;
 }
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 7f5cce8..eb4dc83 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -115,8 +115,12 @@ bool hists__new_col_len(struct hists *self, enum 
hist_column col, u16 len);
 void hists__reset_col_len(struct hists *hists);
 void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
 
-void hists__match(struct hists *leader, struct hists *other);
-int hists__link(struct hists *leader, struct hists *other);
+typedef int (hists__entry_cb)(struct hist_entry *a, struct hist_entry *b,
+ void *data);
+int hists__match(struct hists *leader, struct hists *other,
+hists__entry_cb cb, void *data);
+int hists__link(struct hists *leader, struct hists *other,
+   hists__entry_cb cb, void *data);
 
 struct perf_hpp {
char *buf;
-- 
1.7.11.7

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


[PATCH/RFC 00/14] perf, tool: Fix endian issues

2012-11-28 Thread Jiri Olsa
hi,
adding support to display diff for more than 2 perf.data files.
Sending as RFC, since the change touches lot of hists code,
so I might be breaking something I missed.. still testing.

Also it could colide with Namhyung changes for group report
wrt patches 7 and 8, where I changed the linking of matching
hists entries.

The doc was updated with info about current perf diff processing.

Attached patches:
  01/14 perf tool: Introduce perf_hpp__list for period related columns
  02/14 perf tool: Add struct perf_hpp_fmt into hpp callbacks
  03/14 perf tool: Fix period symbol_conf.field_sep display
  04/14 perf diff: Remove displacement from struct hist_entry_diff
  05/14 perf diff: Change compute methods to work with pair directly
  06/14 perf diff: Change formula methods to work with pair directly
  07/14 perf diff: Add callback to hists__match/hists__link functions
  08/14 perf diff: Change diff command to work over multiple data files
  09/14 perf diff: Update perf diff documentation for multiple data comparison
  10/14 perf tool: Centralize default columns init in perf_hpp__init
  11/14 perf diff: Making compute functions static
  12/14 perf diff: Display data file info ahead of the diff output
  13/14 perf diff: Display zero calculation results
  14/14 perf diff: Add generic order option for compute sorting

Example of multiple perf diff output:

  $ perf diff perf.data.[123456]
  # Event 'cycles:u'
  #
  # Data files:
  #  [0] perf.data.1
  #  [1] perf.data.2
  #  [2] perf.data.3
  #  [3] perf.data.4
  #  [4] perf.data.5
  #  [5] perf.data.6
  #
  # Baseline/0  Delta/1  Delta/2  Delta/3  Delta/4  Delta/5  Shared Object  
   Symbol
  # ..  ...  ...  ...  ...  ...  .  
.
  #
+73.05%  [kernel.kallsyms]  
[k] page_fault   
+26.16%  ld-2.15.so 
[.] _dl_next_ld_env_entry
 +15.40% ld-2.15.so 
[.] _dl_sysdep_start 
71.48%   -26.52% libc-2.15.so   
[.] __strcmp_sse2
27.69%   -1.65%-4.83%   -4.68%   ld-2.15.so 
[.] dl_main  
 0.82%   -0.05%   -0.34%   -0.15%   -0.13%   -0.03%  ld-2.15.so 
[.] _start   
 +39.15% libc-2.15.so   
[.] error_tail   
+73.18%  libc-2.15.so   
[.] __strcasecmp_l_sse2  
   +76.30%   libc-2.15.so   
[.] __stpcpy_sse2
  +76.46%libc-2.15.so   
[.] _IO_getline_info 

thanks,
jirka

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Documentation/perf-diff.txt |  77 --
 tools/perf/builtin-diff.c  | 747 
++---
 tools/perf/ui/browsers/hists.c |  22 +--
 tools/perf/ui/gtk/browser.c|  26 +---
 tools/perf/ui/hist.c   | 392 
++-
 tools/perf/ui/stdio/hist.c |  17 +--
 tools/perf/util/hist.c |  29 ++--
 tools/perf/util/hist.h |  42 ++---
 tools/perf/util/sort.h |  38 ++---
 9 files changed, 855 insertions(+), 535 deletions(-)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


<    1   2   3   4   5   6   7   8   9   10   >