Skip to contentSkip to conversation

perf report: Display CPU Measurement facility counter sets

PATCH Applied Thomas Richter 4 participants 18 messages Jan 17, 2019 – Jan 22, 2019 perf events

lore
Share & tools
lore
#0 lore raw

v2 cover perf report: Display CPU Measurement facility counter sets

The CPU Measurement facility for counters supports the extraction of complete counter sets via hardware instruction STCCTM (if available).

This patch set displays the counter sets in the perf report tool.

V1 --> V2
1. Repackage event decoding and create an s390 specific file util/s390-sample-raw.c. It decodes the counter sets and is located in the common tree to enable decoding on other platforms (x86) as well.
2. Patch 3 unchanged

Thomas Richter (3):
perf report: Display s390 diagnostic counter sets perf report: Display names in s390 diagnostic counter sets perf/report: s390 dump counter set data to file.

Signature · 1 line
2.14.3
#1 lore raw

PATCH v2 1/3 perf report: Display s390 diagnostic counter sets

On s390 the event bc000 (also named CF_DIAG) extracts the CPU Measurement Facility diagnostic counter sets and displays them as counter number and counter value pairs sorted by counter set number.

Output:
[root@s35lp76 perf]# ./perf report -D --stdio

[00000000] Counterset:0 Counters:6
Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94 Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460 Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
[0x000038] Counterset:1 Counters:2
Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
[0x000050] Counterset:2 Counters:16
Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000 Counter:002 Value:000000000000000000 Counter:003 Value:000000000000000000 Counter:004 Value:000000000000000000 Counter:005 Value:000000000000000000 Counter:006 Value:000000000000000000 Counter:007 Value:000000000000000000 Counter:008 Value:000000000000000000 Counter:009 Value:000000000000000000 Counter:010 Value:000000000000000000 Counter:011 Value:000000000000000000 Counter:012 Value:000000000000000000 Counter:013 Value:000000000000000000 Counter:014 Value:000000000000000000 Counter:015 Value:000000000000000000
[0x0000d8] Counterset:3 Counters:128
Counter:000 Value:0x000000000000020f Counter:001 Value:0x00000000000001d8 Counter:002 Value:0x000000000000d7fa Counter:003 Value:0x000000000000008b
...

The number in brackets is the offset into the raw data field of the sample.

New functions trace_event_sample_raw() and s390_sample_raw() are introduced in the code path to enable interpretation on non s390 platforms. This event bc000 attached raw data is generated only on s390 platform. Correct display on other platforms requires correct endianness handling.

---
 tools/perf/util/Build                    |   2 +
 tools/perf/util/s390-cpumcf-kernel.h     |  62 +++++++++++
 tools/perf/util/s390-sample-raw.c        | 172 +++++++++++++++++++++++++++++++
 tools/perf/util/session.c                |   2 +
 tools/perf/util/session.h                |   5 +
 tools/perf/util/trace-event-sample-raw.c |  30 ++++++
 6 files changed, 273 insertions(+)
 create mode 100644 tools/perf/util/s390-cpumcf-kernel.h
 create mode 100644 tools/perf/util/s390-sample-raw.c
 create mode 100644 tools/perf/util/trace-event-sample-raw.c
tools/perf/util/Build +2 -0
index af72be7f5b3b..d6a11099919c 100644
@@ -44,6 +44,8 @@ libperf-y += machine.o
 libperf-y += map.o
 libperf-y += pstack.o
 libperf-y += session.o
+libperf-y += trace-event-sample-raw.o
+libperf-y += s390-sample-raw.o
 libperf-$(CONFIG_TRACE) += syscalltbl.o
 libperf-y += ordered-events.o
 libperf-y += namespaces.o
tools/perf/util/s390-cpumcf-kernel.h new file +62 -0

62 lines not on this page · raw message

tools/perf/util/s390-sample-raw.c new file +172 -0

172 lines not on this page · raw message

tools/perf/util/session.c +2 -0
index 5456c84c7dd1..f0c71c6f670a 100644
@@ -1065,6 +1065,8 @@ static void dump_event(struct perf_evlist *evlist, union perf_event *event,
 	       file_offset, event->header.size, event->header.type);
 
 	trace_event(event);
+	if (event->header.type == PERF_RECORD_SAMPLE)
+		trace_event_sample_raw(evlist, event, sample);
 
 	if (sample)
 		perf_evlist__print_tstamp(evlist, event, sample);
tools/perf/util/session.h +5 -0
index d96eccd7d27f..dbd7256c82f6 100644
@@ -128,4 +128,9 @@ int perf_event__synthesize_id_index(struct perf_tool *tool,
 				    struct perf_evlist *evlist,
 				    struct machine *machine);
 
+void trace_event_sample_raw(struct perf_evlist *evlist __maybe_unused,
+			    union perf_event *event __maybe_unused,
+			    struct perf_sample *sample __maybe_unused);
+void s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
+		     struct perf_sample *sample);
 #endif /* __PERF_SESSION_H */
tools/perf/util/trace-event-sample-raw.c new file +30 -0
new file mode 100644
index 000000000000..622471a02267
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright IBM Corp. 2019
+ * Author(s): Thomas Richter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ * Architecture specific trace_event function. Save event's bc000 raw data
+ * to file. File name is aux.ctr.## where ## stands for the CPU number the
+ * sample was taken from.
+ */
+
+#include <string.h>
+
+#include "session.h"
+#include "evlist.h"
+
+/* Check platform the perf data file was created on and perform platform
+ * specific interpretation.
+ */
+void trace_event_sample_raw(struct perf_evlist *evlist, union perf_event *event,
+			    struct perf_sample *sample)
+{
+	const char *arch_pf = perf_env__arch(evlist->env);
+
+	if (arch_pf && !strcmp("s390", arch_pf))
+		s390_sample_raw(evlist, event, sample);
+}
Signature · 1 line
2.14.3
#2 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Em Thu, Jan 17, 2019 at 10:30:01AM +0100, Thomas Richter escreveu:

Quoted 4 lines

On s390 the event bc000 (also named CF_DIAG) extracts the CPU Measurement Facility diagnostic counter sets and displays them as counter number and counter value pairs sorted by counter set number.

Thanks for taking my comments into account, I did some changes, documented in the updated patch, that is at the end of this message, first my changes to your patch, the end result should be the same:

$ interdiff /wb/thomas.patch /wb/acme.patch
diff -u b/tools/perf/util/Build b/tools/perf/util/Build
--- b/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -44,7 +44,6 @@
 libperf-y += map.o
 libperf-y += pstack.o
 libperf-y += session.o
-libperf-y += trace-event-sample-raw.o
 libperf-y += s390-sample-raw.o
 libperf-$(CONFIG_TRACE) += syscalltbl.o
 libperf-y += ordered-events.o
diff -u b/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c
--- b/tools/perf/util/s390-sample-raw.c
+++ b/tools/perf/util/s390-sample-raw.c
@@ -150,8 +150,8 @@
  * its raw data.
  * The function is only invoked when the dump flag -D is set.
  */
-void s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
-		     struct perf_sample *sample)
+void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
+				  struct perf_sample *sample)
 {
 	struct perf_evsel *ev_bc000;
tools/perf/util/session.c +2 -2
diff -u b/tools/perf/util/session.c b/tools/perf/util/session.c
@@ -1065,8 +1065,8 @@
 	       file_offset, event->header.size, event->header.type);
 
 	trace_event(event);
-	if (event->header.type == PERF_RECORD_SAMPLE)
-		trace_event_sample_raw(evlist, event, sample);
+	if (event->header.type == PERF_RECORD_SAMPLE && evlist->trace_event_sample_raw)
+		evlist->trace_event_sample_raw(evlist, event, sample);
 
 	if (sample)
 		perf_evlist__print_tstamp(evlist, event, sample);

reverted:

tools/perf/util/session.h +0 -5
@@ -128,9 +128,4 @@
 				    struct perf_evlist *evlist,
 				    struct machine *machine);
 
-void trace_event_sample_raw(struct perf_evlist *evlist __maybe_unused,
-			    union perf_event *event __maybe_unused,
-			    struct perf_sample *sample __maybe_unused);
-void s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
-		     struct perf_sample *sample);
 #endif /* __PERF_SESSION_H */

reverted:

tools/perf/util/trace-event-sample-raw.c deleted +0 -30
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright IBM Corp. 2019
- * Author(s): Thomas Richter <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (version 2 only)
- * as published by the Free Software Foundation.
- *
- * Architecture specific trace_event function. Save event's bc000 raw data
- * to file. File name is aux.ctr.## where ## stands for the CPU number the
- * sample was taken from.
- */
-
-#include <string.h>
-
-#include "session.h"
-#include "evlist.h"
-
-/* Check platform the perf data file was created on and perform platform
- * specific interpretation.
- */
-void trace_event_sample_raw(struct perf_evlist *evlist, union perf_event *event,
-			    struct perf_sample *sample)
-{
-	const char *arch_pf = perf_env__arch(evlist->env);
-
-	if (arch_pf && !strcmp("s390", arch_pf))
-		s390_sample_raw(evlist, event, sample);
-}

only in patch2:
unchanged:

tools/perf/util/evlist.c +13 -0
@@ -41,6 +41,18 @@ int sigqueue(pid_t pid, int sig, const union sigval value);
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
 
+/*
+ * Check platform the perf data file was created on and perform platform
+ * specific interpretation.
+ */
+static void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist)
+{
+	const char *arch_pf = perf_env__arch(evlist->env);
+
+	if (arch_pf && !strcmp("s390", arch_pf))
+		evlist->trace_event_sample_raw = perf_evlist__s390_sample_raw;
+}
+
 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
 		       struct thread_map *threads)
 {
@@ -53,6 +65,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
 	fdarray__init(&evlist->pollfd, 64);
 	evlist->workload.pid = -1;
 	evlist->bkw_mmap_state = BKW_MMAP_NOTREADY;
+	perf_evlist__init_trace_event_sample_raw(evlist);
 }
 
 struct perf_evlist *perf_evlist__new(void)

only in patch2:
unchanged:

tools/perf/util/evlist.h +5 -0
@@ -49,6 +49,9 @@ struct perf_evlist {
 	struct perf_evsel *selected;
 	struct events_stats stats;
 	struct perf_env	*env;
+	void (*trace_event_sample_raw)(struct perf_evlist *evlist,
+				       union perf_event *event,
+				       struct perf_sample *sample);
 	u64		first_sample_time;
 	u64		last_sample_time;
 };
@@ -315,4 +318,6 @@ void perf_evlist__force_leader(struct perf_evlist *evlist);
 struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist,
 						 struct perf_evsel *evsel);
 
+void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
+				  struct perf_sample *sample);
 #endif /* __PERF_EVLIST_H */

only in patch2:
unchanged:

tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

---------------------------------------

And the updated patch:

$ cat /wb/acme.patch
commit b7dd95b7479ed6773c6dbec72e0b867a1cfd3765
Author: Thomas Richter <[email protected]>
Date:   Thu Jan 17 10:37:17 2019 -0300
    erf report: Display arch specific diagnostic counter sets, starting with s390
    
    On s390 the event bc000 (also named CF_DIAG) extracts the CPU
    Measurement Facility diagnostic counter sets and displays them as
    counter number and counter value pairs sorted by counter set number.
    
    Output:
     [root@s35lp76 perf]# ./perf report -D --stdio
    
     [00000000] Counterset:0 Counters:6
       Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94
       Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460
       Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
     [0x000038] Counterset:1 Counters:2
       Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
     [0x000050] Counterset:2 Counters:16
       Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000
       Counter:002 Value:000000000000000000 Counter:003 Value:000000000000000000
       Counter:004 Value:000000000000000000 Counter:005 Value:000000000000000000
       Counter:006 Value:000000000000000000 Counter:007 Value:000000000000000000
       Counter:008 Value:000000000000000000 Counter:009 Value:000000000000000000
       Counter:010 Value:000000000000000000 Counter:011 Value:000000000000000000
       Counter:012 Value:000000000000000000 Counter:013 Value:000000000000000000
       Counter:014 Value:000000000000000000 Counter:015 Value:000000000000000000
     [0x0000d8] Counterset:3 Counters:128
       Counter:000 Value:0x000000000000020f Counter:001 Value:0x00000000000001d8
       Counter:002 Value:0x000000000000d7fa Counter:003 Value:0x000000000000008b
       ...
    
    The number in brackets is the offset into the raw data field of the
    sample.
    
    New functions trace_event_sample_raw__init() and s390_sample_raw() are
    introduced in the code path to enable interpretation on non s390
    platforms. This event bc000 attached raw data is generated only on s390
    platform. Correct display on other platforms requires correct endianness
    handling.
    
    Committer notes:
    
    Added a init function that sets up a evlist function pointer to avoid
    repeated tests on evlist->env and calls to perf_env__name() that
    involves normalizing, etc, for each PERF_RECORD_SAMPLE.
    
    Removed needless __maybe_unused from the trace_event_raw()
    prototype in session.h, move it to be an static function in evlist.
    
    Reviewed-by: Hendrik Brueckner <[email protected]>
    Cc: Martin Schwidefsky <[email protected]>
    Cc: Heiko Carstens <[email protected]>
    Signed-off-by: Thomas Richter <[email protected]>
    Link: https://lkml.kernel.org/r/[email protected]
    Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
tools/perf/util/Build +1 -0
index af72be7f5b3b..5ff0087ba693 100644
@@ -44,6 +44,7 @@ libperf-y += machine.o
 libperf-y += map.o
 libperf-y += pstack.o
 libperf-y += session.o
+libperf-y += s390-sample-raw.o
 libperf-$(CONFIG_TRACE) += syscalltbl.o
 libperf-y += ordered-events.o
 libperf-y += namespaces.o
tools/perf/util/evlist.c +13 -0
index 8c902276d4b4..5f01bced3116 100644
@@ -41,6 +41,18 @@ int sigqueue(pid_t pid, int sig, const union sigval value);
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
 
+/*
+ * Check platform the perf data file was created on and perform platform
+ * specific interpretation.
+ */
+static void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist)
+{
+	const char *arch_pf = perf_env__arch(evlist->env);
+
+	if (arch_pf && !strcmp("s390", arch_pf))
+		evlist->trace_event_sample_raw = perf_evlist__s390_sample_raw;
+}
+
 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
 		       struct thread_map *threads)
 {
@@ -53,6 +65,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
 	fdarray__init(&evlist->pollfd, 64);
 	evlist->workload.pid = -1;
 	evlist->bkw_mmap_state = BKW_MMAP_NOTREADY;
+	perf_evlist__init_trace_event_sample_raw(evlist);
 }
 
 struct perf_evlist *perf_evlist__new(void)
tools/perf/util/evlist.h +5 -0
index 868294491194..18365b1f80b0 100644
@@ -49,6 +49,9 @@ struct perf_evlist {
 	struct perf_evsel *selected;
 	struct events_stats stats;
 	struct perf_env	*env;
+	void (*trace_event_sample_raw)(struct perf_evlist *evlist,
+				       union perf_event *event,
+				       struct perf_sample *sample);
 	u64		first_sample_time;
 	u64		last_sample_time;
 };
@@ -315,4 +318,6 @@ void perf_evlist__force_leader(struct perf_evlist *evlist);
 struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist,
 						 struct perf_evsel *evsel);
 
+void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, union perf_event *event,
+				  struct perf_sample *sample);
 #endif /* __PERF_EVLIST_H */
tools/perf/util/python-ext-sources +1 -0
index 7aa0ea64544e..aada3e69565b 100644
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c
tools/perf/util/s390-cpumcf-kernel.h new file +62 -0

62 lines not on this page · raw message

tools/perf/util/s390-sample-raw.c new file +172 -0

172 lines not on this page · raw message

tools/perf/util/session.c +2 -0
index d6f41611f504..379a54702ba9 100644
@@ -1065,6 +1065,8 @@ static void dump_event(struct perf_evlist *evlist, union perf_event *event,
 	       file_offset, event->header.size, event->header.type);
 
 	trace_event(event);
+	if (event->header.type == PERF_RECORD_SAMPLE && evlist->trace_event_sample_raw)
+		evlist->trace_event_sample_raw(evlist, event, sample);
 
 	if (sample)
 		perf_evlist__print_tstamp(evlist, event, sample);
author Tested-by Applied
#3 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Quoted 40 lines · Arnaldo Carvalho de Melo

erf report: Display arch specific diagnostic counter sets, starting with s390

    On s390 the event bc000 (also named CF_DIAG) extracts the CPU
    Measurement Facility diagnostic counter sets and displays them as
    counter number and counter value pairs sorted by counter set number.
    
    Output:
     [root@s35lp76 perf]# ./perf report -D --stdio
    
     [00000000] Counterset:0 Counters:6
       Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94
       Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460
       Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
     [0x000038] Counterset:1 Counters:2
       Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
     [0x000050] Counterset:2 Counters:16
       Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000
       Counter:002 Value:000000000000000000 Counter:003 Value:000000000000000000
       Counter:004 Value:000000000000000000 Counter:005 Value:000000000000000000
       Counter:006 Value:000000000000000000 Counter:007 Value:000000000000000000
       Counter:008 Value:000000000000000000 Counter:009 Value:000000000000000000
       Counter:010 Value:000000000000000000 Counter:011 Value:000000000000000000
       Counter:012 Value:000000000000000000 Counter:013 Value:000000000000000000
       Counter:014 Value:000000000000000000 Counter:015 Value:000000000000000000
     [0x0000d8] Counterset:3 Counters:128
       Counter:000 Value:0x000000000000020f Counter:001 Value:0x00000000000001d8
       Counter:002 Value:0x000000000000d7fa Counter:003 Value:0x000000000000008b
       ...
    
    The number in brackets is the offset into the raw data field of the
    sample.
    
    New functions trace_event_sample_raw__init() and s390_sample_raw() are
    introduced in the code path to enable interpretation on non s390
    platforms. This event bc000 attached raw data is generated only on s390
    platform. Correct display on other platforms requires correct endianness
    handling.
    
    Committer notes:
Quoted 8 lines
    Added a init function that sets up a evlist function pointer to avoid
    repeated tests on evlist->env and calls to perf_env__name() that
    involves normalizing, etc, for each PERF_RECORD_SAMPLE.
    
    Removed needless __maybe_unused from the trace_event_raw()
    prototype in session.h, move it to be an static function in evlist.
    
    Reviewed-by: Hendrik Brueckner <[email protected]>

I have applied your changed patch. Works great. Thanks a lot.

Signature · 5 lines
Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany
--
Vorsitzende des Aufsichtsrats: Martina Koederitz 
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294
#4 lore raw

[tip:perf/core] perf report: Display arch specific diagnostic counter sets, starting with s390

perf report: Display arch specific diagnostic counter sets, starting with s390
Commit-ID:  93115d32e8666614f3578601a0b7b3f4914509f4
Gitweb:     https://git.kernel.org/tip/93115d32e8666614f3578601a0b7b3f4914509f4
Author:     Thomas Richter <[email protected]>
AuthorDate: Thu, 17 Jan 2019 10:37:17 -0300
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 21 Jan 2019 17:00:48 -0300

perf report: Display arch specific diagnostic counter sets, starting with s390

On s390 the event bc000 (also named CF_DIAG) extracts the CPU Measurement Facility diagnostic counter sets and displays them as counter number and counter value pairs sorted by counter set number.

Output:
[root@s35lp76 perf]# ./perf report -D --stdio

[00000000] Counterset:0 Counters:6
Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94 Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460 Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
[0x000038] Counterset:1 Counters:2
Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
[0x000050] Counterset:2 Counters:16
Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000 Counter:002 Value:000000000000000000 Counter:003 Value:000000000000000000 Counter:004 Value:000000000000000000 Counter:005 Value:000000000000000000 Counter:006 Value:000000000000000000 Counter:007 Value:000000000000000000 Counter:008 Value:000000000000000000 Counter:009 Value:000000000000000000 Counter:010 Value:000000000000000000 Counter:011 Value:000000000000000000 Counter:012 Value:000000000000000000 Counter:013 Value:000000000000000000 Counter:014 Value:000000000000000000 Counter:015 Value:000000000000000000
[0x0000d8] Counterset:3 Counters:128
Counter:000 Value:0x000000000000020f Counter:001 Value:0x00000000000001d8 Counter:002 Value:0x000000000000d7fa Counter:003 Value:0x000000000000008b
...

The number in brackets is the offset into the raw data field of the sample.

New functions trace_event_sample_raw__init() and s390_sample_raw() are introduced in the code path to enable interpretation on non s390 platforms. This event bc000 attached raw data is generated only on s390 platform. Correct display on other platforms requires correct endianness handling.

Committer notes:

Added a init function that sets up a evlist function pointer to avoid repeated tests on evlist->env and calls to perf_env__name() that involves normalizing, etc, for each PERF_RECORD_SAMPLE.

Removed needless __maybe_unused from the trace_event_raw() prototype in session.h, move it to be an static function in evlist.

The 'offset' variable is a size_t, not an u64, fix it to avoid this on some arches:

CC /tmp/build/perf/util/s390-sample-raw.o
util/s390-sample-raw.c: In function 's390_cpumcfdg_testctr':
util/s390-sample-raw.c:77:4: error: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'size_t' [-Werror=format=]
pr_err("Invalid counter set entry at %#" PRIx64 "\n",
^
cc1: all warnings being treated as errors

---
 tools/perf/util/Build                |   2 +
 tools/perf/util/evlist.h             |   4 +-
 tools/perf/util/s390-cpumcf-kernel.h |  62 +++++++++++++
 tools/perf/util/s390-sample-raw.c    | 173 +++++++++++++++++++++++++++++++++++
 tools/perf/util/sample-raw.c         |  18 ++++
 tools/perf/util/sample-raw.h         |  14 +++
 tools/perf/util/session.c            |   5 +
 7 files changed, 277 insertions(+), 1 deletion(-)
tools/perf/util/Build +2 -0
index af72be7f5b3b..3ad6a800948d 100644
@@ -44,6 +44,8 @@ libperf-y += machine.o
 libperf-y += map.o
 libperf-y += pstack.o
 libperf-y += session.o
+libperf-y += sample-raw.o
+libperf-y += s390-sample-raw.o
 libperf-$(CONFIG_TRACE) += syscalltbl.o
 libperf-y += ordered-events.o
 libperf-y += namespaces.o
tools/perf/util/evlist.h +3 -1
index 868294491194..00ab43c6dd15 100644
@@ -49,6 +49,9 @@ struct perf_evlist {
 	struct perf_evsel *selected;
 	struct events_stats stats;
 	struct perf_env	*env;
+	void (*trace_event_sample_raw)(struct perf_evlist *evlist,
+				       union perf_event *event,
+				       struct perf_sample *sample);
 	u64		first_sample_time;
 	u64		last_sample_time;
 };
@@ -314,5 +317,4 @@ void perf_evlist__force_leader(struct perf_evlist *evlist);
 
 struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist,
 						 struct perf_evsel *evsel);
-
 #endif /* __PERF_EVLIST_H */
tools/perf/util/s390-cpumcf-kernel.h new file +62 -0

62 lines not on this page · raw message

tools/perf/util/s390-sample-raw.c new file +173 -0

173 lines not on this page · raw message

tools/perf/util/sample-raw.c new file +18 -0
new file mode 100644
index 000000000000..c21e1311fb0f
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <string.h>
+#include "evlist.h"
+#include "env.h"
+#include "sample-raw.h"
+
+/*
+ * Check platform the perf data file was created on and perform platform
+ * specific interpretation.
+ */
+void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist)
+{
+	const char *arch_pf = perf_env__arch(evlist->env);
+
+	if (arch_pf && !strcmp("s390", arch_pf))
+		evlist->trace_event_sample_raw = perf_evlist__s390_sample_raw;
+}
tools/perf/util/sample-raw.h new file +14 -0
new file mode 100644
index 000000000000..95d445c87e93
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SAMPLE_RAW_H
+#define __SAMPLE_RAW_H 1
+
+struct perf_evlist;
+union perf_event;
+struct perf_sample;
+
+void perf_evlist__s390_sample_raw(struct perf_evlist *evlist,
+				  union perf_event *event,
+				  struct perf_sample *sample);
+
+void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist);
+#endif /* __PERF_EVLIST_H */
tools/perf/util/session.c +5 -0
index d6f41611f504..b26bc9c54200 100644
@@ -23,6 +23,7 @@
 #include "auxtrace.h"
 #include "thread.h"
 #include "thread-stack.h"
+#include "sample-raw.h"
 #include "stat.h"
 #include "arch/common.h"
 
@@ -147,6 +148,8 @@ struct perf_session *perf_session__new(struct perf_data *data,
 				perf_session__set_id_hdr_size(session);
 				perf_session__set_comm_exec(session);
 			}
+
+			perf_evlist__init_trace_event_sample_raw(session->evlist);
 		}
 	} else  {
 		session->machines.host.env = &perf_env;
@@ -1065,6 +1068,8 @@ static void dump_event(struct perf_evlist *evlist, union perf_event *event,
 	       file_offset, event->header.size, event->header.type);
 
 	trace_event(event);
+	if (event->header.type == PERF_RECORD_SAMPLE && evlist->trace_event_sample_raw)
+		evlist->trace_event_sample_raw(evlist, event, sample);
 
 	if (sample)
 		perf_evlist__print_tstamp(evlist, event, sample);
#5 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

In reply to Arnaldo Carvalho de Melo

On Thu, Jan 17, 2019 at 11:00:53AM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

changelog doesn't say anything about python related change

jirka

#6 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Quoted 18 lines · Jiri Olsa

On Thu, Jan 17, 2019 at 11:00:53AM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 6 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Could you please check if code in here works for you:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/s390

if it works, I'll post it

thanks,
jirka

author Tested-by
#7 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Quoted 30 lines · Jiri Olsa
Quoted 18 lines · Jiri Olsa

On Thu, Jan 17, 2019 at 11:00:53AM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 6 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Quoted 9 lines

Could you please check if code in here works for you:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/s390

if it works, I'll post it

thanks,
jirka

I downloaded your repository and checked out branch perf/s390. It works nicely, you have my tested by:
-

PS: This looks very similar to my version 1 submitted around Jan 11th. Arnaldo wanted a rework to be able to get these counter values on non-s390 platforms, that why we came up with version 2(which unfortunately broke the perf.so python module).

PS2: This was my first encounter to python and I played around a bit to include the necessary modules to get rid of the undefined warning. However this ended up in a larger list of C files to include and stopped at modules
1. util/pmu.c which refers to symbol perf_buf_in which is a FILE pointer used by some yacc input file.
2. perf_config_bool() which is located in util/config.c and emits a compile error when included in the util/python-ext-sources file for python/perf.so module.

So I think this road is a dead end.

Thanks for fixing this.

Signature · 5 lines
Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany
--
Vorsitzende des Aufsichtsrats: Martina Koederitz 
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294
#8 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

In reply to Jiri Olsa

Em Mon, Jan 21, 2019 at 02:13:36PM +0100, Jiri Olsa escreveu:

Quoted 24 lines · Jiri Olsa
Quoted 23 lines · Arnaldo Carvalho de Melo

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

Quoted 5 lines
Quoted 1 line

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Nope, I explicitely asked him to build that code for all arches, as we want to process s390 perf.data files on a x86 or arm or any other arch.

I stumbled on this as well, I think the way to go is to get the color_fprintf bits in a separate object to avoid dragging more stuff to the perf binding set of objects and then add that to the python binding.

Quoted 8 lines

Could you please check if code in here works for you:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/s390

if it works, I'll post it

thanks,
jirka

Signature · 1 line
- Arnaldo
#9 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Quoted 25 lines · Arnaldo Carvalho de Melo

Em Mon, Jan 21, 2019 at 02:13:36PM +0100, Jiri Olsa escreveu:

Quoted 24 lines · Jiri Olsa
Quoted 23 lines · Arnaldo Carvalho de Melo

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

Quoted 9 lines
Quoted 5 lines
Quoted 1 line

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Nope, I explicitely asked him to build that code for all arches, as we want to process s390 perf.data files on a x86 or arm or any other arch.

aah, so this actualy works over the s390 perf archive data on x86 host?

I missed that in the original conversation, sry for noise

jirka

Quoted 16 lines

I stumbled on this as well, I think the way to go is to get the color_fprintf bits in a separate object to avoid dragging more stuff to the perf binding set of objects and then add that to the python binding.

Quoted 8 lines

Could you please check if code in here works for you:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/s390

if it works, I'll post it

thanks,
jirka

Signature · 1 line
- Arnaldo
#10 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

Em Mon, Jan 21, 2019 at 07:34:37PM +0100, Jiri Olsa escreveu:

Quoted 32 lines · Arnaldo Carvalho de Melo
Quoted 31 lines

Em Mon, Jan 21, 2019 at 02:13:36PM +0100, Jiri Olsa escreveu:

Quoted 29 lines · Jiri Olsa
Quoted 18 lines · Arnaldo Carvalho de Melo

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 6 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Quoted 7 lines
Quoted 3 lines

Nope, I explicitely asked him to build that code for all arches, as we want to process s390 perf.data files on a x86 or arm or any other arch.

aah, so this actualy works over the s390 perf archive data on x86 host?

I missed that in the original conversation, sry for noise

np, I fixed my mistake by making this be done on perf_session__new(), right after creating the evlist, this way these arch specific bits, needed only for dumping the raw sample, do not get dragged via evlist.c into the perf binding :-)

- Arnaldo

Quoted 18 lines

jirka

Quoted 16 lines

I stumbled on this as well, I think the way to go is to get the color_fprintf bits in a separate object to avoid dragging more stuff to the perf binding set of objects and then add that to the python binding.

Quoted 8 lines

Could you please check if code in here works for you:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/s390

if it works, I'll post it

thanks,
jirka

Signature · 1 line
- Arnaldo
Signature · 1 line
- Arnaldo
#11 lore raw

Re: [PATCHv2 1/3] perf report: Display s390 diagnostic counter sets

In reply to Arnaldo Carvalho de Melo

Em Mon, Jan 21, 2019 at 11:17:48AM -0300, Arnaldo Carvalho de Melo escreveu:

Quoted 31 lines

Em Mon, Jan 21, 2019 at 02:13:36PM +0100, Jiri Olsa escreveu:

Quoted 24 lines · Jiri Olsa
Quoted 23 lines · Arnaldo Carvalho de Melo

SNIP

tools/perf/util/python-ext-sources util/parse-branch-options.c · line 31

Quoted 10 lines
tools/perf/util/python-ext-sources +1 -0
@@ -25,6 +25,7 @@ util/parse-branch-options.c
 util/rblist.c
 util/counts.c
 util/print_binary.c
+util/s390-sample-raw.c
 util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c

hi,
this change breaks the python module:

Quoted 1 line
Quoted 1 line
Quoted 1 line

import perf

Traceback (most recent call last):

    File "<stdin>", line 1, in <module>

ImportError: ./perf.so: undefined symbol: color_fprintf

Quoted 5 lines
Quoted 1 line

changelog doesn't say anything about python related change

I made some chenages and movedthat raw sample code under s390.. which cured the python module, but I haven't tested it on s390.

Quoted 6 lines

Nope, I explicitely asked him to build that code for all arches, as we want to process s390 perf.data files on a x86 or arm or any other arch.

I stumbled on this as well, I think the way to go is to get the color_fprintf bits in a separate object to avoid dragging more stuff to the perf binding set of objects and then add that to the python binding.

So I changed it so that the init is done in perf_session__new(), and session.c isn't linked into the python binding, so no need to drag the s390 specific stuff that drags pmu.c, color.c, etc into the python binding.

Should be equivalent to the previous patch, but without breaking the python binding,

- Arnaldo

commit a57dad3354e18f04d0ef198771954c24ad6aed49

Author: Thomas Richter <[email protected]>
Date:   Thu Jan 17 10:37:17 2019 -0300
    perf report: Display arch specific diagnostic counter sets, starting with s390
    
    On s390 the event bc000 (also named CF_DIAG) extracts the CPU
    Measurement Facility diagnostic counter sets and displays them as
    counter number and counter value pairs sorted by counter set number.
    
    Output:
     [root@s35lp76 perf]# ./perf report -D --stdio
    
     [00000000] Counterset:0 Counters:6
       Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94
       Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460
       Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
     [0x000038] Counterset:1 Counters:2
       Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
     [0x000050] Counterset:2 Counters:16
       Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000
       Counter:002 Value:000000000000000000 Counter:003 Value:000000000000000000
       Counter:004 Value:000000000000000000 Counter:005 Value:000000000000000000
       Counter:006 Value:000000000000000000 Counter:007 Value:000000000000000000
       Counter:008 Value:000000000000000000 Counter:009 Value:000000000000000000
       Counter:010 Value:000000000000000000 Counter:011 Value:000000000000000000
       Counter:012 Value:000000000000000000 Counter:013 Value:000000000000000000
       Counter:014 Value:000000000000000000 Counter:015 Value:000000000000000000
     [0x0000d8] Counterset:3 Counters:128
       Counter:000 Value:0x000000000000020f Counter:001 Value:0x00000000000001d8
       Counter:002 Value:0x000000000000d7fa Counter:003 Value:0x000000000000008b
       ...
    
    The number in brackets is the offset into the raw data field of the
    sample.
    
    New functions trace_event_sample_raw__init() and s390_sample_raw() are
    introduced in the code path to enable interpretation on non s390
    platforms. This event bc000 attached raw data is generated only on s390
    platform. Correct display on other platforms requires correct endianness
    handling.
    
    Committer notes:
    
    Added a init function that sets up a evlist function pointer to avoid
    repeated tests on evlist->env and calls to perf_env__name() that
    involves normalizing, etc, for each PERF_RECORD_SAMPLE.
    
    Removed needless __maybe_unused from the trace_event_raw()
    prototype in session.h, move it to be an static function in evlist.
    
    Signed-off-by: Thomas Richter <[email protected]>
    Reviewed-by: Hendrik Brueckner <[email protected]>
    Link: https://lkml.kernel.org/r/[email protected]
    Cc: Martin Schwidefsky <[email protected]>
    Cc: Heiko Carstens <[email protected]>
    Link: https://lkml.kernel.org/n/[email protected]
    Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
tools/perf/util/Build +2 -0
index af72be7f5b3b..3ad6a800948d 100644
@@ -44,6 +44,8 @@ libperf-y += machine.o
 libperf-y += map.o
 libperf-y += pstack.o
 libperf-y += session.o
+libperf-y += sample-raw.o
+libperf-y += s390-sample-raw.o
 libperf-$(CONFIG_TRACE) += syscalltbl.o
 libperf-y += ordered-events.o
 libperf-y += namespaces.o
tools/perf/util/evlist.h +3 -1
index 868294491194..00ab43c6dd15 100644
@@ -49,6 +49,9 @@ struct perf_evlist {
 	struct perf_evsel *selected;
 	struct events_stats stats;
 	struct perf_env	*env;
+	void (*trace_event_sample_raw)(struct perf_evlist *evlist,
+				       union perf_event *event,
+				       struct perf_sample *sample);
 	u64		first_sample_time;
 	u64		last_sample_time;
 };
@@ -314,5 +317,4 @@ void perf_evlist__force_leader(struct perf_evlist *evlist);
 
 struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist,
 						 struct perf_evsel *evsel);
-
 #endif /* __PERF_EVLIST_H */
tools/perf/util/s390-cpumcf-kernel.h new file +62 -0

62 lines not on this page · raw message

tools/perf/util/s390-sample-raw.c new file +173 -0

173 lines not on this page · raw message

tools/perf/util/sample-raw.c new file +18 -0
new file mode 100644
index 000000000000..c21e1311fb0f
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <string.h>
+#include "evlist.h"
+#include "env.h"
+#include "sample-raw.h"
+
+/*
+ * Check platform the perf data file was created on and perform platform
+ * specific interpretation.
+ */
+void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist)
+{
+	const char *arch_pf = perf_env__arch(evlist->env);
+
+	if (arch_pf && !strcmp("s390", arch_pf))
+		evlist->trace_event_sample_raw = perf_evlist__s390_sample_raw;
+}
tools/perf/util/sample-raw.h new file +14 -0
new file mode 100644
index 000000000000..95d445c87e93
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SAMPLE_RAW_H
+#define __SAMPLE_RAW_H 1
+
+struct perf_evlist;
+union perf_event;
+struct perf_sample;
+
+void perf_evlist__s390_sample_raw(struct perf_evlist *evlist,
+				  union perf_event *event,
+				  struct perf_sample *sample);
+
+void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist);
+#endif /* __PERF_EVLIST_H */
tools/perf/util/session.c +5 -0
index d6f41611f504..b26bc9c54200 100644
@@ -23,6 +23,7 @@
 #include "auxtrace.h"
 #include "thread.h"
 #include "thread-stack.h"
+#include "sample-raw.h"
 #include "stat.h"
 #include "arch/common.h"
 
@@ -147,6 +148,8 @@ struct perf_session *perf_session__new(struct perf_data *data,
 				perf_session__set_id_hdr_size(session);
 				perf_session__set_comm_exec(session);
 			}
+
+			perf_evlist__init_trace_event_sample_raw(session->evlist);
 		}
 	} else  {
 		session->machines.host.env = &perf_env;
@@ -1065,6 +1068,8 @@ static void dump_event(struct perf_evlist *evlist, union perf_event *event,
 	       file_offset, event->header.size, event->header.type);
 
 	trace_event(event);
+	if (event->header.type == PERF_RECORD_SAMPLE && evlist->trace_event_sample_raw)
+		evlist->trace_event_sample_raw(evlist, event, sample);
 
 	if (sample)
 		perf_evlist__print_tstamp(evlist, event, sample);
#12 lore raw

PATCH v2 2/3 perf report: Display names in s390 diagnostic counter sets

In reply to Thomas Richter

On s390 the CPU Measurement Facility diagnostic counter sets are displayed by counter number and value. Add the logical counter name in the output (if it is available). Otherwise "unknown" is shown.

Output before:
[root@s35lp76 perf]# ./perf report -D --stdio
[00000000] Counterset:0 Counters:6
Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94 Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460 Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
[0x000038] Counterset:1 Counters:2
Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
[0x000050] Counterset:2 Counters:16
Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000

Output after:

    [root@s35lp76 perf]# ./perf report -D --stdio

[00000000] Counterset:0 Counters:6

     Counter:000 cpu_cycles Value:0x000000000085ec36
     Counter:001 instructions Value:0x0000000000796c94
     Counter:002 l1i_dir_writes Value:0x0000000000005ada
     Counter:003 l1i_penalty_cycles Value:0x0000000000092460
     Counter:004 l1d_dir_writes Value:0x0000000000006073
     Counter:005 l1d_penalty_cycles Value:0x00000000001a9a73
 [0x000038] Counterset:1 Counters:2
     Counter:000 problem_state_cpu_cycles Value:0x000000000007c59f
     Counter:001 problem_state_instructions Value:0x000000000002fad6
 [0x000050] Counterset:2 Counters:16
     Counter:000 prng_functions Value:000000000000000000
---
 tools/perf/util/s390-sample-raw.c | 59 +++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 5 deletions(-)
tools/perf/util/s390-sample-raw.c +54 -5
index ae16c38ce296..73797bda919d 100644
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "color.h"
 #include "s390-cpumcf-kernel.h"
+#include "pmu-events/pmu-events.h"
 
 static size_t ctrset_size(struct cf_ctrset_entry *set)
 {
@@ -111,14 +112,61 @@ static void s390_cpumcfdg_dumptrail(const char *color, size_t offset,
 		      te.tod_base, te.mach_type);
 }
 
+/* Return starting number of a counter set */
+static int get_counterset_start(int setnr)
+{
+	switch (setnr) {
+	case CPUMF_CTR_SET_BASIC:		/* Basic counter set */
+		return 0;
+	case CPUMF_CTR_SET_USER:		/* Problem state counter set */
+		return 32;
+	case CPUMF_CTR_SET_CRYPTO:		/* Crypto counter set */
+		return 64;
+	case CPUMF_CTR_SET_EXT:			/* Extended counter set */
+		return 128;
+	case CPUMF_CTR_SET_MT_DIAG:		/* Diagnostic counter set */
+		return 448;
+	default:
+		return -1;
+	}
+}
+
+/* Scan the PMU table and extract the logical name of a counter from the
+ * PMU events table. Input is the counter set and counter number with in the
+ * set. Construct the event number and use this as key. If they match return
+ * the name of this counter.
+ * If no match is found a NULL pointer is returned.
+ */
+static const char *get_counter_name(int set, int nr, struct pmu_events_map *map)
+{
+	int rc, event_nr, wanted = get_counterset_start(set) + nr;
+
+	if (map) {
+		struct pmu_event *evp = map->table;
+
+		for (; evp->name || evp->event || evp->desc; ++evp) {
+			if (evp->name == NULL || evp->event == NULL)
+				continue;
+			rc = sscanf(evp->event, "event=%x", &event_nr);
+			if (rc == 1 && event_nr == wanted)
+				return evp->name;
+		}
+	}
+	return NULL;
+}
+
 static void s390_cpumcfdg_dump(struct perf_sample *sample)
 {
 	size_t i, len = sample->raw_size, offset = 0;
 	unsigned char *buf = sample->raw_data;
 	const char *color = PERF_COLOR_BLUE;
 	struct cf_ctrset_entry *cep, ce;
+	struct pmu_events_map *map;
+	struct perf_pmu pmu;
 	u64 *p;
 
+	memset(&pmu, 0, sizeof(pmu));
+	map = perf_pmu__find_map(&pmu);
 	while (offset < len) {
 		cep = (struct cf_ctrset_entry *)(buf + offset);
 
@@ -135,12 +183,13 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample)
 
 		color_fprintf(stdout, color, "    [%#08zx] Counterset:%d"
 			      " Counters:%d\n", offset, ce.set, ce.ctr);
-		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; i += 2, p += 2)
+		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) {
+			const char *ev_name = get_counter_name(ce.set, i, map);
+
 			color_fprintf(stdout, color,
-				      "\tCounter:%03d Value:%#018lx"
-				      " Counter:%03d Value:%#018lx\n",
-				      i, be64_to_cpu(*p),
-				      i + 1, be64_to_cpu(*(p + 1)));
+				      "\tCounter:%03d %s Value:%#018lx\n", i,
+				      ev_name ?: "<unknown>", be64_to_cpu(*p));
+		}
 		offset += ctrset_size(&ce);
 	}
 }
Signature · 1 line
2.14.3
maintainer Applied
#13 lore raw

Re: [PATCHv2 2/3] perf report: Display names in s390 diagnostic counter sets

Em Thu, Jan 17, 2019 at 10:30:02AM +0100, Thomas Richter escreveu:

Quoted 3 lines

On s390 the CPU Measurement Facility diagnostic counter sets are displayed by counter number and value. Add the logical counter name in the output (if it is available). Otherwise "unknown" is shown.

Thanks, applied.

Quoted 128 lines

Output before:
[root@s35lp76 perf]# ./perf report -D --stdio
[00000000] Counterset:0 Counters:6
Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94 Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460 Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
[0x000038] Counterset:1 Counters:2
Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
[0x000050] Counterset:2 Counters:16
Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000

Output after:

    [root@s35lp76 perf]# ./perf report -D --stdio

[00000000] Counterset:0 Counters:6

     Counter:000 cpu_cycles Value:0x000000000085ec36
     Counter:001 instructions Value:0x0000000000796c94
     Counter:002 l1i_dir_writes Value:0x0000000000005ada
     Counter:003 l1i_penalty_cycles Value:0x0000000000092460
     Counter:004 l1d_dir_writes Value:0x0000000000006073
     Counter:005 l1d_penalty_cycles Value:0x00000000001a9a73
 [0x000038] Counterset:1 Counters:2
     Counter:000 problem_state_cpu_cycles Value:0x000000000007c59f
     Counter:001 problem_state_instructions Value:0x000000000002fad6
 [0x000050] Counterset:2 Counters:16
     Counter:000 prng_functions Value:000000000000000000
---
 tools/perf/util/s390-sample-raw.c | 59 +++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 5 deletions(-)
tools/perf/util/s390-sample-raw.c +54 -5
index ae16c38ce296..73797bda919d 100644
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "color.h"
 #include "s390-cpumcf-kernel.h"
+#include "pmu-events/pmu-events.h"
 
 static size_t ctrset_size(struct cf_ctrset_entry *set)
 {
@@ -111,14 +112,61 @@ static void s390_cpumcfdg_dumptrail(const char *color, size_t offset,
 		      te.tod_base, te.mach_type);
 }
 
+/* Return starting number of a counter set */
+static int get_counterset_start(int setnr)
+{
+	switch (setnr) {
+	case CPUMF_CTR_SET_BASIC:		/* Basic counter set */
+		return 0;
+	case CPUMF_CTR_SET_USER:		/* Problem state counter set */
+		return 32;
+	case CPUMF_CTR_SET_CRYPTO:		/* Crypto counter set */
+		return 64;
+	case CPUMF_CTR_SET_EXT:			/* Extended counter set */
+		return 128;
+	case CPUMF_CTR_SET_MT_DIAG:		/* Diagnostic counter set */
+		return 448;
+	default:
+		return -1;
+	}
+}
+
+/* Scan the PMU table and extract the logical name of a counter from the
+ * PMU events table. Input is the counter set and counter number with in the
+ * set. Construct the event number and use this as key. If they match return
+ * the name of this counter.
+ * If no match is found a NULL pointer is returned.
+ */
+static const char *get_counter_name(int set, int nr, struct pmu_events_map *map)
+{
+	int rc, event_nr, wanted = get_counterset_start(set) + nr;
+
+	if (map) {
+		struct pmu_event *evp = map->table;
+
+		for (; evp->name || evp->event || evp->desc; ++evp) {
+			if (evp->name == NULL || evp->event == NULL)
+				continue;
+			rc = sscanf(evp->event, "event=%x", &event_nr);
+			if (rc == 1 && event_nr == wanted)
+				return evp->name;
+		}
+	}
+	return NULL;
+}
+
 static void s390_cpumcfdg_dump(struct perf_sample *sample)
 {
 	size_t i, len = sample->raw_size, offset = 0;
 	unsigned char *buf = sample->raw_data;
 	const char *color = PERF_COLOR_BLUE;
 	struct cf_ctrset_entry *cep, ce;
+	struct pmu_events_map *map;
+	struct perf_pmu pmu;
 	u64 *p;
 
+	memset(&pmu, 0, sizeof(pmu));
+	map = perf_pmu__find_map(&pmu);
 	while (offset < len) {
 		cep = (struct cf_ctrset_entry *)(buf + offset);
 
@@ -135,12 +183,13 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample)
 
 		color_fprintf(stdout, color, "    [%#08zx] Counterset:%d"
 			      " Counters:%d\n", offset, ce.set, ce.ctr);
-		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; i += 2, p += 2)
+		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) {
+			const char *ev_name = get_counter_name(ce.set, i, map);
+
 			color_fprintf(stdout, color,
-				      "\tCounter:%03d Value:%#018lx"
-				      " Counter:%03d Value:%#018lx\n",
-				      i, be64_to_cpu(*p),
-				      i + 1, be64_to_cpu(*(p + 1)));
+				      "\tCounter:%03d %s Value:%#018lx\n", i,
+				      ev_name ?: "<unknown>", be64_to_cpu(*p));
+		}
 		offset += ctrset_size(&ce);
 	}
 }
Signature · 1 line
2.14.3
Signature · 1 line
- Arnaldo
#14 lore raw

[tip:perf/core] perf report: Display names in s390 diagnostic counter sets

In reply to Thomas Richter
perf report: Display names in s390 diagnostic counter sets
Commit-ID:  3e4a1c536b2690cf461e930485b0ab0cdafba73b
Gitweb:     https://git.kernel.org/tip/3e4a1c536b2690cf461e930485b0ab0cdafba73b
Author:     Thomas Richter <[email protected]>
AuthorDate: Thu, 17 Jan 2019 10:30:02 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 21 Jan 2019 17:00:56 -0300

perf report: Display names in s390 diagnostic counter sets

On s390 the CPU Measurement Facility diagnostic counter sets are displayed by counter number and value. Add the logical counter name in the output (if it is available). Otherwise "unknown" is shown.

Output before:

[root@s35lp76 perf]# ./perf report -D --stdio
[00000000] Counterset:0 Counters:6
Counter:000 Value:0x000000000085ec36 Counter:001 Value:0x0000000000796c94 Counter:002 Value:0x0000000000005ada Counter:003 Value:0x0000000000092460 Counter:004 Value:0x0000000000006073 Counter:005 Value:0x00000000001a9a73
[0x000038] Counterset:1 Counters:2
Counter:000 Value:0x000000000007c59f Counter:001 Value:0x000000000002fad6
[0x000050] Counterset:2 Counters:16
Counter:000 Value:000000000000000000 Counter:001 Value:000000000000000000

Output after:

    [root@s35lp76 perf]# ./perf report -D --stdio

[00000000] Counterset:0 Counters:6

     Counter:000 cpu_cycles Value:0x000000000085ec36
     Counter:001 instructions Value:0x0000000000796c94
     Counter:002 l1i_dir_writes Value:0x0000000000005ada
     Counter:003 l1i_penalty_cycles Value:0x0000000000092460
     Counter:004 l1d_dir_writes Value:0x0000000000006073
     Counter:005 l1d_penalty_cycles Value:0x00000000001a9a73
 [0x000038] Counterset:1 Counters:2
     Counter:000 problem_state_cpu_cycles Value:0x000000000007c59f
     Counter:001 problem_state_instructions Value:0x000000000002fad6
 [0x000050] Counterset:2 Counters:16
     Counter:000 prng_functions Value:000000000000000000
---
 tools/perf/util/s390-sample-raw.c | 59 +++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 5 deletions(-)
tools/perf/util/s390-sample-raw.c +54 -5
index 1c5a4d63bc9d..6650f599ed9c 100644
@@ -30,6 +30,7 @@
 #include "color.h"
 #include "sample-raw.h"
 #include "s390-cpumcf-kernel.h"
+#include "pmu-events/pmu-events.h"
 
 static size_t ctrset_size(struct cf_ctrset_entry *set)
 {
@@ -112,14 +113,61 @@ static void s390_cpumcfdg_dumptrail(const char *color, size_t offset,
 		      te.tod_base, te.mach_type);
 }
 
+/* Return starting number of a counter set */
+static int get_counterset_start(int setnr)
+{
+	switch (setnr) {
+	case CPUMF_CTR_SET_BASIC:		/* Basic counter set */
+		return 0;
+	case CPUMF_CTR_SET_USER:		/* Problem state counter set */
+		return 32;
+	case CPUMF_CTR_SET_CRYPTO:		/* Crypto counter set */
+		return 64;
+	case CPUMF_CTR_SET_EXT:			/* Extended counter set */
+		return 128;
+	case CPUMF_CTR_SET_MT_DIAG:		/* Diagnostic counter set */
+		return 448;
+	default:
+		return -1;
+	}
+}
+
+/* Scan the PMU table and extract the logical name of a counter from the
+ * PMU events table. Input is the counter set and counter number with in the
+ * set. Construct the event number and use this as key. If they match return
+ * the name of this counter.
+ * If no match is found a NULL pointer is returned.
+ */
+static const char *get_counter_name(int set, int nr, struct pmu_events_map *map)
+{
+	int rc, event_nr, wanted = get_counterset_start(set) + nr;
+
+	if (map) {
+		struct pmu_event *evp = map->table;
+
+		for (; evp->name || evp->event || evp->desc; ++evp) {
+			if (evp->name == NULL || evp->event == NULL)
+				continue;
+			rc = sscanf(evp->event, "event=%x", &event_nr);
+			if (rc == 1 && event_nr == wanted)
+				return evp->name;
+		}
+	}
+	return NULL;
+}
+
 static void s390_cpumcfdg_dump(struct perf_sample *sample)
 {
 	size_t i, len = sample->raw_size, offset = 0;
 	unsigned char *buf = sample->raw_data;
 	const char *color = PERF_COLOR_BLUE;
 	struct cf_ctrset_entry *cep, ce;
+	struct pmu_events_map *map;
+	struct perf_pmu pmu;
 	u64 *p;
 
+	memset(&pmu, 0, sizeof(pmu));
+	map = perf_pmu__find_map(&pmu);
 	while (offset < len) {
 		cep = (struct cf_ctrset_entry *)(buf + offset);
 
@@ -136,12 +184,13 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample)
 
 		color_fprintf(stdout, color, "    [%#08zx] Counterset:%d"
 			      " Counters:%d\n", offset, ce.set, ce.ctr);
-		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; i += 2, p += 2)
+		for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) {
+			const char *ev_name = get_counter_name(ce.set, i, map);
+
 			color_fprintf(stdout, color,
-				      "\tCounter:%03d Value:%#018lx"
-				      " Counter:%03d Value:%#018lx\n",
-				      i, be64_to_cpu(*p),
-				      i + 1, be64_to_cpu(*(p + 1)));
+				      "\tCounter:%03d %s Value:%#018lx\n", i,
+				      ev_name ?: "<unknown>", be64_to_cpu(*p));
+		}
 		offset += ctrset_size(&ce);
 	}
 }
#15 lore raw

PATCH v2 3/3 perf report: s390 dump counter set data to file.

In reply to Thomas Richter

Add support for the new s390 PMU device cpum_cf_diag to extract the counter set diagnostic data. This data is available as event raw data and can be created with this command:

[root@s35lp76 perf]# ./perf record -R -e '{rbd000,rbc000}' --

                                 ~/mytests/facultaet 2500

[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.009 MB perf.data ] [root@s35lp76 perf]#

The new event 0xbc000 generated this counter set diagnostic trace data. The data can be extracted using command:

  [root@s35lp76 perf]# ./perf report --stdio --itrace=d
  #
  # Total Lost Samples: 0
  #
  # Samples: 21  of events 'anon group { rbd000, rbc000 }'
  # Event count (approx.): 21
  #
  #         Overhead  Command    Shared Object      Symbol
  # ................  .........  .................  ........................
  #
    80.95%   0.00%  facultaet  facultaet          [.] facultaet
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] check_chain_key
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] ftrace_likely_update
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] lock_release
     4.76%   0.00%  facultaet  libc-2.26.so       [.] _dl_addr
  [root@s35lp76 perf]# ll aux*
  -rw-r--r-- 1 root root 3408 Oct 16 12:40 aux.ctr.02
  -rw-r--r-- 1 root root 4096 Oct 16 12:40 aux.smp.02
  [root@s35lp76 perf]#

The files named aux.ctr.## contain the counter set diagnstic data and the files named aux.smp.## contain the sampling diagnostic data. ## stand for the CPU number the data was taken from.

---
 tools/perf/util/s390-cpumsf.c | 77 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)
tools/perf/util/s390-cpumsf.c +73 -4
index 68b2570304ec..835249c77f56 100644
@@ -162,6 +162,7 @@
 #include "auxtrace.h"
 #include "s390-cpumsf.h"
 #include "s390-cpumsf-kernel.h"
+#include "s390-cpumcf-kernel.h"
 #include "config.h"
 
 struct s390_cpumsf {
@@ -184,8 +185,58 @@ struct s390_cpumsf_queue {
 	struct auxtrace_buffer	*buffer;
 	int			cpu;
 	FILE			*logfile;
+	FILE			*logfile_ctr;
 };
 
+/* Check if the raw data should be dumped to file. If this is the case and
+ * the file to dump to has not been opened for writing, do so.
+ *
+ * Return 0 on success and greater zero on error so processing continues.
+ */
+static int s390_cpumcf_dumpctr(struct s390_cpumsf *sf,
+			       struct perf_sample *sample)
+{
+	struct s390_cpumsf_queue *sfq;
+	struct auxtrace_queue *q;
+	int rc = 0;
+
+	if (!sf->use_logfile || sf->queues.nr_queues <= sample->cpu)
+		return rc;
+
+	q = &sf->queues.queue_array[sample->cpu];
+	sfq = q->priv;
+	if (!sfq)		/* Queue not yet allocated */
+		return rc;
+
+	if (!sfq->logfile_ctr) {
+		char *name;
+
+		rc = (sf->logdir)
+			? asprintf(&name, "%s/aux.ctr.%02x",
+				 sf->logdir, sample->cpu)
+			: asprintf(&name, "aux.ctr.%02x", sample->cpu);
+		if (rc > 0)
+			sfq->logfile_ctr = fopen(name, "w");
+		if (sfq->logfile_ctr == NULL) {
+			pr_err("Failed to open counter set log file %s, "
+			       "continue...\n", name);
+			rc = 1;
+		}
+		free(name);
+	}
+
+	if (sfq->logfile_ctr) {
+		/* See comment above for -4 */
+		size_t n = fwrite(sample->raw_data, sample->raw_size - 4, 1,
+				  sfq->logfile_ctr);
+		if (n != 1) {
+			pr_err("Failed to write counter set data\n");
+			rc = 1;
+		}
+	}
+	return rc;
+}
+
 /* Display s390 CPU measurement facility basic-sampling data entry */
 static bool s390_cpumsf_basic_show(const char *color, size_t pos,
 				   struct hws_basic_entry *basic)
@@ -792,7 +843,7 @@ static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample)
 }
 
 static int
-s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
+s390_cpumsf_process_event(struct perf_session *session,
 			  union perf_event *event,
 			  struct perf_sample *sample,
 			  struct perf_tool *tool)
@@ -801,6 +852,8 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 					      struct s390_cpumsf,
 					      auxtrace);
 	u64 timestamp = sample->time;
+	struct perf_evsel *ev_bc000;
+
 	int err = 0;
 
 	if (dump_trace)
@@ -811,6 +864,16 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 		return -EINVAL;
 	}
 
+	if (event->header.type == PERF_RECORD_SAMPLE &&
+	    sample->raw_size) {
+		/* Handle event with raw data */
+		ev_bc000 = perf_evlist__event2evsel(session->evlist, event);
+		if (ev_bc000 &&
+		    ev_bc000->attr.config == PERF_EVENT_CPUM_CF_DIAG)
+			err = s390_cpumcf_dumpctr(sf, sample);
+		return err;
+	}
+
 	if (event->header.type == PERF_RECORD_AUX &&
 	    event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
 		return s390_cpumsf_lost(sf, sample);
@@ -891,9 +954,15 @@ static void s390_cpumsf_free_queues(struct perf_session *session)
 		struct s390_cpumsf_queue *sfq = (struct s390_cpumsf_queue *)
 						queues->queue_array[i].priv;
 
-		if (sfq != NULL && sfq->logfile) {
-			fclose(sfq->logfile);
-			sfq->logfile = NULL;
+		if (sfq != NULL) {
+			if (sfq->logfile) {
+				fclose(sfq->logfile);
+				sfq->logfile = NULL;
+			}
+			if (sfq->logfile_ctr) {
+				fclose(sfq->logfile_ctr);
+				sfq->logfile_ctr = NULL;
+			}
 		}
 		zfree(&queues->queue_array[i].priv);
 	}
Signature · 1 line
2.14.3
maintainer Applied
#16 lore raw

Re: [PATCHv2 3/3] perf report: s390 dump counter set data to file.

Em Thu, Jan 17, 2019 at 10:30:03AM +0100, Thomas Richter escreveu:

Quoted 3 lines

Add support for the new s390 PMU device cpum_cf_diag to extract the counter set diagnostic data. This data is available as event raw data and can be created with this command:

Thanks, applied.

- Arnaldo

Quoted 167 lines

[root@s35lp76 perf]# ./perf record -R -e '{rbd000,rbc000}' --

                                 ~/mytests/facultaet 2500

[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.009 MB perf.data ] [root@s35lp76 perf]#

The new event 0xbc000 generated this counter set diagnostic trace data. The data can be extracted using command:

  [root@s35lp76 perf]# ./perf report --stdio --itrace=d
  #
  # Total Lost Samples: 0
  #
  # Samples: 21  of events 'anon group { rbd000, rbc000 }'
  # Event count (approx.): 21
  #
  #         Overhead  Command    Shared Object      Symbol
  # ................  .........  .................  ........................
  #
    80.95%   0.00%  facultaet  facultaet          [.] facultaet
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] check_chain_key
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] ftrace_likely_update
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] lock_release
     4.76%   0.00%  facultaet  libc-2.26.so       [.] _dl_addr
  [root@s35lp76 perf]# ll aux*
  -rw-r--r-- 1 root root 3408 Oct 16 12:40 aux.ctr.02
  -rw-r--r-- 1 root root 4096 Oct 16 12:40 aux.smp.02
  [root@s35lp76 perf]#

The files named aux.ctr.## contain the counter set diagnstic data and the files named aux.smp.## contain the sampling diagnostic data. ## stand for the CPU number the data was taken from.

---
 tools/perf/util/s390-cpumsf.c | 77 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)
tools/perf/util/s390-cpumsf.c +73 -4
index 68b2570304ec..835249c77f56 100644
@@ -162,6 +162,7 @@
 #include "auxtrace.h"
 #include "s390-cpumsf.h"
 #include "s390-cpumsf-kernel.h"
+#include "s390-cpumcf-kernel.h"
 #include "config.h"
 
 struct s390_cpumsf {
@@ -184,8 +185,58 @@ struct s390_cpumsf_queue {
 	struct auxtrace_buffer	*buffer;
 	int			cpu;
 	FILE			*logfile;
+	FILE			*logfile_ctr;
 };
 
+/* Check if the raw data should be dumped to file. If this is the case and
+ * the file to dump to has not been opened for writing, do so.
+ *
+ * Return 0 on success and greater zero on error so processing continues.
+ */
+static int s390_cpumcf_dumpctr(struct s390_cpumsf *sf,
+			       struct perf_sample *sample)
+{
+	struct s390_cpumsf_queue *sfq;
+	struct auxtrace_queue *q;
+	int rc = 0;
+
+	if (!sf->use_logfile || sf->queues.nr_queues <= sample->cpu)
+		return rc;
+
+	q = &sf->queues.queue_array[sample->cpu];
+	sfq = q->priv;
+	if (!sfq)		/* Queue not yet allocated */
+		return rc;
+
+	if (!sfq->logfile_ctr) {
+		char *name;
+
+		rc = (sf->logdir)
+			? asprintf(&name, "%s/aux.ctr.%02x",
+				 sf->logdir, sample->cpu)
+			: asprintf(&name, "aux.ctr.%02x", sample->cpu);
+		if (rc > 0)
+			sfq->logfile_ctr = fopen(name, "w");
+		if (sfq->logfile_ctr == NULL) {
+			pr_err("Failed to open counter set log file %s, "
+			       "continue...\n", name);
+			rc = 1;
+		}
+		free(name);
+	}
+
+	if (sfq->logfile_ctr) {
+		/* See comment above for -4 */
+		size_t n = fwrite(sample->raw_data, sample->raw_size - 4, 1,
+				  sfq->logfile_ctr);
+		if (n != 1) {
+			pr_err("Failed to write counter set data\n");
+			rc = 1;
+		}
+	}
+	return rc;
+}
+
 /* Display s390 CPU measurement facility basic-sampling data entry */
 static bool s390_cpumsf_basic_show(const char *color, size_t pos,
 				   struct hws_basic_entry *basic)
@@ -792,7 +843,7 @@ static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample)
 }
 
 static int
-s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
+s390_cpumsf_process_event(struct perf_session *session,
 			  union perf_event *event,
 			  struct perf_sample *sample,
 			  struct perf_tool *tool)
@@ -801,6 +852,8 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 					      struct s390_cpumsf,
 					      auxtrace);
 	u64 timestamp = sample->time;
+	struct perf_evsel *ev_bc000;
+
 	int err = 0;
 
 	if (dump_trace)
@@ -811,6 +864,16 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 		return -EINVAL;
 	}
 
+	if (event->header.type == PERF_RECORD_SAMPLE &&
+	    sample->raw_size) {
+		/* Handle event with raw data */
+		ev_bc000 = perf_evlist__event2evsel(session->evlist, event);
+		if (ev_bc000 &&
+		    ev_bc000->attr.config == PERF_EVENT_CPUM_CF_DIAG)
+			err = s390_cpumcf_dumpctr(sf, sample);
+		return err;
+	}
+
 	if (event->header.type == PERF_RECORD_AUX &&
 	    event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
 		return s390_cpumsf_lost(sf, sample);
@@ -891,9 +954,15 @@ static void s390_cpumsf_free_queues(struct perf_session *session)
 		struct s390_cpumsf_queue *sfq = (struct s390_cpumsf_queue *)
 						queues->queue_array[i].priv;
 
-		if (sfq != NULL && sfq->logfile) {
-			fclose(sfq->logfile);
-			sfq->logfile = NULL;
+		if (sfq != NULL) {
+			if (sfq->logfile) {
+				fclose(sfq->logfile);
+				sfq->logfile = NULL;
+			}
+			if (sfq->logfile_ctr) {
+				fclose(sfq->logfile_ctr);
+				sfq->logfile_ctr = NULL;
+			}
 		}
 		zfree(&queues->queue_array[i].priv);
 	}
Signature · 1 line
2.14.3
Signature · 1 line
- Arnaldo
#17 lore raw

[tip:perf/core] perf report: Dump s390 counter set data to file

In reply to Thomas Richter
perf report: Dump s390 counter set data to file
Commit-ID:  8dabe9c43af7aa78b16ce0d61bc595eca20c7a70
Gitweb:     https://git.kernel.org/tip/8dabe9c43af7aa78b16ce0d61bc595eca20c7a70
Author:     Thomas Richter <[email protected]>
AuthorDate: Thu, 17 Jan 2019 10:30:03 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 21 Jan 2019 17:00:57 -0300

perf report: Dump s390 counter set data to file

Add support for the new s390 PMU device cpum_cf_diag to extract the counter set diagnostic data. This data is available as event raw data and can be created with this command:

[root@s35lp76 perf]# ./perf record -R -e '{rbd000,rbc000}' --

                                 ~/mytests/facultaet 2500

[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.009 MB perf.data ] [root@s35lp76 perf]#

The new event 0xbc000 generated this counter set diagnostic trace data. The data can be extracted using command:

  [root@s35lp76 perf]# ./perf report --stdio --itrace=d
  #
  # Total Lost Samples: 0
  #
  # Samples: 21  of events 'anon group { rbd000, rbc000 }'
  # Event count (approx.): 21
  #
  #         Overhead  Command    Shared Object      Symbol
  # ................  .........  .................  ........................
  #
    80.95%   0.00%  facultaet  facultaet          [.] facultaet
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] check_chain_key
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] ftrace_likely_update
     4.76%   0.00%  facultaet  [kernel.kallsyms]  [k] lock_release
     4.76%   0.00%  facultaet  libc-2.26.so       [.] _dl_addr
  [root@s35lp76 perf]# ll aux*
  -rw-r--r-- 1 root root 3408 Oct 16 12:40 aux.ctr.02
  -rw-r--r-- 1 root root 4096 Oct 16 12:40 aux.smp.02
  [root@s35lp76 perf]#

The files named aux.ctr.## contain the counter set diagnostic data and the files named aux.smp.## contain the sampling diagnostic data. ## stand for the CPU number the data was taken from.

---
 tools/perf/util/s390-cpumsf.c | 77 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)
tools/perf/util/s390-cpumsf.c +73 -4
index 68b2570304ec..835249c77f56 100644
@@ -162,6 +162,7 @@
 #include "auxtrace.h"
 #include "s390-cpumsf.h"
 #include "s390-cpumsf-kernel.h"
+#include "s390-cpumcf-kernel.h"
 #include "config.h"
 
 struct s390_cpumsf {
@@ -184,8 +185,58 @@ struct s390_cpumsf_queue {
 	struct auxtrace_buffer	*buffer;
 	int			cpu;
 	FILE			*logfile;
+	FILE			*logfile_ctr;
 };
 
+/* Check if the raw data should be dumped to file. If this is the case and
+ * the file to dump to has not been opened for writing, do so.
+ *
+ * Return 0 on success and greater zero on error so processing continues.
+ */
+static int s390_cpumcf_dumpctr(struct s390_cpumsf *sf,
+			       struct perf_sample *sample)
+{
+	struct s390_cpumsf_queue *sfq;
+	struct auxtrace_queue *q;
+	int rc = 0;
+
+	if (!sf->use_logfile || sf->queues.nr_queues <= sample->cpu)
+		return rc;
+
+	q = &sf->queues.queue_array[sample->cpu];
+	sfq = q->priv;
+	if (!sfq)		/* Queue not yet allocated */
+		return rc;
+
+	if (!sfq->logfile_ctr) {
+		char *name;
+
+		rc = (sf->logdir)
+			? asprintf(&name, "%s/aux.ctr.%02x",
+				 sf->logdir, sample->cpu)
+			: asprintf(&name, "aux.ctr.%02x", sample->cpu);
+		if (rc > 0)
+			sfq->logfile_ctr = fopen(name, "w");
+		if (sfq->logfile_ctr == NULL) {
+			pr_err("Failed to open counter set log file %s, "
+			       "continue...\n", name);
+			rc = 1;
+		}
+		free(name);
+	}
+
+	if (sfq->logfile_ctr) {
+		/* See comment above for -4 */
+		size_t n = fwrite(sample->raw_data, sample->raw_size - 4, 1,
+				  sfq->logfile_ctr);
+		if (n != 1) {
+			pr_err("Failed to write counter set data\n");
+			rc = 1;
+		}
+	}
+	return rc;
+}
+
 /* Display s390 CPU measurement facility basic-sampling data entry */
 static bool s390_cpumsf_basic_show(const char *color, size_t pos,
 				   struct hws_basic_entry *basic)
@@ -792,7 +843,7 @@ static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample)
 }
 
 static int
-s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
+s390_cpumsf_process_event(struct perf_session *session,
 			  union perf_event *event,
 			  struct perf_sample *sample,
 			  struct perf_tool *tool)
@@ -801,6 +852,8 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 					      struct s390_cpumsf,
 					      auxtrace);
 	u64 timestamp = sample->time;
+	struct perf_evsel *ev_bc000;
+
 	int err = 0;
 
 	if (dump_trace)
@@ -811,6 +864,16 @@ s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
 		return -EINVAL;
 	}
 
+	if (event->header.type == PERF_RECORD_SAMPLE &&
+	    sample->raw_size) {
+		/* Handle event with raw data */
+		ev_bc000 = perf_evlist__event2evsel(session->evlist, event);
+		if (ev_bc000 &&
+		    ev_bc000->attr.config == PERF_EVENT_CPUM_CF_DIAG)
+			err = s390_cpumcf_dumpctr(sf, sample);
+		return err;
+	}
+
 	if (event->header.type == PERF_RECORD_AUX &&
 	    event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
 		return s390_cpumsf_lost(sf, sample);
@@ -891,9 +954,15 @@ static void s390_cpumsf_free_queues(struct perf_session *session)
 		struct s390_cpumsf_queue *sfq = (struct s390_cpumsf_queue *)
 						queues->queue_array[i].priv;
 
-		if (sfq != NULL && sfq->logfile) {
-			fclose(sfq->logfile);
-			sfq->logfile = NULL;
+		if (sfq != NULL) {
+			if (sfq->logfile) {
+				fclose(sfq->logfile);
+				sfq->logfile = NULL;
+			}
+			if (sfq->logfile_ctr) {
+				fclose(sfq->logfile_ctr);
+				sfq->logfile_ctr = NULL;
+			}
 		}
 		zfree(&queues->queue_array[i].priv);
 	}