Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1294191 > unrolled thread

[GIT PULL 00/43] perf/core new feature: 'perf stat record/report'

Started byArnaldo Carvalho de Melo <acme@kernel.org>
First post2015-12-17 21:00 +0100
Last post2015-12-18 11:20 +0100
Articles 20 on this page of 34 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [GIT PULL 00/43] perf/core new feature: 'perf stat record/report' Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 08/43] perf cpu_map: Add perf_event__fprintf_cpu_map function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 06/43] perf cpu_map: Add cpu_map event synthesize function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 10/43] perf tools: Add stat config event synthesize function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 19/43] perf tools: Add event_update event unit type Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 09/43] perf tools: Add stat config user level event Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 25/43] perf tools: Introduce stat perf.data header feature Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 24/43] perf report: Display newly added events in raw dump Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 07/43] perf cpu_map: Add cpu_map__new_event function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 40/43] perf stat report: Move csv_sep initialization before report command Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 05/43] perf cpu_map: Add cpu_map user level event Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 18/43] perf tools: Add event_update user level event Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 22/43] perf tools: Add event_update event cpus type Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 29/43] perf evlist: Export id_add_fd() Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 01/43] perf thread_map: Add thread_map user level event Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 17/43] perf tools: Add stat events fprintf functions Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 39/43] perf stat report: Add support to initialize aggr_map from file Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 36/43] perf stat report: Add report command Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 03/43] perf thread_map: Add thread_map__new_event function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 16/43] perf tools: Add stat round event synthesize function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 28/43] perf stat record: Synthesize stat record data Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 35/43] perf stat record: Synthesize event update events Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 13/43] perf tools: Add stat event synthesize function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 26/43] perf stat record: Add record command Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 15/43] perf tools: Add stat round user level event Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 21/43] perf tools: Add event_update event name type Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 20/43] perf tools: Add event_update event scale type Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 33/43] perf stat record: Write stat round events on record Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 14/43] perf tools: Add stat event read function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:00 +0100
    [PATCH 02/43] perf thread_map: Add thread_map event sythesize function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:10 +0100
    [PATCH 04/43] perf thread_map: Add perf_event__fprintf_thread_map function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-12-17 21:10 +0100
    Re: [GIT PULL 00/43] perf/core new feature: 'perf stat record/report' Ingo Molnar <mingo@kernel.org> - 2015-12-18 09:50 +0100
      Re: [GIT PULL 00/43] perf/core new feature: 'perf stat record/report' Ingo Molnar <mingo@kernel.org> - 2015-12-18 10:00 +0100
        Re: [GIT PULL 00/43] perf/core new feature: 'perf stat record/report' Jiri Olsa <jolsa@redhat.com> - 2015-12-18 11:20 +0100

Page 1 of 2  [1] 2  Next page →


#1294191 — [GIT PULL 00/43] perf/core new feature: 'perf stat record/report'

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[GIT PULL 00/43] perf/core new feature: 'perf stat record/report'
Message-ID<qGMIN-3MF-3@gated-at.bofh.it>
From: Arnaldo Carvalho de Melo <acme@redhat.com>

Hi Ingo,

	Please consider pulling, cool new feature! This is on top of the
perf-core-for-mingo-2.1 tag, with that RHEL6.7 bugfix, I had also to go
over this one fixing stuff in many spots :-\

- Arnaldo

The following changes since commit 1843b4e057b7717db21a3ad96fa16d6b4ee8f6c4:

  tools subcmd: Rename subcmd header include guards (2015-12-17 14:27:14 -0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-3

for you to fetch changes up to 89af4e05c21d68f22e07fe66940ea675615a49ed:

  perf stat report: Allow to override aggr_mode (2015-12-17 16:30:30 -0300)

----------------------------------------------------------------
perf/core improvement.

User visible:

- Generate perf.data files from 'perf stat', to tap into the scripting
  capabilities perf has instead of defining a 'perf stat' specific scripting
  support to calculate event ratios, etc. Simple example:

  $ perf stat record -e cycles usleep 1

   Performance counter stats for 'usleep 1':

         1,134,996      cycles

       0.000670644 seconds time elapsed

  $ perf stat report

   Performance counter stats for '/home/acme/bin/perf stat record -e cycles usleep 1':

         1,134,996      cycles

       0.000670644 seconds time elapsed

  $

  It generates PERF_RECORD_ userspace records to store the details:

  $ perf report -D | grep PERF_RECORD
  0xf0 [0x28]: PERF_RECORD_THREAD_MAP nr: 1 thread: 27637
  0x118 [0x12]: PERF_RECORD_CPU_MAP nr: 1 cpu: 65535
  0x12a [0x40]: PERF_RECORD_STAT_CONFIG
  0x16a [0x30]: PERF_RECORD_STAT
  -1 -1 0x19a [0x40]: PERF_RECORD_MMAP -1/0: [0xffffffff81000000(0x1f000000) @ 0xffffffff81000000]: x [kernel.kallsyms]_text
  0x1da [0x18]: PERF_RECORD_STAT_ROUND
  [acme@ssdandy linux]$

  An effort was made to make perf.data files generated like this to not
  generate cryptic messages when processed by older tools.

  The 'perf script' bits need rebasing, will go up later.

Jiri's cover letter for this series:

The initial attempt defined its own formula lang and allowed triggering user's
script on the end of the stat command:

  http://marc.info/?l=linux-kernel&m=136742146322273&w=2

This patchset abandons the idea of new formula language and rather adds support
to:

  - store stat data into perf.data file
  - add python support to process stat events

Basically it allows to store stat data into perf.data and post process it with
python scripts in a similar way we do for sampling data.

The stat data are stored in new stat, stat-round, stat-config user events.
  stat        - stored for each read syscall of the counter
  stat round  - stored for each interval or end of the command invocation
  stat config - stores all the config information needed to process data
                so report tool could restore the same output as record

The python script can now define 'stat__<eventname>_<modifier>' functions
to get stat events data and 'stat__interval' to get stat-round data.

See CPI script example in scripts/python/stat-cpi.py.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

----------------------------------------------------------------
Jiri Olsa (43):
      perf thread_map: Add thread_map user level event
      perf thread_map: Add thread_map event sythesize function
      perf thread_map: Add thread_map__new_event function
      perf thread_map: Add perf_event__fprintf_thread_map function
      perf cpu_map: Add cpu_map user level event
      perf cpu_map: Add cpu_map event synthesize function
      perf cpu_map: Add cpu_map__new_event function
      perf cpu_map: Add perf_event__fprintf_cpu_map function
      perf tools: Add stat config user level event
      perf tools: Add stat config event synthesize function
      perf tools: Add stat config event read function
      perf tools: Add stat user level event
      perf tools: Add stat event synthesize function
      perf tools: Add stat event read function
      perf tools: Add stat round user level event
      perf tools: Add stat round event synthesize function
      perf tools: Add stat events fprintf functions
      perf tools: Add event_update user level event
      perf tools: Add event_update event unit type
      perf tools: Add event_update event scale type
      perf tools: Add event_update event name type
      perf tools: Add event_update event cpus type
      perf tools: Add perf_event__fprintf_event_update function
      perf report: Display newly added events in raw dump
      perf tools: Introduce stat perf.data header feature
      perf stat record: Add record command
      perf stat record: Initialize record features
      perf stat record: Synthesize stat record data
      perf evlist: Export id_add_fd()
      perf stat record: Store events IDs in perf data file
      perf stat record: Add pipe support for record command
      perf stat record: Write stat events on record
      perf stat record: Write stat round events on record
      perf stat record: Do not allow record with multiple runs mode
      perf stat record: Synthesize event update events
      perf stat report: Add report command
      perf stat report: Process cpu/threads maps
      perf stat report: Process stat config event
      perf stat report: Add support to initialize aggr_map from file
      perf stat report: Move csv_sep initialization before report command
      perf stat report: Process stat and stat round events
      perf stat report: Process event update events
      perf stat report: Allow to override aggr_mode

 tools/perf/Documentation/perf-stat.txt |  34 ++
 tools/perf/builtin-record.c            |   2 +
 tools/perf/builtin-stat.c              | 614 ++++++++++++++++++++++++++++++++-
 tools/perf/tests/Build                 |   3 +
 tools/perf/tests/builtin-test.c        |  24 ++
 tools/perf/tests/cpumap.c              |  88 +++++
 tools/perf/tests/event_update.c        | 117 +++++++
 tools/perf/tests/stat.c                | 111 ++++++
 tools/perf/tests/tests.h               |   6 +
 tools/perf/tests/thread-map.c          |  43 +++
 tools/perf/util/cpumap.c               |  42 +++
 tools/perf/util/cpumap.h               |   1 +
 tools/perf/util/event.c                | 308 +++++++++++++++++
 tools/perf/util/event.h                | 150 +++++++-
 tools/perf/util/evlist.c               |   6 +-
 tools/perf/util/evlist.h               |   3 +
 tools/perf/util/header.c               | 205 +++++++++++
 tools/perf/util/header.h               |  17 +
 tools/perf/util/session.c              | 189 ++++++++++
 tools/perf/util/stat.c                 |  62 ++++
 tools/perf/util/stat.h                 |  10 +
 tools/perf/util/thread_map.c           |  27 ++
 tools/perf/util/thread_map.h           |   3 +
 tools/perf/util/tool.h                 |   8 +-
 24 files changed, 2054 insertions(+), 19 deletions(-)
 create mode 100644 tools/perf/tests/cpumap.c
 create mode 100644 tools/perf/tests/event_update.c
 create mode 100644 tools/perf/tests/stat.c
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1294192 — [PATCH 08/43] perf cpu_map: Add perf_event__fprintf_cpu_map function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 08/43] perf cpu_map: Add perf_event__fprintf_cpu_map function
Message-ID<qGMSu-3Qg-15@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

To display a cpu_map event for raw dump.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-11-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c | 16 ++++++++++++++++
 tools/perf/util/event.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 15d6466a4b8f..f31ab3b8f918 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -968,6 +968,22 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp)
 	return ret;
 }
 
+size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp)
+{
+	struct cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data);
+	size_t ret;
+
+	ret = fprintf(fp, " nr: ");
+
+	if (cpus)
+		ret += cpu_map__fprintf(cpus, fp);
+	else
+		ret += fprintf(fp, "failed to get cpumap from event\n");
+
+	cpu_map__put(cpus);
+	return ret;
+}
+
 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
 			     union perf_event *event,
 			     struct perf_sample *sample,
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index de18ee0e9c96..74a434116b2c 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -550,6 +550,7 @@ size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf(union perf_event *event, FILE *fp);
 
 u64 kallsyms__get_function_start(const char *kallsyms_filename,
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294193 — [PATCH 06/43] perf cpu_map: Add cpu_map event synthesize function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 06/43] perf cpu_map: Add cpu_map event synthesize function
Message-ID<qGMSu-3Qg-13@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introduce the perf_event__synthesize_cpu_map function to synthesize a
struct cpu_map.

Added generic interface:
  cpu_map_data__alloc
  cpu_map_data__synthesize

to make the cpu_map synthesizing usable for other events.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-9-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/Build          |   1 +
 tools/perf/tests/builtin-test.c |   4 ++
 tools/perf/tests/cpumap.c       |  71 ++++++++++++++++++++++
 tools/perf/tests/tests.h        |   1 +
 tools/perf/util/event.c         | 131 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/event.h         |   8 +++
 6 files changed, 216 insertions(+)
 create mode 100644 tools/perf/tests/cpumap.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index f23fb7ed4400..7abad28fe17e 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -34,6 +34,7 @@ perf-y += thread-map.o
 perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o
 perf-y += bpf.o
 perf-y += topology.o
+perf-y += cpumap.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 745bdb02d22b..0c3fe2846de8 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -184,6 +184,10 @@ static struct test generic_tests[] = {
 		.func = test__thread_map_synthesize,
 	},
 	{
+		.desc = "Test cpu map synthesize",
+		.func = test__cpu_map_synthesize,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
new file mode 100644
index 000000000000..715480558088
--- /dev/null
+++ b/tools/perf/tests/cpumap.c
@@ -0,0 +1,71 @@
+#include "tests.h"
+#include "cpumap.h"
+
+static int process_event_mask(struct perf_tool *tool __maybe_unused,
+			 union perf_event *event,
+			 struct perf_sample *sample __maybe_unused,
+			 struct machine *machine __maybe_unused)
+{
+	struct cpu_map_event *map = &event->cpu_map;
+	struct cpu_map_mask *mask;
+	struct cpu_map_data *data;
+	int i;
+
+	data = &map->data;
+
+	TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK);
+
+	mask = (struct cpu_map_mask *)data->data;
+
+	TEST_ASSERT_VAL("wrong nr",   mask->nr == 1);
+
+	for (i = 0; i < 20; i++) {
+		TEST_ASSERT_VAL("wrong cpu", test_bit(i, mask->mask));
+	}
+
+	return 0;
+}
+
+static int process_event_cpus(struct perf_tool *tool __maybe_unused,
+			 union perf_event *event,
+			 struct perf_sample *sample __maybe_unused,
+			 struct machine *machine __maybe_unused)
+{
+	struct cpu_map_event *map = &event->cpu_map;
+	struct cpu_map_entries *cpus;
+	struct cpu_map_data *data;
+
+	data = &map->data;
+
+	TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__CPUS);
+
+	cpus = (struct cpu_map_entries *)data->data;
+
+	TEST_ASSERT_VAL("wrong nr",   cpus->nr == 2);
+	TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[0] == 1);
+	TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[1] == 256);
+	return 0;
+}
+
+
+int test__cpu_map_synthesize(int subtest __maybe_unused)
+{
+	struct cpu_map *cpus;
+
+	/* This one is better stores in mask. */
+	cpus = cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19");
+
+	TEST_ASSERT_VAL("failed to synthesize map",
+		!perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL));
+
+	cpu_map__put(cpus);
+
+	/* This one is better stores in cpu values. */
+	cpus = cpu_map__new("1,256");
+
+	TEST_ASSERT_VAL("failed to synthesize map",
+		!perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL));
+
+	cpu_map__put(cpus);
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 3fe52ccc4d05..f85160f6ebb8 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -80,6 +80,7 @@ const char *test__bpf_subtest_get_desc(int subtest);
 int test__bpf_subtest_get_nr(void);
 int test_session_topology(int subtest);
 int test__thread_map_synthesize(int subtest);
+int test__cpu_map_synthesize(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 719c0781a82a..15d6466a4b8f 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -737,6 +737,137 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,
 	return err;
 }
 
+static void synthesize_cpus(struct cpu_map_entries *cpus,
+			    struct cpu_map *map)
+{
+	int i;
+
+	cpus->nr = map->nr;
+
+	for (i = 0; i < map->nr; i++)
+		cpus->cpu[i] = map->map[i];
+}
+
+static void synthesize_mask(struct cpu_map_mask *mask,
+			    struct cpu_map *map, int max)
+{
+	int i;
+
+	mask->nr = BITS_TO_LONGS(max);
+	mask->long_size = sizeof(long);
+
+	for (i = 0; i < map->nr; i++)
+		set_bit(map->map[i], mask->mask);
+}
+
+static size_t cpus_size(struct cpu_map *map)
+{
+	return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16);
+}
+
+static size_t mask_size(struct cpu_map *map, int *max)
+{
+	int i;
+
+	*max = 0;
+
+	for (i = 0; i < map->nr; i++) {
+		/* bit possition of the cpu is + 1 */
+		int bit = map->map[i] + 1;
+
+		if (bit > *max)
+			*max = bit;
+	}
+
+	return sizeof(struct cpu_map_mask) + BITS_TO_LONGS(*max) * sizeof(long);
+}
+
+void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max)
+{
+	size_t size_cpus, size_mask;
+	bool is_dummy = cpu_map__empty(map);
+
+	/*
+	 * Both array and mask data have variable size based
+	 * on the number of cpus and their actual values.
+	 * The size of the 'struct cpu_map_data' is:
+	 *
+	 *   array = size of 'struct cpu_map_entries' +
+	 *           number of cpus * sizeof(u64)
+	 *
+	 *   mask  = size of 'struct cpu_map_mask' +
+	 *           maximum cpu bit converted to size of longs
+	 *
+	 * and finaly + the size of 'struct cpu_map_data'.
+	 */
+	size_cpus = cpus_size(map);
+	size_mask = mask_size(map, max);
+
+	if (is_dummy || (size_cpus < size_mask)) {
+		*size += size_cpus;
+		*type  = PERF_CPU_MAP__CPUS;
+	} else {
+		*size += size_mask;
+		*type  = PERF_CPU_MAP__MASK;
+	}
+
+	*size += sizeof(struct cpu_map_data);
+	return zalloc(*size);
+}
+
+void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map,
+			      u16 type, int max)
+{
+	data->type = type;
+
+	switch (type) {
+	case PERF_CPU_MAP__CPUS:
+		synthesize_cpus((struct cpu_map_entries *) data->data, map);
+		break;
+	case PERF_CPU_MAP__MASK:
+		synthesize_mask((struct cpu_map_mask *) data->data, map, max);
+	default:
+		break;
+	};
+}
+
+static struct cpu_map_event* cpu_map_event__new(struct cpu_map *map)
+{
+	size_t size = sizeof(struct cpu_map_event);
+	struct cpu_map_event *event;
+	int max;
+	u16 type;
+
+	event = cpu_map_data__alloc(map, &size, &type, &max);
+	if (!event)
+		return NULL;
+
+	event->header.type = PERF_RECORD_CPU_MAP;
+	event->header.size = size;
+	event->data.type   = type;
+
+	cpu_map_data__synthesize(&event->data, map, type, max);
+	return event;
+}
+
+int perf_event__synthesize_cpu_map(struct perf_tool *tool,
+				   struct cpu_map *map,
+				   perf_event__handler_t process,
+				   struct machine *machine)
+{
+	struct cpu_map_event *event;
+	int err;
+
+	event = cpu_map_event__new(map);
+	if (!event)
+		return -ENOMEM;
+
+	err = process(tool, (union perf_event *) event, NULL, machine);
+
+	free(event);
+	return err;
+}
+
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
 	const char *s;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1c82a0ebda73..de18ee0e9c96 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -425,6 +425,7 @@ void perf_event__print_totals(void);
 
 struct perf_tool;
 struct thread_map;
+struct cpu_map;
 
 typedef int (*perf_event__handler_t)(struct perf_tool *tool,
 				     union perf_event *event,
@@ -440,6 +441,10 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,
 				      struct thread_map *threads,
 				      perf_event__handler_t process,
 				      struct machine *machine);
+int perf_event__synthesize_cpu_map(struct perf_tool *tool,
+				   struct cpu_map *cpus,
+				   perf_event__handler_t process,
+				   struct machine *machine);
 int perf_event__synthesize_threads(struct perf_tool *tool,
 				   perf_event__handler_t process,
 				   struct machine *machine, bool mmap_data,
@@ -550,4 +555,7 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp);
 u64 kallsyms__get_function_start(const char *kallsyms_filename,
 				 const char *symbol_name);
 
+void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max);
+void  cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map,
+			       u16 type, int max);
 #endif /* __PERF_RECORD_H */
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294194 — [PATCH 10/43] perf tools: Add stat config event synthesize function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 10/43] perf tools: Add stat config event synthesize function
Message-ID<qGMSu-3Qg-19@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introduce the perf_event__synthesize_stat_config to synthesize a 'struct
perf_stat_config'.

Storing the stat config in the form of tag-value pairs will, I believe,
sort out future version extensibility issues.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-13-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/stat.c         | 53 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/event.c         | 40 +++++++++++++++++++++++++++++++
 tools/perf/util/event.h         |  5 ++++
 6 files changed, 104 insertions(+)
 create mode 100644 tools/perf/tests/stat.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 7abad28fe17e..fc0293150f93 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -35,6 +35,7 @@ perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o
 perf-y += bpf.o
 perf-y += topology.o
 perf-y += cpumap.o
+perf-y += stat.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0c3fe2846de8..ed8402f339fa 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -188,6 +188,10 @@ static struct test generic_tests[] = {
 		.func = test__cpu_map_synthesize,
 	},
 	{
+		.desc = "Test stat config synthesize",
+		.func = test__synthesize_stat_config,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
new file mode 100644
index 000000000000..c7a2bdb97708
--- /dev/null
+++ b/tools/perf/tests/stat.c
@@ -0,0 +1,53 @@
+#include <linux/compiler.h>
+#include "event.h"
+#include "tests.h"
+#include "stat.h"
+#include "debug.h"
+
+static bool has_term(struct stat_config_event *config,
+		     u64 tag, u64 val)
+{
+	unsigned i;
+
+	for (i = 0; i < config->nr; i++) {
+		if ((config->data[i].tag == tag) &&
+		    (config->data[i].val == val))
+			return true;
+	}
+
+	return false;
+}
+
+static int process_event(struct perf_tool *tool __maybe_unused,
+			 union perf_event *event,
+			 struct perf_sample *sample __maybe_unused,
+			 struct machine *machine __maybe_unused)
+{
+	struct stat_config_event *config = &event->stat_config;
+
+#define HAS(term, val) \
+	has_term(config, PERF_STAT_CONFIG_TERM__##term, val)
+
+	TEST_ASSERT_VAL("wrong nr",        config->nr == PERF_STAT_CONFIG_TERM__MAX);
+	TEST_ASSERT_VAL("wrong aggr_mode", HAS(AGGR_MODE, AGGR_CORE));
+	TEST_ASSERT_VAL("wrong scale",     HAS(SCALE, 1));
+	TEST_ASSERT_VAL("wrong interval",  HAS(INTERVAL, 1));
+
+#undef HAS
+
+	return 0;
+}
+
+int test__synthesize_stat_config(int subtest __maybe_unused)
+{
+	struct perf_stat_config stat_config = {
+		.aggr_mode	= AGGR_CORE,
+		.scale		= 1,
+		.interval	= 1,
+	};
+
+	TEST_ASSERT_VAL("failed to synthesize stat_config",
+		!perf_event__synthesize_stat_config(NULL, &stat_config, process_event, NULL));
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index f85160f6ebb8..319757a3ca69 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -81,6 +81,7 @@ int test__bpf_subtest_get_nr(void);
 int test_session_topology(int subtest);
 int test__thread_map_synthesize(int subtest);
 int test__cpu_map_synthesize(int subtest);
+int test__synthesize_stat_config(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 43e2dfc2c73b..1ea693c2a14b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -10,6 +10,8 @@
 #include "thread.h"
 #include "thread_map.h"
 #include "symbol/kallsyms.h"
+#include "asm/bug.h"
+#include "stat.h"
 
 static const char *perf_event__names[] = {
 	[0]					= "TOTAL",
@@ -869,6 +871,44 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,
 	return err;
 }
 
+int perf_event__synthesize_stat_config(struct perf_tool *tool,
+				       struct perf_stat_config *config,
+				       perf_event__handler_t process,
+				       struct machine *machine)
+{
+	struct stat_config_event *event;
+	int size, i = 0, err;
+
+	size  = sizeof(*event);
+	size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0]));
+
+	event = zalloc(size);
+	if (!event)
+		return -ENOMEM;
+
+	event->header.type = PERF_RECORD_STAT_CONFIG;
+	event->header.size = size;
+	event->nr          = PERF_STAT_CONFIG_TERM__MAX;
+
+#define ADD(__term, __val)					\
+	event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term;	\
+	event->data[i].val = __val;				\
+	i++;
+
+	ADD(AGGR_MODE,	config->aggr_mode)
+	ADD(INTERVAL,	config->interval)
+	ADD(SCALE,	config->scale)
+
+	WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX,
+		  "stat config terms unbalanced\n");
+#undef ADD
+
+	err = process(tool, (union perf_event *) event, NULL, machine);
+
+	free(event);
+	return err;
+}
+
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
 	const char *s;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 16cee44de56b..39014c7c5a5b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -446,6 +446,7 @@ void perf_event__print_totals(void);
 struct perf_tool;
 struct thread_map;
 struct cpu_map;
+struct perf_stat_config;
 
 typedef int (*perf_event__handler_t)(struct perf_tool *tool,
 				     union perf_event *event,
@@ -472,6 +473,10 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
 				       perf_event__handler_t process,
 				       struct machine *machine);
+int perf_event__synthesize_stat_config(struct perf_tool *tool,
+				       struct perf_stat_config *config,
+				       perf_event__handler_t process,
+				       struct machine *machine);
 
 int perf_event__synthesize_modules(struct perf_tool *tool,
 				   perf_event__handler_t process,
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294195 — [PATCH 19/43] perf tools: Add event_update event unit type

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 19/43] perf tools: Add event_update event unit type
Message-ID<qGMSv-3Qg-21@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding unit type 'event update' event, that stores/transfer events unit
name. The unit name is part of the perf stat output data.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-22-git-send-email-jolsa@kernel.org
[ Rename __alloc() to __new() for consistency ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/event_update.c | 42 +++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/event.h         |  4 ++++
 tools/perf/util/header.c        | 44 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.h        |  3 +++
 7 files changed, 99 insertions(+)
 create mode 100644 tools/perf/tests/event_update.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index fc0293150f93..614899b88b37 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -36,6 +36,7 @@ perf-y += bpf.o
 perf-y += topology.o
 perf-y += cpumap.o
 perf-y += stat.o
+perf-y += event_update.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 6a3519814492..f2b1dcac45d3 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -200,6 +200,10 @@ static struct test generic_tests[] = {
 		.func = test__synthesize_stat_round,
 	},
 	{
+		.desc = "Test attr update synthesize",
+		.func = test__event_update,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
new file mode 100644
index 000000000000..9cdf4c934977
--- /dev/null
+++ b/tools/perf/tests/event_update.c
@@ -0,0 +1,42 @@
+#include <linux/compiler.h>
+#include "evlist.h"
+#include "evsel.h"
+#include "machine.h"
+#include "tests.h"
+#include "debug.h"
+
+static int process_event_unit(struct perf_tool *tool __maybe_unused,
+			      union perf_event *event,
+			      struct perf_sample *sample __maybe_unused,
+			      struct machine *machine __maybe_unused)
+{
+	struct event_update_event *ev = (struct event_update_event *) event;
+
+	TEST_ASSERT_VAL("wrong id", ev->id == 123);
+	TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__UNIT);
+	TEST_ASSERT_VAL("wrong unit", !strcmp(ev->data, "KRAVA"));
+	return 0;
+}
+
+int test__event_update(int subtest __maybe_unused)
+{
+	struct perf_evlist *evlist;
+	struct perf_evsel *evsel;
+
+	evlist = perf_evlist__new_default();
+	TEST_ASSERT_VAL("failed to get evlist", evlist);
+
+	evsel = perf_evlist__first(evlist);
+
+	TEST_ASSERT_VAL("failed to allos ids",
+			!perf_evsel__alloc_id(evsel, 1, 1));
+
+	perf_evlist__id_add(evlist, evsel, 0, 0, 123);
+
+	evsel->unit = strdup("KRAVA");
+
+	TEST_ASSERT_VAL("failed to synthesize attr update unit",
+			!perf_event__synthesize_event_update_unit(NULL, evsel, process_event_unit));
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a82ab9c4c0ca..82b2b5e6ba7c 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -84,6 +84,7 @@ int test__cpu_map_synthesize(int subtest);
 int test__synthesize_stat_config(int subtest);
 int test__synthesize_stat(int subtest);
 int test__synthesize_stat_round(int subtest);
+int test__event_update(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 6966a4b7c0f0..64c4cdf5aada 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -308,6 +308,10 @@ struct attr_event {
 	u64 id[];
 };
 
+enum {
+	PERF_EVENT_UPDATE__UNIT  = 0,
+};
+
 struct event_update_event {
 	struct perf_event_header header;
 	u64 type;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6b4e00220a5a..5759ebfde666 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2686,6 +2686,43 @@ int perf_event__synthesize_attr(struct perf_tool *tool,
 	return err;
 }
 
+static struct event_update_event *
+event_update_event__new(size_t size, u64 type, u64 id)
+{
+	struct event_update_event *ev;
+
+	size += sizeof(*ev);
+	size  = PERF_ALIGN(size, sizeof(u64));
+
+	ev = zalloc(size);
+	if (ev) {
+		ev->header.type = PERF_RECORD_EVENT_UPDATE;
+		ev->header.size = (u16)size;
+		ev->type = type;
+		ev->id = id;
+	}
+	return ev;
+}
+
+int
+perf_event__synthesize_event_update_unit(struct perf_tool *tool,
+					 struct perf_evsel *evsel,
+					 perf_event__handler_t process)
+{
+	struct event_update_event *ev;
+	size_t size = strlen(evsel->unit);
+	int err;
+
+	ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]);
+	if (ev == NULL)
+		return -ENOMEM;
+
+	strncpy(ev->data, evsel->unit, size);
+	err = process(tool, (union perf_event *)ev, NULL, NULL);
+	free(ev);
+	return err;
+}
+
 int perf_event__synthesize_attrs(struct perf_tool *tool,
 				   struct perf_session *session,
 				   perf_event__handler_t process)
@@ -2762,6 +2799,13 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
 	if (evsel == NULL)
 		return -EINVAL;
 
+	switch (ev->type) {
+	case PERF_EVENT_UPDATE__UNIT:
+		evsel->unit = strdup(ev->data);
+	default:
+		break;
+	}
+
 	return 0;
 }
 
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 1e843c67a4ff..6aa2b9242fc1 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -105,6 +105,9 @@ int perf_event__synthesize_attr(struct perf_tool *tool,
 int perf_event__synthesize_attrs(struct perf_tool *tool,
 				 struct perf_session *session,
 				 perf_event__handler_t process);
+int perf_event__synthesize_event_update_unit(struct perf_tool *tool,
+					     struct perf_evsel *evsel,
+					     perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
 int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294196 — [PATCH 09/43] perf tools: Add stat config user level event

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 09/43] perf tools: Add stat config user level event
Message-ID<qGMSv-3Qg-23@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding the stat config event to pass/store stat config data, so report
tools (report/script) know how to interpret stat data.

The config data is stored in a 'tag|value' way to allow for easy
extension and backwards compatibility.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-12-git-send-email-jolsa@kernel.org
[ stat_config_term_event -> stat_config_event_entry ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   | 20 ++++++++++++++++++++
 tools/perf/util/session.c | 24 ++++++++++++++++++++++++
 tools/perf/util/tool.h    |  3 ++-
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f31ab3b8f918..43e2dfc2c73b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -39,6 +39,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_AUXTRACE_ERROR]		= "AUXTRACE_ERROR",
 	[PERF_RECORD_THREAD_MAP]		= "THREAD_MAP",
 	[PERF_RECORD_CPU_MAP]			= "CPU_MAP",
+	[PERF_RECORD_STAT_CONFIG]		= "STAT_CONFIG",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 74a434116b2c..16cee44de56b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -228,6 +228,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_AUXTRACE_ERROR		= 72,
 	PERF_RECORD_THREAD_MAP			= 73,
 	PERF_RECORD_CPU_MAP			= 74,
+	PERF_RECORD_STAT_CONFIG			= 75,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -395,6 +396,24 @@ struct thread_map_event {
 	struct thread_map_event_entry	entries[];
 };
 
+enum {
+	PERF_STAT_CONFIG_TERM__AGGR_MODE	= 0,
+	PERF_STAT_CONFIG_TERM__INTERVAL		= 1,
+	PERF_STAT_CONFIG_TERM__SCALE		= 2,
+	PERF_STAT_CONFIG_TERM__MAX		= 3,
+};
+
+struct stat_config_event_entry {
+	u64	tag;
+	u64	val;
+};
+
+struct stat_config_event {
+	struct perf_event_header	header;
+	u64				nr;
+	struct stat_config_event_entry	data[];
+};
+
 union perf_event {
 	struct perf_event_header	header;
 	struct mmap_event		mmap;
@@ -419,6 +438,7 @@ union perf_event {
 	struct context_switch_event	context_switch;
 	struct thread_map_event		thread_map;
 	struct cpu_map_event		cpu_map;
+	struct stat_config_event	stat_config;
 };
 
 void perf_event__print_totals(void);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4350f5e85bf5..fbc52ab3eb75 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -315,6 +315,15 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static
+int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,
+				   union perf_event *event __maybe_unused,
+				   struct perf_session *session __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
@@ -369,6 +378,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->thread_map = process_event_thread_map_stub;
 	if (tool->cpu_map == NULL)
 		tool->cpu_map = process_event_cpu_map_stub;
+	if (tool->stat_config == NULL)
+		tool->stat_config = process_event_stat_config_stub;
 }
 
 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -686,6 +697,16 @@ static void perf_event__cpu_map_swap(union perf_event *event,
 	}
 }
 
+static void perf_event__stat_config_swap(union perf_event *event,
+					 bool sample_id_all __maybe_unused)
+{
+	u64 size;
+
+	size  = event->stat_config.nr * sizeof(event->stat_config.data[0]);
+	size += 1; /* nr item itself */
+	mem_bswap_64(&event->stat_config.nr, size);
+}
+
 typedef void (*perf_event__swap_op)(union perf_event *event,
 				    bool sample_id_all);
 
@@ -715,6 +736,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_AUXTRACE_ERROR]	  = perf_event__auxtrace_error_swap,
 	[PERF_RECORD_THREAD_MAP]	  = perf_event__thread_map_swap,
 	[PERF_RECORD_CPU_MAP]		  = perf_event__cpu_map_swap,
+	[PERF_RECORD_STAT_CONFIG]	  = perf_event__stat_config_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1255,6 +1277,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 		return tool->thread_map(tool, event, session);
 	case PERF_RECORD_CPU_MAP:
 		return tool->cpu_map(tool, event, session);
+	case PERF_RECORD_STAT_CONFIG:
+		return tool->stat_config(tool, event, session);
 	default:
 		return -EINVAL;
 	}
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 9e5925c78519..aa7ae73d76b4 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -57,7 +57,8 @@ struct perf_tool {
 			auxtrace_info,
 			auxtrace_error,
 			thread_map,
-			cpu_map;
+			cpu_map,
+			stat_config;
 	event_op3	auxtrace;
 	bool		ordered_events;
 	bool		ordering_requires_timestamps;
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294197 — [PATCH 25/43] perf tools: Introduce stat perf.data header feature

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 25/43] perf tools: Introduce stat perf.data header feature
Message-ID<qGMSv-3Qg-27@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introducing the 'stat' feature to mark a perf.data as created by  the
'perf stat record' command. It contains no data.

It's needed so that the report tools (report/script) can differentiate
sampling data from counting data, because they need to be treated in a
different way.

In the future it might be used to store the version of the stat storage
system used.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-28-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c |  2 ++
 tools/perf/util/header.c    | 14 ++++++++++++++
 tools/perf/util/header.h    |  1 +
 3 files changed, 17 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1435ef6265b6..9c5cdc2c4471 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -452,6 +452,8 @@ static void record__init_features(struct record *rec)
 
 	if (!rec->opts.full_auxtrace)
 		perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
+
+	perf_header__clear_feat(&session->header, HEADER_STAT);
 }
 
 static volatile int workload_exec_errno;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 49676c14c8ae..f50b7235ecb6 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -868,6 +868,13 @@ static int write_auxtrace(int fd, struct perf_header *h,
 	return err;
 }
 
+static int write_stat(int fd __maybe_unused,
+		      struct perf_header *h __maybe_unused,
+		      struct perf_evlist *evlist __maybe_unused)
+{
+	return 0;
+}
+
 static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
 			   FILE *fp)
 {
@@ -1159,6 +1166,12 @@ static void print_auxtrace(struct perf_header *ph __maybe_unused,
 	fprintf(fp, "# contains AUX area data (e.g. instruction trace)\n");
 }
 
+static void print_stat(struct perf_header *ph __maybe_unused,
+		       int fd __maybe_unused, FILE *fp)
+{
+	fprintf(fp, "# contains stat data\n");
+}
+
 static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused,
 			       FILE *fp)
 {
@@ -1948,6 +1961,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
 	FEAT_OPP(HEADER_PMU_MAPPINGS,	pmu_mappings),
 	FEAT_OPP(HEADER_GROUP_DESC,	group_desc),
 	FEAT_OPP(HEADER_AUXTRACE,	auxtrace),
+	FEAT_OPA(HEADER_STAT,		stat),
 };
 
 struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 710deecf8f80..cff9892452ee 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -31,6 +31,7 @@ enum {
 	HEADER_PMU_MAPPINGS,
 	HEADER_GROUP_DESC,
 	HEADER_AUXTRACE,
+	HEADER_STAT,
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
 };
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294198 — [PATCH 24/43] perf report: Display newly added events in raw dump

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 24/43] perf report: Display newly added events in raw dump
Message-ID<qGMSu-3Qg-17@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

The 'perf report -D' command will now display detailed output for these
newly added events:

  event_update
  thread_map
  cpu_map
  stat
  stat_config
  stat_round

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-27-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/session.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 49e5cdc4cc5a..a90c74b67e43 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -17,6 +17,7 @@
 #include "asm/bug.h"
 #include "auxtrace.h"
 #include "thread-stack.h"
+#include "stat.h"
 
 static int perf_session__deliver_event(struct perf_session *session,
 				       union perf_event *event,
@@ -210,6 +211,9 @@ static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_
 						 struct perf_evlist **pevlist
 						 __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_event_update(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
@@ -311,6 +315,9 @@ int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,
 				  union perf_event *event __maybe_unused,
 				  struct perf_session *session __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_thread_map(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
@@ -320,6 +327,9 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,
 			       union perf_event *event __maybe_unused,
 			       struct perf_session *session __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_cpu_map(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
@@ -329,6 +339,9 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,
 				   union perf_event *event __maybe_unused,
 				   struct perf_session *session __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_stat_config(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
@@ -338,6 +351,9 @@ static int process_stat_stub(struct perf_tool *tool __maybe_unused,
 			     struct perf_session *perf_session
 			     __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_stat(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
@@ -347,6 +363,9 @@ static int process_stat_round_stub(struct perf_tool *tool __maybe_unused,
 				   struct perf_session *perf_session
 				   __maybe_unused)
 {
+	if (dump_trace)
+		perf_event__fprintf_stat_round(event, stdout);
+
 	dump_printf(": unhandled!\n");
 	return 0;
 }
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294199 — [PATCH 07/43] perf cpu_map: Add cpu_map__new_event function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 07/43] perf cpu_map: Add cpu_map__new_event function
Message-ID<qGMSu-3Qg-5@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introducing the cpu_map__new_event function to create a struct cpu_map
object from a cpu_map event.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-10-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/cpumap.c | 25 +++++++++++++++++++++----
 tools/perf/util/cpumap.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/cpumap.h  |  1 +
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
index 715480558088..4cb6418a8ffc 100644
--- a/tools/perf/tests/cpumap.c
+++ b/tools/perf/tests/cpumap.c
@@ -6,12 +6,13 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,
 			 struct perf_sample *sample __maybe_unused,
 			 struct machine *machine __maybe_unused)
 {
-	struct cpu_map_event *map = &event->cpu_map;
+	struct cpu_map_event *map_event = &event->cpu_map;
 	struct cpu_map_mask *mask;
 	struct cpu_map_data *data;
+	struct cpu_map *map;
 	int i;
 
-	data = &map->data;
+	data = &map_event->data;
 
 	TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK);
 
@@ -23,6 +24,14 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,
 		TEST_ASSERT_VAL("wrong cpu", test_bit(i, mask->mask));
 	}
 
+	map = cpu_map__new_data(data);
+	TEST_ASSERT_VAL("wrong nr",  map->nr == 20);
+
+	for (i = 0; i < 20; i++) {
+		TEST_ASSERT_VAL("wrong cpu", map->map[i] == i);
+	}
+
+	cpu_map__put(map);
 	return 0;
 }
 
@@ -31,11 +40,12 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
 			 struct perf_sample *sample __maybe_unused,
 			 struct machine *machine __maybe_unused)
 {
-	struct cpu_map_event *map = &event->cpu_map;
+	struct cpu_map_event *map_event = &event->cpu_map;
 	struct cpu_map_entries *cpus;
 	struct cpu_map_data *data;
+	struct cpu_map *map;
 
-	data = &map->data;
+	data = &map_event->data;
 
 	TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__CPUS);
 
@@ -44,6 +54,13 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
 	TEST_ASSERT_VAL("wrong nr",   cpus->nr == 2);
 	TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[0] == 1);
 	TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[1] == 256);
+
+	map = cpu_map__new_data(data);
+	TEST_ASSERT_VAL("wrong nr",  map->nr == 2);
+	TEST_ASSERT_VAL("wrong cpu", map->map[0] == 1);
+	TEST_ASSERT_VAL("wrong cpu", map->map[1] == 256);
+	TEST_ASSERT_VAL("wrong refcnt", atomic_read(&map->refcnt) == 1);
+	cpu_map__put(map);
 	return 0;
 }
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 10af1e7524fb..a0717b93d8f5 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -5,6 +5,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <linux/bitmap.h>
 #include "asm/bug.h"
 
 static struct cpu_map *cpu_map__default_new(void)
@@ -179,6 +180,47 @@ out:
 	return cpus;
 }
 
+static struct cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus)
+{
+	struct cpu_map *map;
+
+	map = cpu_map__empty_new(cpus->nr);
+	if (map) {
+		unsigned i;
+
+		for (i = 0; i < cpus->nr; i++)
+			map->map[i] = (int)cpus->cpu[i];
+	}
+
+	return map;
+}
+
+static struct cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask)
+{
+	struct cpu_map *map;
+	int nr, nbits = mask->nr * mask->long_size * BITS_PER_BYTE;
+
+	nr = bitmap_weight(mask->mask, nbits);
+
+	map = cpu_map__empty_new(nr);
+	if (map) {
+		int cpu, i = 0;
+
+		for_each_set_bit(cpu, mask->mask, nbits)
+			map->map[i++] = cpu;
+	}
+	return map;
+
+}
+
+struct cpu_map *cpu_map__new_data(struct cpu_map_data *data)
+{
+	if (data->type == PERF_CPU_MAP__CPUS)
+		return cpu_map__from_entries((struct cpu_map_entries *)data->data);
+	else
+		return cpu_map__from_mask((struct cpu_map_mask *)data->data);
+}
+
 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp)
 {
 	int i;
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 85f7772457fa..71c41b9efabb 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -17,6 +17,7 @@ struct cpu_map {
 struct cpu_map *cpu_map__new(const char *cpu_list);
 struct cpu_map *cpu_map__empty_new(int nr);
 struct cpu_map *cpu_map__dummy_new(void);
+struct cpu_map *cpu_map__new_data(struct cpu_map_data *data);
 struct cpu_map *cpu_map__read(FILE *file);
 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
 int cpu_map__get_socket_id(int cpu);
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294200 — [PATCH 40/43] perf stat report: Move csv_sep initialization before report command

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 40/43] perf stat report: Move csv_sep initialization before report command
Message-ID<qGMSu-3Qg-11@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

So we have csv_sep properly initialized before report command leg.

Reported-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1446734469-11352-18-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c78052580023..f9d4e0963ac7 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1776,6 +1776,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 					(const char **) stat_usage,
 					PARSE_OPT_STOP_AT_NON_OPTION);
 
+	if (csv_sep) {
+		csv_output = true;
+		if (!strcmp(csv_sep, "\\t"))
+			csv_sep = "\t";
+	} else
+		csv_sep = DEFAULT_SEPARATOR;
+
 	if (argc && !strncmp(argv[0], "rec", 3)) {
 		argc = __cmd_record(argc, argv);
 		if (argc < 0)
@@ -1826,13 +1833,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	stat_config.output = output;
 
-	if (csv_sep) {
-		csv_output = true;
-		if (!strcmp(csv_sep, "\\t"))
-			csv_sep = "\t";
-	} else
-		csv_sep = DEFAULT_SEPARATOR;
-
 	/*
 	 * let the spreadsheet do the pretty-printing
 	 */
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294201 — [PATCH 05/43] perf cpu_map: Add cpu_map user level event

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 05/43] perf cpu_map: Add cpu_map user level event
Message-ID<qGMSv-3Qg-29@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding the cpu_map event to pass/store cpu maps as data in
a pipe/perf.data.

We store maps in 2 formats:
  - list of cpus
  - mask of cpus

The format that takes less space is selected transparently in the
following patch.

The interface is made generic, so we could add the cpumap event data
into another event in the following patches.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-8-git-send-email-jolsa@kernel.org
[ cpu_map_data_cpus -> cpu_map_entries, cpu_map_data_mask -> cpu_map_mask ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   | 28 ++++++++++++++++++++++++++
 tools/perf/util/session.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/tool.h    |  3 ++-
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 938f006c758e..719c0781a82a 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -38,6 +38,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_AUXTRACE]			= "AUXTRACE",
 	[PERF_RECORD_AUXTRACE_ERROR]		= "AUXTRACE_ERROR",
 	[PERF_RECORD_THREAD_MAP]		= "THREAD_MAP",
+	[PERF_RECORD_CPU_MAP]			= "CPU_MAP",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index b7ad896d1317..1c82a0ebda73 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -227,6 +227,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_AUXTRACE			= 71,
 	PERF_RECORD_AUXTRACE_ERROR		= 72,
 	PERF_RECORD_THREAD_MAP			= 73,
+	PERF_RECORD_CPU_MAP			= 74,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -271,6 +272,32 @@ struct events_stats {
 	u32 nr_proc_map_timeout;
 };
 
+enum {
+	PERF_CPU_MAP__CPUS = 0,
+	PERF_CPU_MAP__MASK = 1,
+};
+
+struct cpu_map_entries {
+	u16	nr;
+	u16	cpu[];
+};
+
+struct cpu_map_mask {
+	u16	nr;
+	u16	long_size;
+	unsigned long mask[];
+};
+
+struct cpu_map_data {
+	u16	type;
+	char	data[];
+};
+
+struct cpu_map_event {
+	struct perf_event_header	header;
+	struct cpu_map_data		data;
+};
+
 struct attr_event {
 	struct perf_event_header header;
 	struct perf_event_attr attr;
@@ -391,6 +418,7 @@ union perf_event {
 	struct itrace_start_event	itrace_start;
 	struct context_switch_event	context_switch;
 	struct thread_map_event		thread_map;
+	struct cpu_map_event		cpu_map;
 };
 
 void perf_event__print_totals(void);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 36b07b22392d..4350f5e85bf5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -306,6 +306,15 @@ int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static
+int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,
+			       union perf_event *event __maybe_unused,
+			       struct perf_session *session __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
@@ -358,6 +367,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->auxtrace_error = process_event_auxtrace_error_stub;
 	if (tool->thread_map == NULL)
 		tool->thread_map = process_event_thread_map_stub;
+	if (tool->cpu_map == NULL)
+		tool->cpu_map = process_event_cpu_map_stub;
 }
 
 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -639,6 +650,42 @@ static void perf_event__thread_map_swap(union perf_event *event,
 		event->thread_map.entries[i].pid = bswap_64(event->thread_map.entries[i].pid);
 }
 
+static void perf_event__cpu_map_swap(union perf_event *event,
+				     bool sample_id_all __maybe_unused)
+{
+	struct cpu_map_data *data = &event->cpu_map.data;
+	struct cpu_map_entries *cpus;
+	struct cpu_map_mask *mask;
+	unsigned i;
+
+	data->type = bswap_64(data->type);
+
+	switch (data->type) {
+	case PERF_CPU_MAP__CPUS:
+		cpus = (struct cpu_map_entries *)data->data;
+
+		cpus->nr = bswap_16(cpus->nr);
+
+		for (i = 0; i < cpus->nr; i++)
+			cpus->cpu[i] = bswap_16(cpus->cpu[i]);
+		break;
+	case PERF_CPU_MAP__MASK:
+		mask = (struct cpu_map_mask *) data->data;
+
+		mask->nr = bswap_16(mask->nr);
+		mask->long_size = bswap_16(mask->long_size);
+
+		switch (mask->long_size) {
+		case 4: mem_bswap_32(&mask->mask, mask->nr); break;
+		case 8: mem_bswap_64(&mask->mask, mask->nr); break;
+		default:
+			pr_err("cpu_map swap: unsupported long size\n");
+		}
+	default:
+		break;
+	}
+}
+
 typedef void (*perf_event__swap_op)(union perf_event *event,
 				    bool sample_id_all);
 
@@ -667,6 +714,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_AUXTRACE]		  = perf_event__auxtrace_swap,
 	[PERF_RECORD_AUXTRACE_ERROR]	  = perf_event__auxtrace_error_swap,
 	[PERF_RECORD_THREAD_MAP]	  = perf_event__thread_map_swap,
+	[PERF_RECORD_CPU_MAP]		  = perf_event__cpu_map_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1205,6 +1253,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 		return tool->auxtrace_error(tool, event, session);
 	case PERF_RECORD_THREAD_MAP:
 		return tool->thread_map(tool, event, session);
+	case PERF_RECORD_CPU_MAP:
+		return tool->cpu_map(tool, event, session);
 	default:
 		return -EINVAL;
 	}
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 1af4774960c3..9e5925c78519 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -56,7 +56,8 @@ struct perf_tool {
 			id_index,
 			auxtrace_info,
 			auxtrace_error,
-			thread_map;
+			thread_map,
+			cpu_map;
 	event_op3	auxtrace;
 	bool		ordered_events;
 	bool		ordering_requires_timestamps;
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294202 — [PATCH 18/43] perf tools: Add event_update user level event

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 18/43] perf tools: Add event_update user level event
Message-ID<qGMSv-3Qg-35@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

It'll serve as a base event for additional event attributes details,
that are not part of the attr event.

At the moment this event is just a dummy one without any specific
functionality. The type value will distinguish the update event details.
It'll come in the following patches.

The idea for this event is to be extensible for any update that the
event might need in the future.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-21-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   | 10 ++++++++++
 tools/perf/util/header.c  | 20 ++++++++++++++++++++
 tools/perf/util/header.h  |  3 +++
 tools/perf/util/session.c | 21 +++++++++++++++++++++
 tools/perf/util/tool.h    |  1 +
 6 files changed, 56 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e4c68ba79974..cd61bb1f3917 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -44,6 +44,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_STAT_CONFIG]		= "STAT_CONFIG",
 	[PERF_RECORD_STAT]			= "STAT",
 	[PERF_RECORD_STAT_ROUND]		= "STAT_ROUND",
+	[PERF_RECORD_EVENT_UPDATE]		= "EVENT_UPDATE",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1afaa21eeebe..6966a4b7c0f0 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -231,6 +231,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_STAT_CONFIG			= 75,
 	PERF_RECORD_STAT			= 76,
 	PERF_RECORD_STAT_ROUND			= 77,
+	PERF_RECORD_EVENT_UPDATE		= 78,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -307,6 +308,14 @@ struct attr_event {
 	u64 id[];
 };
 
+struct event_update_event {
+	struct perf_event_header header;
+	u64 type;
+	u64 id;
+
+	char data[];
+};
+
 #define MAX_EVENT_NAME 64
 
 struct perf_trace_event_type {
@@ -456,6 +465,7 @@ union perf_event {
 	struct throttle_event		throttle;
 	struct sample_event		sample;
 	struct attr_event		attr;
+	struct event_update_event	event_update;
 	struct event_type_event		event_type;
 	struct tracing_data_event	tracing_data;
 	struct build_id_event		build_id;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 5ac7bdb0dff7..6b4e00220a5a 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2745,6 +2745,26 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
+				     union perf_event *event,
+				     struct perf_evlist **pevlist)
+{
+	struct event_update_event *ev = &event->event_update;
+	struct perf_evlist *evlist;
+	struct perf_evsel *evsel;
+
+	if (!pevlist || *pevlist == NULL)
+		return -EINVAL;
+
+	evlist = *pevlist;
+
+	evsel = perf_evlist__id2evsel(evlist, ev->id);
+	if (evsel == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
 int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
 					struct perf_evlist *evlist,
 					perf_event__handler_t process)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 05f27cb6b7e3..1e843c67a4ff 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -107,6 +107,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
 				 perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
+int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
+				     union perf_event *event,
+				     struct perf_evlist **pevlist);
 
 int perf_event__synthesize_tracing_data(struct perf_tool *tool,
 					int fd, struct perf_evlist *evlist,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5b3a81a6b795..49e5cdc4cc5a 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -205,6 +205,15 @@ static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_unused,
+						 union perf_event *event __maybe_unused,
+						 struct perf_evlist **pevlist
+						 __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 static int process_event_sample_stub(struct perf_tool *tool __maybe_unused,
 				     union perf_event *event __maybe_unused,
 				     struct perf_sample *sample __maybe_unused,
@@ -374,6 +383,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->unthrottle = process_event_stub;
 	if (tool->attr == NULL)
 		tool->attr = process_event_synth_attr_stub;
+	if (tool->event_update == NULL)
+		tool->event_update = process_event_synth_event_update_stub;
 	if (tool->tracing_data == NULL)
 		tool->tracing_data = process_event_synth_tracing_data_stub;
 	if (tool->build_id == NULL)
@@ -625,6 +636,13 @@ static void perf_event__hdr_attr_swap(union perf_event *event,
 	mem_bswap_64(event->attr.id, size);
 }
 
+static void perf_event__event_update_swap(union perf_event *event,
+					  bool sample_id_all __maybe_unused)
+{
+	event->event_update.type = bswap_64(event->event_update.type);
+	event->event_update.id   = bswap_64(event->event_update.id);
+}
+
 static void perf_event__event_type_swap(union perf_event *event,
 					bool sample_id_all __maybe_unused)
 {
@@ -779,6 +797,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_STAT_CONFIG]	  = perf_event__stat_config_swap,
 	[PERF_RECORD_STAT]		  = perf_event__stat_swap,
 	[PERF_RECORD_STAT_ROUND]	  = perf_event__stat_round_swap,
+	[PERF_RECORD_EVENT_UPDATE]	  = perf_event__event_update_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1290,6 +1309,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 			perf_session__set_comm_exec(session);
 		}
 		return err;
+	case PERF_RECORD_EVENT_UPDATE:
+		return tool->event_update(tool, event, &session->evlist);
 	case PERF_RECORD_HEADER_EVENT_TYPE:
 		/*
 		 * Depreceated, but we need to handle it for sake
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index d04d9e5f444a..55de4cffcd4e 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -50,6 +50,7 @@ struct perf_tool {
 			throttle,
 			unthrottle;
 	event_attr_op	attr;
+	event_attr_op	event_update;
 	event_op2	tracing_data;
 	event_oe	finished_round;
 	event_op2	build_id,
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294203 — [PATCH 22/43] perf tools: Add event_update event cpus type

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 22/43] perf tools: Add event_update event cpus type
Message-ID<qGMSv-3Qg-33@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding the cpumask 'event update' event, that stores/transfer the
cpumask for a event.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-25-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/event_update.c | 29 ++++++++++++++++++++++++++++
 tools/perf/util/event.h         |  5 +++++
 tools/perf/util/header.c        | 42 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.h        |  3 +++
 4 files changed, 79 insertions(+)

diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
index 482b89650bbe..012eab5d1df1 100644
--- a/tools/perf/tests/event_update.c
+++ b/tools/perf/tests/event_update.c
@@ -53,6 +53,29 @@ static int process_event_name(struct perf_tool *tool,
 	return 0;
 }
 
+static int process_event_cpus(struct perf_tool *tool __maybe_unused,
+			      union perf_event *event,
+			      struct perf_sample *sample __maybe_unused,
+			      struct machine *machine __maybe_unused)
+{
+	struct event_update_event *ev = (struct event_update_event*) event;
+	struct event_update_event_cpus *ev_data;
+	struct cpu_map *map;
+
+	ev_data = (struct event_update_event_cpus*) ev->data;
+
+	map = cpu_map__new_data(&ev_data->cpus);
+
+	TEST_ASSERT_VAL("wrong id", ev->id == 123);
+	TEST_ASSERT_VAL("wrong type", ev->type == PERF_EVENT_UPDATE__CPUS);
+	TEST_ASSERT_VAL("wrong cpus", map->nr == 3);
+	TEST_ASSERT_VAL("wrong cpus", map->map[0] == 1);
+	TEST_ASSERT_VAL("wrong cpus", map->map[1] == 2);
+	TEST_ASSERT_VAL("wrong cpus", map->map[2] == 3);
+	cpu_map__put(map);
+	return 0;
+}
+
 int test__event_update(int subtest __maybe_unused)
 {
 	struct perf_evlist *evlist;
@@ -84,5 +107,11 @@ int test__event_update(int subtest __maybe_unused)
 	TEST_ASSERT_VAL("failed to synthesize attr update name",
 			!perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name));
 
+	evsel->own_cpus = cpu_map__new("1,2,3");
+
+	TEST_ASSERT_VAL("failed to synthesize attr update cpus",
+			!perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus));
+
+	cpu_map__put(evsel->own_cpus);
 	return 0;
 }
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 235196b575d6..b7ffb7ee9971 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -312,6 +312,11 @@ enum {
 	PERF_EVENT_UPDATE__UNIT  = 0,
 	PERF_EVENT_UPDATE__SCALE = 1,
 	PERF_EVENT_UPDATE__NAME  = 2,
+	PERF_EVENT_UPDATE__CPUS  = 3,
+};
+
+struct event_update_event_cpus {
+	struct cpu_map_data cpus;
 };
 
 struct event_update_event_scale {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index cd3d005a34af..79d3eb984db7 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2762,6 +2762,38 @@ perf_event__synthesize_event_update_name(struct perf_tool *tool,
 	return err;
 }
 
+int
+perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
+					struct perf_evsel *evsel,
+					perf_event__handler_t process)
+{
+	size_t size = sizeof(struct event_update_event);
+	struct event_update_event *ev;
+	int max, err;
+	u16 type;
+
+	if (!evsel->own_cpus)
+		return 0;
+
+	ev = cpu_map_data__alloc(evsel->own_cpus, &size, &type, &max);
+	if (!ev)
+		return -ENOMEM;
+
+	ev->header.type = PERF_RECORD_EVENT_UPDATE;
+	ev->header.size = (u16)size;
+	ev->type = PERF_EVENT_UPDATE__CPUS;
+	ev->id   = evsel->id[0];
+
+	cpu_map_data__synthesize((struct cpu_map_data *) ev->data,
+				 evsel->own_cpus,
+				 type, max);
+
+	err = process(tool, (union perf_event*) ev, NULL, NULL);
+	free(ev);
+	return err;
+}
+
+
 int perf_event__synthesize_attrs(struct perf_tool *tool,
 				   struct perf_session *session,
 				   perf_event__handler_t process)
@@ -2827,8 +2859,10 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
 {
 	struct event_update_event *ev = &event->event_update;
 	struct event_update_event_scale *ev_scale;
+	struct event_update_event_cpus *ev_cpus;
 	struct perf_evlist *evlist;
 	struct perf_evsel *evsel;
+	struct cpu_map *map;
 
 	if (!pevlist || *pevlist == NULL)
 		return -EINVAL;
@@ -2849,6 +2883,14 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
 	case PERF_EVENT_UPDATE__SCALE:
 		ev_scale = (struct event_update_event_scale *) ev->data;
 		evsel->scale = ev_scale->scale;
+	case PERF_EVENT_UPDATE__CPUS:
+		ev_cpus = (struct event_update_event_cpus *) ev->data;
+
+		map = cpu_map__new_data(&ev_cpus->cpus);
+		if (map)
+			evsel->own_cpus = map;
+		else
+			pr_err("failed to get event_update cpus\n");
 	default:
 		break;
 	}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 51cf566a0835..a1bc0c5706a3 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -114,6 +114,9 @@ int perf_event__synthesize_event_update_scale(struct perf_tool *tool,
 int perf_event__synthesize_event_update_name(struct perf_tool *tool,
 					     struct perf_evsel *evsel,
 					     perf_event__handler_t process);
+int perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
+					     struct perf_evsel *evsel,
+					     perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
 int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294204 — [PATCH 29/43] perf evlist: Export id_add_fd()

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 29/43] perf evlist: Export id_add_fd()
Message-ID<qGMSv-3Qg-39@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Will be used to storing the event IDs in evlist object so it get stored
into perf.data file.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1446734469-11352-6-git-send-email-jolsa@kernel.org
[ Split from the patch storing the ids in the perf.data file ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evlist.c | 6 +++---
 tools/perf/util/evlist.h | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 8c44aadb9810..b9eac0daa0b9 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -534,9 +534,9 @@ void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
 	evsel->id[evsel->ids++] = id;
 }
 
-static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
-				  struct perf_evsel *evsel,
-				  int cpu, int thread, int fd)
+int perf_evlist__id_add_fd(struct perf_evlist *evlist,
+			   struct perf_evsel *evsel,
+			   int cpu, int thread, int fd)
 {
 	u64 read_data[4] = { 0, };
 	int id_idx = 1; /* The first entry is the counter value */
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index a459fe71b452..139a50038097 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -97,6 +97,9 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
 
 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
 			 int cpu, int thread, u64 id);
+int perf_evlist__id_add_fd(struct perf_evlist *evlist,
+			   struct perf_evsel *evsel,
+			   int cpu, int thread, int fd);
 
 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist);
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294205 — [PATCH 01/43] perf thread_map: Add thread_map user level event

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 01/43] perf thread_map: Add thread_map user level event
Message-ID<qGMSv-3Qg-37@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding the thread_map event to pass/store thread maps as data in
the pipe/perf.data.

Storing the thread ID along with the standard comm[16] thread name string.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-4-git-send-email-jolsa@kernel.org
[ Renamed thread_map_data_event to thread_map_event_entry ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   | 13 +++++++++++++
 tools/perf/util/session.c | 26 ++++++++++++++++++++++++++
 tools/perf/util/tool.h    |  3 ++-
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 8b10621b415c..771545a27b9b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -37,6 +37,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_AUXTRACE_INFO]		= "AUXTRACE_INFO",
 	[PERF_RECORD_AUXTRACE]			= "AUXTRACE",
 	[PERF_RECORD_AUXTRACE_ERROR]		= "AUXTRACE_ERROR",
+	[PERF_RECORD_THREAD_MAP]		= "THREAD_MAP",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index a0dbcbd4f6d8..66f303e69c4d 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -226,6 +226,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_AUXTRACE_INFO		= 70,
 	PERF_RECORD_AUXTRACE			= 71,
 	PERF_RECORD_AUXTRACE_ERROR		= 72,
+	PERF_RECORD_THREAD_MAP			= 73,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -356,6 +357,17 @@ struct context_switch_event {
 	u32 next_prev_tid;
 };
 
+struct thread_map_event_entry {
+	u64	pid;
+	char	comm[16];
+};
+
+struct thread_map_event {
+	struct perf_event_header	header;
+	u64				nr;
+	struct thread_map_event_entry	entries[];
+};
+
 union perf_event {
 	struct perf_event_header	header;
 	struct mmap_event		mmap;
@@ -378,6 +390,7 @@ union perf_event {
 	struct aux_event		aux;
 	struct itrace_start_event	itrace_start;
 	struct context_switch_event	context_switch;
+	struct thread_map_event		thread_map;
 };
 
 void perf_event__print_totals(void);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 9774686525b4..36b07b22392d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -296,6 +296,16 @@ int process_event_auxtrace_error_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+
+static
+int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,
+				  union perf_event *event __maybe_unused,
+				  struct perf_session *session __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
@@ -346,6 +356,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->auxtrace = process_event_auxtrace_stub;
 	if (tool->auxtrace_error == NULL)
 		tool->auxtrace_error = process_event_auxtrace_error_stub;
+	if (tool->thread_map == NULL)
+		tool->thread_map = process_event_thread_map_stub;
 }
 
 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -616,6 +628,17 @@ static void perf_event__auxtrace_error_swap(union perf_event *event,
 	event->auxtrace_error.ip   = bswap_64(event->auxtrace_error.ip);
 }
 
+static void perf_event__thread_map_swap(union perf_event *event,
+					bool sample_id_all __maybe_unused)
+{
+	unsigned i;
+
+	event->thread_map.nr = bswap_64(event->thread_map.nr);
+
+	for (i = 0; i < event->thread_map.nr; i++)
+		event->thread_map.entries[i].pid = bswap_64(event->thread_map.entries[i].pid);
+}
+
 typedef void (*perf_event__swap_op)(union perf_event *event,
 				    bool sample_id_all);
 
@@ -643,6 +666,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_AUXTRACE_INFO]	  = perf_event__auxtrace_info_swap,
 	[PERF_RECORD_AUXTRACE]		  = perf_event__auxtrace_swap,
 	[PERF_RECORD_AUXTRACE_ERROR]	  = perf_event__auxtrace_error_swap,
+	[PERF_RECORD_THREAD_MAP]	  = perf_event__thread_map_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1179,6 +1203,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 	case PERF_RECORD_AUXTRACE_ERROR:
 		perf_session__auxtrace_error_inc(session, event);
 		return tool->auxtrace_error(tool, event, session);
+	case PERF_RECORD_THREAD_MAP:
+		return tool->thread_map(tool, event, session);
 	default:
 		return -EINVAL;
 	}
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index cab8cc24831b..1af4774960c3 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -55,7 +55,8 @@ struct perf_tool {
 	event_op2	build_id,
 			id_index,
 			auxtrace_info,
-			auxtrace_error;
+			auxtrace_error,
+			thread_map;
 	event_op3	auxtrace;
 	bool		ordered_events;
 	bool		ordering_requires_timestamps;
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294206 — [PATCH 17/43] perf tools: Add stat events fprintf functions

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 17/43] perf tools: Add stat events fprintf functions
Message-ID<qGMSv-3Qg-41@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introducing the following functions to display the stat events for raw
dump.

  perf_event__fprintf_stat
  perf_event__fprintf_stat_round
  perf_event__fprintf_stat_config

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-20-git-send-email-jolsa@kernel.org
[ s/stat/st/g and s/round/rd/g parameters to fix 'already defined' build error with older distros (e.g. RHEL6.7) ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/stat.c | 39 +++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.h |  4 ++++
 2 files changed, 43 insertions(+)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 0ad59cea318c..2f901d15e063 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -364,3 +364,42 @@ int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused,
 	counter->supported = true;
 	return 0;
 }
+
+size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp)
+{
+	struct stat_event *st = (struct stat_event *) event;
+	size_t ret;
+
+	ret  = fprintf(fp, "\n... id %" PRIu64 ", cpu %d, thread %d\n",
+		       st->id, st->cpu, st->thread);
+	ret += fprintf(fp, "... value %" PRIu64 ", enabled %" PRIu64 ", running %" PRIu64 "\n",
+		       st->val, st->ena, st->run);
+
+	return ret;
+}
+
+size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp)
+{
+	struct stat_round_event *rd = (struct stat_round_event *)event;
+	size_t ret;
+
+	ret = fprintf(fp, "\n... time %" PRIu64 ", type %s\n", rd->time,
+		      rd->type == PERF_STAT_ROUND_TYPE__FINAL ? "FINAL" : "INTERVAL");
+
+	return ret;
+}
+
+size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp)
+{
+	struct perf_stat_config sc;
+	size_t ret;
+
+	perf_event__read_stat_config(&sc, &event->stat_config);
+
+	ret  = fprintf(fp, "\n");
+	ret += fprintf(fp, "... aggr_mode %d\n", sc.aggr_mode);
+	ret += fprintf(fp, "... scale     %d\n", sc.scale);
+	ret += fprintf(fp, "... interval  %u\n", sc.interval);
+
+	return ret;
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index afe6844e5219..086f4e128d63 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -96,4 +96,8 @@ struct perf_session;
 int perf_event__process_stat_event(struct perf_tool *tool,
 				   union perf_event *event,
 				   struct perf_session *session);
+
+size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);
 #endif
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294207 — [PATCH 39/43] perf stat report: Add support to initialize aggr_map from file

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 39/43] perf stat report: Add support to initialize aggr_map from file
Message-ID<qGMSw-3Qg-47@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Using perf.data's perf_env data to initialize aggregate config.

Reported-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1446734469-11352-15-git-send-email-jolsa@kernel.org
[ s/stat/st/g, s/socket/socket_id/g to fix 'already defined' build error with older distros (e.g. RHEL6.7) ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1e5db50dab9e..c78052580023 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1326,6 +1326,101 @@ static void perf_stat__exit_aggr_mode(void)
 	cpus_aggr_map = NULL;
 }
 
+static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx)
+{
+	int cpu;
+
+	if (idx > map->nr)
+		return -1;
+
+	cpu = map->map[idx];
+
+	if (cpu >= env->nr_cpus_online)
+		return -1;
+
+	return cpu;
+}
+
+static int perf_env__get_socket(struct cpu_map *map, int idx, void *data)
+{
+	struct perf_env *env = data;
+	int cpu = perf_env__get_cpu(env, map, idx);
+
+	return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
+}
+
+static int perf_env__get_core(struct cpu_map *map, int idx, void *data)
+{
+	struct perf_env *env = data;
+	int core = -1, cpu = perf_env__get_cpu(env, map, idx);
+
+	if (cpu != -1) {
+		int socket_id = env->cpu[cpu].socket_id;
+
+		/*
+		 * Encode socket in upper 16 bits
+		 * core_id is relative to socket, and
+		 * we need a global id. So we combine
+		 * socket + core id.
+		 */
+		core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff);
+	}
+
+	return core;
+}
+
+static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus,
+				      struct cpu_map **sockp)
+{
+	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
+}
+
+static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,
+				    struct cpu_map **corep)
+{
+	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
+}
+
+static int perf_stat__get_socket_file(struct cpu_map *map, int idx)
+{
+	return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
+}
+
+static int perf_stat__get_core_file(struct cpu_map *map, int idx)
+{
+	return perf_env__get_core(map, idx, &perf_stat.session->header.env);
+}
+
+static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
+{
+	struct perf_env *env = &st->session->header.env;
+
+	switch (stat_config.aggr_mode) {
+	case AGGR_SOCKET:
+		if (perf_env__build_socket_map(env, evsel_list->cpus, &aggr_map)) {
+			perror("cannot build socket map");
+			return -1;
+		}
+		aggr_get_id = perf_stat__get_socket_file;
+		break;
+	case AGGR_CORE:
+		if (perf_env__build_core_map(env, evsel_list->cpus, &aggr_map)) {
+			perror("cannot build core map");
+			return -1;
+		}
+		aggr_get_id = perf_stat__get_core_file;
+		break;
+	case AGGR_NONE:
+	case AGGR_GLOBAL:
+	case AGGR_THREAD:
+	case AGGR_UNSET:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 /*
  * Add default attributes, if there were no attributes specified or
  * if -d/--detailed, -d -d or -d -d -d is used:
@@ -1538,7 +1633,15 @@ int process_stat_config_event(struct perf_tool *tool __maybe_unused,
 			      union perf_event *event,
 			      struct perf_session *session __maybe_unused)
 {
+	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
+
 	perf_event__read_stat_config(&stat_config, &event->stat_config);
+
+	if (perf_stat.file.is_pipe)
+		perf_stat_init_aggr_mode();
+	else
+		perf_stat_init_aggr_mode_file(st);
+
 	return 0;
 }
 
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294208 — [PATCH 36/43] perf stat report: Add report command

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 36/43] perf stat report: Add report command
Message-ID<qGMSv-3Qg-43@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Adding 'perf stat report' command support. ATM it only processes attr
events and display nothing.

Reported-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1446734469-11352-12-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-stat.txt | 12 +++++++
 tools/perf/builtin-stat.c              | 61 +++++++++++++++++++++++++++++++---
 2 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 70eee1c2c444..95f492828657 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command>
 'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
 'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>]
+'perf stat' report [-i file]
 
 DESCRIPTION
 -----------
@@ -26,6 +27,9 @@ OPTIONS
 record::
 	See STAT RECORD.
 
+report::
+	See STAT REPORT.
+
 -e::
 --event=::
 	Select the PMU event. Selection can be:
@@ -170,6 +174,14 @@ Stores stat data into perf data file.
 --output file::
 Output file name.
 
+STAT REPORT
+-----------
+Reads and reports stat data from perf data file.
+
+-i file::
+--input file::
+Input file name.
+
 
 EXAMPLES
 --------
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 575e2535ea03..abba49b847d2 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -60,6 +60,8 @@
 #include "util/thread_map.h"
 #include "util/counts.h"
 #include "util/session.h"
+#include "util/tool.h"
+#include "asm/bug.h"
 
 #include <stdlib.h>
 #include <sys/prctl.h>
@@ -132,6 +134,7 @@ struct perf_stat {
 	struct perf_data_file	 file;
 	struct perf_session	*session;
 	u64			 bytes_written;
+	struct perf_tool	 tool;
 };
 
 static struct perf_stat		perf_stat;
@@ -1041,8 +1044,8 @@ static void print_header(int argc, const char **argv)
 		else if (target.cpu_list)
 			fprintf(output, "\'CPU(s) %s", target.cpu_list);
 		else if (!target__has_task(&target)) {
-			fprintf(output, "\'%s", argv[0]);
-			for (i = 1; i < argc; i++)
+			fprintf(output, "\'%s", argv ? argv[0] : "pipe");
+			for (i = 1; argv && (i < argc); i++)
 				fprintf(output, " %s", argv[i]);
 		} else if (target.pid)
 			fprintf(output, "process id \'%s", target.pid);
@@ -1527,6 +1530,55 @@ static int __cmd_record(int argc, const char **argv)
 	return argc;
 }
 
+static const char * const report_usage[] = {
+	"perf stat report [<options>]",
+	NULL,
+};
+
+static struct perf_stat perf_stat = {
+	.tool = {
+		.attr		= perf_event__process_attr,
+	},
+};
+
+static int __cmd_report(int argc, const char **argv)
+{
+	struct perf_session *session;
+	const struct option options[] = {
+	OPT_STRING('i', "input", &input_name, "file", "input file name"),
+	OPT_END()
+	};
+	struct stat st;
+	int ret;
+
+	argc = parse_options(argc, argv, options, report_usage, 0);
+
+	if (!input_name || !strlen(input_name)) {
+		if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
+			input_name = "-";
+		else
+			input_name = "perf.data";
+	}
+
+	perf_stat.file.path = input_name;
+	perf_stat.file.mode = PERF_DATA_MODE_READ;
+
+	session = perf_session__new(&perf_stat.file, false, &perf_stat.tool);
+	if (session == NULL)
+		return -1;
+
+	perf_stat.session  = session;
+	stat_config.output = stderr;
+	evsel_list         = session->evlist;
+
+	ret = perf_session__process_events(session);
+	if (ret)
+		return ret;
+
+	perf_session__delete(session);
+	return 0;
+}
+
 int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	const char * const stat_usage[] = {
@@ -1537,7 +1589,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	const char *mode;
 	FILE *output = stderr;
 	unsigned int interval;
-	const char * const stat_subcommands[] = { "record" };
+	const char * const stat_subcommands[] = { "record", "report" };
 
 	setlocale(LC_ALL, "");
 
@@ -1553,7 +1605,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		argc = __cmd_record(argc, argv);
 		if (argc < 0)
 			return -1;
-	}
+	} else if (argc && !strncmp(argv[0], "rep", 3))
+		return __cmd_report(argc, argv);
 
 	interval = stat_config.interval;
 
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294209 — [PATCH 03/43] perf thread_map: Add thread_map__new_event function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 03/43] perf thread_map: Add thread_map__new_event function
Message-ID<qGMSw-3Qg-51@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introducing the thread_map__new_event function to create a struct
thread_map object from a thread_map event.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-6-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/thread-map.c | 14 ++++++++++++++
 tools/perf/util/thread_map.c  | 27 +++++++++++++++++++++++++++
 tools/perf/util/thread_map.h  |  3 +++
 3 files changed, 44 insertions(+)

diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index ac5be2578367..fccde848fe9c 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -47,10 +47,24 @@ static int process_event(struct perf_tool *tool __maybe_unused,
 			 struct machine *machine __maybe_unused)
 {
 	struct thread_map_event *map = &event->thread_map;
+	struct thread_map *threads;
 
 	TEST_ASSERT_VAL("wrong nr",   map->nr == 1);
 	TEST_ASSERT_VAL("wrong pid",  map->entries[0].pid == (u64) getpid());
 	TEST_ASSERT_VAL("wrong comm", !strcmp(map->entries[0].comm, "perf"));
+
+	threads = thread_map__new_event(&event->thread_map);
+	TEST_ASSERT_VAL("failed to alloc map", threads);
+
+	TEST_ASSERT_VAL("wrong nr", threads->nr == 1);
+	TEST_ASSERT_VAL("wrong pid",
+			thread_map__pid(threads, 0) == getpid());
+	TEST_ASSERT_VAL("wrong comm",
+			thread_map__comm(threads, 0) &&
+			!strcmp(thread_map__comm(threads, 0), "perf"));
+	TEST_ASSERT_VAL("wrong refcnt",
+			atomic_read(&threads->refcnt) == 1);
+	thread_map__put(threads);
 	return 0;
 }
 
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 371fb28fe5b1..08afc6909953 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -13,6 +13,7 @@
 #include "thread_map.h"
 #include "util.h"
 #include "debug.h"
+#include "event.h"
 
 /* Skip "." and ".." directories */
 static int filter(const struct dirent *dir)
@@ -409,3 +410,29 @@ void thread_map__read_comms(struct thread_map *threads)
 	for (i = 0; i < threads->nr; ++i)
 		comm_init(threads, i);
 }
+
+static void thread_map__copy_event(struct thread_map *threads,
+				   struct thread_map_event *event)
+{
+	unsigned i;
+
+	threads->nr = (int) event->nr;
+
+	for (i = 0; i < event->nr; i++) {
+		thread_map__set_pid(threads, i, (pid_t) event->entries[i].pid);
+		threads->map[i].comm = strndup(event->entries[i].comm, 16);
+	}
+
+	atomic_set(&threads->refcnt, 1);
+}
+
+struct thread_map *thread_map__new_event(struct thread_map_event *event)
+{
+	struct thread_map *threads;
+
+	threads = thread_map__alloc(event->nr);
+	if (threads)
+		thread_map__copy_event(threads, event);
+
+	return threads;
+}
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index af679d8a50f8..85e4c7c4fbde 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -16,11 +16,14 @@ struct thread_map {
 	struct thread_map_data map[];
 };
 
+struct thread_map_event;
+
 struct thread_map *thread_map__new_dummy(void);
 struct thread_map *thread_map__new_by_pid(pid_t pid);
 struct thread_map *thread_map__new_by_tid(pid_t tid);
 struct thread_map *thread_map__new_by_uid(uid_t uid);
 struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
+struct thread_map *thread_map__new_event(struct thread_map_event *event);
 
 struct thread_map *thread_map__get(struct thread_map *map);
 void thread_map__put(struct thread_map *map);
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


#1294210 — [PATCH 16/43] perf tools: Add stat round event synthesize function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-12-17 21:00 +0100
Subject[PATCH 16/43] perf tools: Add stat round event synthesize function
Message-ID<qGMSw-3Qg-53@gated-at.bofh.it>
In reply to#1294191
From: Jiri Olsa <jolsa@kernel.org>

Introduce the perf_event__synthesize_stat_round function to
synthesize a 'struct stat_round_event'.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Kan Liang <kan.liang@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445784728-21732-19-git-send-email-jolsa@kernel.org
[ Renamed 'time' parameter to 'evtime' to fix build on older systems ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/stat.c         | 21 +++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/event.c         | 17 +++++++++++++++++
 tools/perf/util/event.h         |  4 ++++
 5 files changed, 47 insertions(+)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 4a7d9989e1c3..6a3519814492 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -196,6 +196,10 @@ static struct test generic_tests[] = {
 		.func = test__synthesize_stat,
 	},
 	{
+		.desc = "Test stat round synthesize",
+		.func = test__synthesize_stat_round,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
index d319875a5e7c..6a20ff2326bb 100644
--- a/tools/perf/tests/stat.c
+++ b/tools/perf/tests/stat.c
@@ -88,3 +88,24 @@ int test__synthesize_stat(int subtest __maybe_unused)
 
 	return 0;
 }
+
+static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
+				    union perf_event *event,
+				    struct perf_sample *sample __maybe_unused,
+				    struct machine *machine __maybe_unused)
+{
+	struct stat_round_event *stat_round = &event->stat_round;
+
+	TEST_ASSERT_VAL("wrong time", stat_round->time == 0xdeadbeef);
+	TEST_ASSERT_VAL("wrong type", stat_round->type == PERF_STAT_ROUND_TYPE__INTERVAL);
+	return 0;
+}
+
+int test__synthesize_stat_round(int subtest __maybe_unused)
+{
+	TEST_ASSERT_VAL("failed to synthesize stat_config",
+		!perf_event__synthesize_stat_round(NULL, 0xdeadbeef, PERF_STAT_ROUND_TYPE__INTERVAL,
+						   process_stat_round_event, NULL));
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index d36eda17a5f5..a82ab9c4c0ca 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -83,6 +83,7 @@ int test__thread_map_synthesize(int subtest);
 int test__cpu_map_synthesize(int subtest);
 int test__synthesize_stat_config(int subtest);
 int test__synthesize_stat(int subtest);
+int test__synthesize_stat_round(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 725db548c7d5..e4c68ba79974 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -933,6 +933,23 @@ int perf_event__synthesize_stat(struct perf_tool *tool,
 	return process(tool, (union perf_event *) &event, NULL, machine);
 }
 
+int perf_event__synthesize_stat_round(struct perf_tool *tool,
+				      u64 evtime, u64 type,
+				      perf_event__handler_t process,
+				      struct machine *machine)
+{
+	struct stat_round_event event;
+
+	event.header.type = PERF_RECORD_STAT_ROUND;
+	event.header.size = sizeof(event);
+	event.header.misc = 0;
+
+	event.time = evtime;
+	event.type = type;
+
+	return process(tool, (union perf_event *) &event, NULL, machine);
+}
+
 void perf_event__read_stat_config(struct perf_stat_config *config,
 				  struct stat_config_event *event)
 {
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 5eb4f55a141d..1afaa21eeebe 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -517,6 +517,10 @@ int perf_event__synthesize_stat(struct perf_tool *tool,
 				struct perf_counts_values *count,
 				perf_event__handler_t process,
 				struct machine *machine);
+int perf_event__synthesize_stat_round(struct perf_tool *tool,
+				      u64 time, u64 type,
+				      perf_event__handler_t process,
+				      struct machine *machine);
 int perf_event__synthesize_modules(struct perf_tool *tool,
 				   perf_event__handler_t process,
 				   struct machine *machine);
-- 
2.1.0

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

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web