2009-09-19 11:36:56

by Arjan van de Ven

[permalink] [raw]
Subject: [git pull] incremental updates to timechart

Hi Ingo,

a few incremental updates to timechart are now in my git tree; mostly based
on your review feedback. The individual patches will be sent as reply to this email


The following changes since commit a98c33c37d5973f2c4edeac7426b9a944d668fe1:
Ingo Molnar (1):
Merge branch 'tracing/urgent'

are available in the git repository at:

ssh://master.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-timechart master

Arjan van de Ven (5):
perf: Add "perf timechart record"
perf: Be consistent about minimum text size in the svghelper
trace: Move the end point of a C state in the power tracer
perf: Add timechart help text and add timechart to "perf help"
perf: Use a define for the maximum length of a trace event

arch/x86/kernel/process.c | 3 --
drivers/cpuidle/cpuidle.c | 2 +
tools/perf/Documentation/perf-timechart.txt | 35 ++++++++++++++++++++
tools/perf/builtin-timechart.c | 47 ++++++++++++++++++++++----
tools/perf/command-list.txt | 1 +
tools/perf/util/header.c | 7 ++--
tools/perf/util/svghelper.c | 24 +++++++------
7 files changed, 94 insertions(+), 25 deletions(-)
create mode 100644 tools/perf/Documentation/perf-timechart.txt


--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org


2009-09-19 11:36:28

by Arjan van de Ven

[permalink] [raw]
Subject: [PATCH] perf: Add "perf timechart record"


>From f11a27881ef0fcdf459e6f52dd57885c7af93426 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <[email protected]>
Date: Sat, 19 Sep 2009 12:59:47 +0200
Subject: [PATCH] perf: Add "perf timechart record"

Add a command line option to record a trace, similar to "perf sched record".

Signed-off-by: Arjan van de Ven <[email protected]>
---
tools/perf/builtin-timechart.c | 47 +++++++++++++++++++++++++++++++++------
1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 00fac1b..58d737e 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1086,11 +1086,42 @@ done:
return rc;
}

-static const char * const report_usage[] = {
- "perf report [<options>] <command>",
+static const char * const timechart_usage[] = {
+ "perf timechart [<options>] {record}",
NULL
};

+static const char *record_args[] = {
+ "record",
+ "-a",
+ "-R",
+ "-M",
+ "-f",
+ "-c", "1",
+ "-e", "power:power_start",
+ "-e", "power:power_end",
+ "-e", "power:power_frequency",
+ "-e", "sched:sched_wakeup",
+ "-e", "sched:sched_switch",
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+ unsigned int rec_argc, i, j;
+ const char **rec_argv;
+
+ rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+ rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+ for (i = 0; i < ARRAY_SIZE(record_args); i++)
+ rec_argv[i] = strdup(record_args[i]);
+
+ for (j = 1; j < (unsigned int)argc; j++, i++)
+ rec_argv[i] = argv[j];
+
+ return cmd_record(i, rec_argv, NULL);
+}
+
static const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file",
"input file name"),
@@ -1106,13 +1137,13 @@ int cmd_timechart(int argc, const char **argv, const char *prefix __used)

page_size = getpagesize();

- argc = parse_options(argc, argv, options, report_usage, 0);
+ argc = parse_options(argc, argv, options, timechart_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);

- /*
- * Any (unrecognized) arguments left?
- */
- if (argc)
- usage_with_options(report_usage, options);
+ if (argc && !strncmp(argv[0], "rec", 3))
+ return __cmd_record(argc, argv);
+ else if (argc)
+ usage_with_options(timechart_usage, options);

setup_pager();

--
1.6.0.6


--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org

2009-09-19 11:36:35

by Arjan van de Ven

[permalink] [raw]
Subject: [PATCH] perf: Be consistent about minimum text size in the svghelper

>From 18efabd499da9225cf7a83f54a91a6d5521c26a1 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <[email protected]>
Date: Sat, 19 Sep 2009 13:07:08 +0200
Subject: [PATCH] perf: Be consistent about minimum text size in the svghelper

Be more consistent in the svghelper about the minimum text size
by having a global #define for this.

There needs to be a minimum text size in order to keep the size
of the SVG file within the reach of what current SVG viewers can
cope with.

Signed-off-by: Arjan van de Ven <[email protected]>
---
tools/perf/util/svghelper.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index c7a29af..b0fcecd 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -27,6 +27,8 @@ static u64 turbo_frequency, max_freq;
#define SLOT_HEIGHT 25.0
#define WIDTH 1000.0

+#define MIN_TEXT_SIZE 0.001
+
static u64 total_height;
static FILE *svgfile;

@@ -104,8 +106,8 @@ void svg_sample(int Yslot, int cpu, u64 start, u64 end, const char *type)
text_size = text_size/2;
if (text_size > 1.25)
text_size = 1.25;
- if (text_size > 0.0001)
- fprintf(svgfile, "<text transform=\"translate(%1.6f,%1.6f)\" font-size=\"%1.6fpt\">%i</text>\n",
+ if (text_size > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%1.8f,%1.8f)\" font-size=\"%1.6fpt\">%i</text>\n",
time2pixels(start), Yslot * SLOT_MULT + SLOT_HEIGHT - 1, text_size, cpu + 1);

}
@@ -146,10 +148,10 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);

sprintf(cpu_string, "CPU %i", (int)cpu+1);
- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\">%s</text>\n",
10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string);

- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\" font-size=\"1.25pt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"1.25pt\">%s</text>\n",
10+time2pixels(first_time), cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - 4, cpu_model());
}

@@ -166,8 +168,8 @@ void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name
if (width > 6)
width = 6;

- if (width > 0.001)
- fprintf(svgfile, "<text transform=\"translate(%4.5f,%4.5f) rotate(90)\" font-size=\"%3.4fpt\">%s</text>\n",
+ if (width > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f) rotate(90)\" font-size=\"%3.4fpt\">%s</text>\n",
time2pixels(start), cpu2y(cpu), width, name);
}

@@ -193,8 +195,8 @@ void svg_cstate(int cpu, u64 start, u64 end, int type)
if (width > 6)
width = 6;

- if (width > 0.05)
- fprintf(svgfile, "<text transform=\"translate(%4.5f,%4.5f) rotate(90)\" font-size=\"%3.4fpt\">C%i</text>\n",
+ if (width > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f) rotate(90)\" font-size=\"%3.4fpt\">C%i</text>\n",
time2pixels(start), cpu2y(cpu), width, type);
}

@@ -234,7 +236,7 @@ void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
height = 1 + cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - height;
fprintf(svgfile, "<line x1=\"%4.8f\" x2=\"%4.8f\" y1=\"%4.1f\" y2=\"%4.1f\" class=\"pstate\"/>\n",
time2pixels(start), time2pixels(end), height, height);
- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\" font-size=\"0.25pt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"0.25pt\">%s</text>\n",
time2pixels(start), height+0.9, HzToHuman(freq));

}
@@ -311,7 +313,7 @@ void svg_text(int Yslot, u64 start, const char *text)
if (!svgfile)
return;

- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\">%s</text>\n",
time2pixels(start), Yslot * SLOT_MULT+SLOT_HEIGHT/2, text);
}

@@ -322,7 +324,7 @@ static void svg_legenda_box(int X, const char *text, const char *style)

fprintf(svgfile, "<rect x=\"%i\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
X, boxsize, boxsize, style);
- fprintf(svgfile, "<text transform=\"translate(%4.1f, %4.1f)\" font-size=\"%4.4fpt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f, %4.8f)\" font-size=\"%4.4fpt\">%s</text>\n",
X + boxsize + 5, boxsize, 0.8 * boxsize, text);
}

--
1.6.0.6




--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org

2009-09-19 11:36:42

by Arjan van de Ven

[permalink] [raw]
Subject: [PATCH] trace: Move the end point of a C state in the power tracer

>From c1ffb79a8e87501ccaf269517566f438220f1c49 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <[email protected]>
Date: Sat, 19 Sep 2009 13:09:16 +0200
Subject: [PATCH] trace: Move the end point of a C state in the power tracer

The "end of a C state" trace point currently happens before
the code runs that corrects the TSC for having stopped during idle.
The result of this is that the timestamp of the end-of-C-state event
is garbage on cpus where the TSC stops during idle.

This patch moves the end point of the C state to after the timekeeping
engine of the kernel has been corrected.

Signed-off-by: Arjan van de Ven <[email protected]>
---
arch/x86/kernel/process.c | 3 ---
drivers/cpuidle/cpuidle.c | 2 ++
2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 98e9cac..230d054 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -299,7 +299,6 @@ void default_idle(void)
else
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
- trace_power_end(0);
} else {
local_irq_enable();
/* loop is done by the caller */
@@ -367,7 +366,6 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
if (!need_resched())
__mwait(ax, cx);
}
- trace_power_end(0);
}

/* Default MONITOR/MWAIT with no hints, used for default C1 state */
@@ -384,7 +382,6 @@ static void mwait_idle(void)
__sti_mwait(0, 0);
else
local_irq_enable();
- trace_power_end(0);
} else
local_irq_enable();
}
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 8504a21..ad41f19 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -17,6 +17,7 @@
#include <linux/cpuidle.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
+#include <trace/events/power.h>

#include "cpuidle.h"

@@ -91,6 +92,7 @@ static void cpuidle_idle_call(void)
/* give the governor an opportunity to reflect on the outcome */
if (cpuidle_curr_governor->reflect)
cpuidle_curr_governor->reflect(dev);
+ trace_power_end(0);
}

/**
--
1.6.0.6




--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org

2009-09-19 11:36:43

by Arjan van de Ven

[permalink] [raw]
Subject: [PATCH] perf: Add timechart help text and add timechart to "perf help"


>From 880307a7ee6136aca34ca0fc71bab544723829c9 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <[email protected]>
Date: Sat, 19 Sep 2009 13:17:57 +0200
Subject: [PATCH] perf: Add timechart help text and add timechart to "perf help"

As suggested by Ingo, add a timechart man page help text, as well
as add it to the "perf help" overview.

Signed-off-by: Arjan van de Ven <[email protected]>
---
tools/perf/Documentation/perf-timechart.txt | 35 +++++++++++++++++++++++++++
tools/perf/command-list.txt | 1 +
2 files changed, 36 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/Documentation/perf-timechart.txt

diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
new file mode 100644
index 0000000..61e0104
--- /dev/null
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -0,0 +1,35 @@
+perf-timechart(1)
+=================
+
+NAME
+----
+perf-timechart - Tool to visualize total system behavior during a workload
+
+SYNOPSIS
+--------
+[verse]
+'perf timechart' {record}
+
+DESCRIPTION
+-----------
+There are two variants of perf timechart:
+
+ 'perf timechart record <command>' to record the system level events
+ of an arbitrary workload.
+
+ 'perf timechart' to turn a trace into a Scalable Vector Graphics file,
+ that can be viewed with popular SVG viewers such as 'Inkscape'.
+
+OPTIONS
+-------
+-o::
+--output=::
+ Select the output file (default: output.svg)
+-i::
+--input=::
+ Select the input file (default: perf.data)
+
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 3133c74..00326e2 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -8,5 +8,6 @@ perf-sched mainporcelain common
perf-record mainporcelain common
perf-report mainporcelain common
perf-stat mainporcelain common
+perf-timechart mainporcelain common
perf-top mainporcelain common
perf-trace mainporcelain common
--
1.6.0.6


--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org

2009-09-19 11:37:25

by Arjan van de Ven

[permalink] [raw]
Subject: [PATCH] perf: Use a define for the maximum length of a trace event

From e5f5037ae4423c188aa68ee6ba239708bb720722 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <[email protected]>
Date: Sat, 19 Sep 2009 13:21:20 +0200
Subject: [PATCH] perf: Use a define for the maximum length of a trace event

As per Ingo's review: use a #define rather than an open coded constant
for the maximum length of a trace event for storing in the perf.data file.

Signed-off-by: Arjan van de Ven <[email protected]>
---
tools/perf/util/header.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ef91145..ed6b553 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -86,9 +86,10 @@ void perf_header__add_attr(struct perf_header *self,
self->attr[pos] = attr;
}

+#define MAX_EVENT_NAME 64
struct perf_trace_event_type {
u64 event_id;
- char name[64];
+ char name[MAX_EVENT_NAME];
};

static int event_count;
@@ -96,7 +97,7 @@ static struct perf_trace_event_type *events;

void perf_header__push_event(u64 id, const char *name)
{
- if (strlen(name) > 64)
+ if (strlen(name) > MAX_EVENT_NAME)
printf("Event %s will be truncated\n", name);

if (!events) {
@@ -110,7 +111,7 @@ void perf_header__push_event(u64 id, const char *name)
}
memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
events[event_count].event_id = id;
- strncpy(events[event_count].name, name, 63);
+ strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
event_count++;
}

--
1.6.0.6




--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org

2009-09-19 17:01:28

by Arjan van de Ven

[permalink] [raw]
Subject: [tip:perfcounters/core] perf timechart: Add "perf timechart record"

Commit-ID: 3c09eebd61eaacca866cd60b50416f18640bc731
Gitweb: http://git.kernel.org/tip/3c09eebd61eaacca866cd60b50416f18640bc731
Author: Arjan van de Ven <[email protected]>
AuthorDate: Sat, 19 Sep 2009 13:34:42 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sat, 19 Sep 2009 18:57:51 +0200

perf timechart: Add "perf timechart record"

Add a command line option to record a trace, similar to "perf sched record".

Signed-off-by: Arjan van de Ven <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Paul Mackerras <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
tools/perf/builtin-timechart.c | 47 +++++++++++++++++++++++++++++++++------
1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 00fac1b..58d737e 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1086,11 +1086,42 @@ done:
return rc;
}

-static const char * const report_usage[] = {
- "perf report [<options>] <command>",
+static const char * const timechart_usage[] = {
+ "perf timechart [<options>] {record}",
NULL
};

+static const char *record_args[] = {
+ "record",
+ "-a",
+ "-R",
+ "-M",
+ "-f",
+ "-c", "1",
+ "-e", "power:power_start",
+ "-e", "power:power_end",
+ "-e", "power:power_frequency",
+ "-e", "sched:sched_wakeup",
+ "-e", "sched:sched_switch",
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+ unsigned int rec_argc, i, j;
+ const char **rec_argv;
+
+ rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+ rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+ for (i = 0; i < ARRAY_SIZE(record_args); i++)
+ rec_argv[i] = strdup(record_args[i]);
+
+ for (j = 1; j < (unsigned int)argc; j++, i++)
+ rec_argv[i] = argv[j];
+
+ return cmd_record(i, rec_argv, NULL);
+}
+
static const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file",
"input file name"),
@@ -1106,13 +1137,13 @@ int cmd_timechart(int argc, const char **argv, const char *prefix __used)

page_size = getpagesize();

- argc = parse_options(argc, argv, options, report_usage, 0);
+ argc = parse_options(argc, argv, options, timechart_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);

- /*
- * Any (unrecognized) arguments left?
- */
- if (argc)
- usage_with_options(report_usage, options);
+ if (argc && !strncmp(argv[0], "rec", 3))
+ return __cmd_record(argc, argv);
+ else if (argc)
+ usage_with_options(timechart_usage, options);

setup_pager();

2009-09-19 17:01:34

by Arjan van de Ven

[permalink] [raw]
Subject: [tip:perfcounters/core] perf utils: Be consistent about minimum text size in the svghelper

Commit-ID: 964a0b3d2b1b1cac1d01e29b635831b3d92a3fdd
Gitweb: http://git.kernel.org/tip/964a0b3d2b1b1cac1d01e29b635831b3d92a3fdd
Author: Arjan van de Ven <[email protected]>
AuthorDate: Sat, 19 Sep 2009 13:35:07 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sat, 19 Sep 2009 18:57:52 +0200

perf utils: Be consistent about minimum text size in the svghelper

Be more consistent in the svghelper about the minimum text size
by having a global #define for this.

There needs to be a minimum text size in order to keep the size
of the SVG file within the reach of what current SVG viewers can
cope with.

Signed-off-by: Arjan van de Ven <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Paul Mackerras <[email protected]>
Cc: Arjan van de Ven <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
tools/perf/util/svghelper.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index c7a29af..b0fcecd 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -27,6 +27,8 @@ static u64 turbo_frequency, max_freq;
#define SLOT_HEIGHT 25.0
#define WIDTH 1000.0

+#define MIN_TEXT_SIZE 0.001
+
static u64 total_height;
static FILE *svgfile;

@@ -104,8 +106,8 @@ void svg_sample(int Yslot, int cpu, u64 start, u64 end, const char *type)
text_size = text_size/2;
if (text_size > 1.25)
text_size = 1.25;
- if (text_size > 0.0001)
- fprintf(svgfile, "<text transform=\"translate(%1.6f,%1.6f)\" font-size=\"%1.6fpt\">%i</text>\n",
+ if (text_size > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%1.8f,%1.8f)\" font-size=\"%1.6fpt\">%i</text>\n",
time2pixels(start), Yslot * SLOT_MULT + SLOT_HEIGHT - 1, text_size, cpu + 1);

}
@@ -146,10 +148,10 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);

sprintf(cpu_string, "CPU %i", (int)cpu+1);
- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\">%s</text>\n",
10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string);

- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\" font-size=\"1.25pt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"1.25pt\">%s</text>\n",
10+time2pixels(first_time), cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - 4, cpu_model());
}

@@ -166,8 +168,8 @@ void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name
if (width > 6)
width = 6;

- if (width > 0.001)
- fprintf(svgfile, "<text transform=\"translate(%4.5f,%4.5f) rotate(90)\" font-size=\"%3.4fpt\">%s</text>\n",
+ if (width > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f) rotate(90)\" font-size=\"%3.4fpt\">%s</text>\n",
time2pixels(start), cpu2y(cpu), width, name);
}

@@ -193,8 +195,8 @@ void svg_cstate(int cpu, u64 start, u64 end, int type)
if (width > 6)
width = 6;

- if (width > 0.05)
- fprintf(svgfile, "<text transform=\"translate(%4.5f,%4.5f) rotate(90)\" font-size=\"%3.4fpt\">C%i</text>\n",
+ if (width > MIN_TEXT_SIZE)
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f) rotate(90)\" font-size=\"%3.4fpt\">C%i</text>\n",
time2pixels(start), cpu2y(cpu), width, type);
}

@@ -234,7 +236,7 @@ void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
height = 1 + cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - height;
fprintf(svgfile, "<line x1=\"%4.8f\" x2=\"%4.8f\" y1=\"%4.1f\" y2=\"%4.1f\" class=\"pstate\"/>\n",
time2pixels(start), time2pixels(end), height, height);
- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\" font-size=\"0.25pt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"0.25pt\">%s</text>\n",
time2pixels(start), height+0.9, HzToHuman(freq));

}
@@ -311,7 +313,7 @@ void svg_text(int Yslot, u64 start, const char *text)
if (!svgfile)
return;

- fprintf(svgfile, "<text transform=\"translate(%4.1f,%4.1f)\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\">%s</text>\n",
time2pixels(start), Yslot * SLOT_MULT+SLOT_HEIGHT/2, text);
}

@@ -322,7 +324,7 @@ static void svg_legenda_box(int X, const char *text, const char *style)

fprintf(svgfile, "<rect x=\"%i\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
X, boxsize, boxsize, style);
- fprintf(svgfile, "<text transform=\"translate(%4.1f, %4.1f)\" font-size=\"%4.4fpt\">%s</text>\n",
+ fprintf(svgfile, "<text transform=\"translate(%4.8f, %4.8f)\" font-size=\"%4.4fpt\">%s</text>\n",
X + boxsize + 5, boxsize, 0.8 * boxsize, text);
}

2009-09-19 17:01:44

by Arjan van de Ven

[permalink] [raw]
Subject: [tip:perfcounters/core] tracing, x86, cpuidle: Move the end point of a C state in the power tracer

Commit-ID: 288f023e708efd89d77ce9acf977a33a623ae83d
Gitweb: http://git.kernel.org/tip/288f023e708efd89d77ce9acf977a33a623ae83d
Author: Arjan van de Ven <[email protected]>
AuthorDate: Sat, 19 Sep 2009 13:35:33 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sat, 19 Sep 2009 18:57:52 +0200

tracing, x86, cpuidle: Move the end point of a C state in the power tracer

The "end of a C state" trace point currently happens before
the code runs that corrects the TSC for having stopped during idle.

The result of this is that the timestamp of the end-of-C-state event
is garbage on cpus where the TSC stops during idle.

This patch moves the end point of the C state to after the timekeeping
engine of the kernel has been corrected.

Signed-off-by: Arjan van de Ven <[email protected]>
Cc: Len Brown <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Paul Mackerras <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
arch/x86/kernel/process.c | 3 ---
drivers/cpuidle/cpuidle.c | 2 ++
2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 7b60e39..847ab41 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -309,7 +309,6 @@ void default_idle(void)
else
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
- trace_power_end(0);
} else {
local_irq_enable();
/* loop is done by the caller */
@@ -377,7 +376,6 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
if (!need_resched())
__mwait(ax, cx);
}
- trace_power_end(0);
}

/* Default MONITOR/MWAIT with no hints, used for default C1 state */
@@ -394,7 +392,6 @@ static void mwait_idle(void)
__sti_mwait(0, 0);
else
local_irq_enable();
- trace_power_end(0);
} else
local_irq_enable();
}
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 8504a21..ad41f19 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -17,6 +17,7 @@
#include <linux/cpuidle.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
+#include <trace/events/power.h>

#include "cpuidle.h"

@@ -91,6 +92,7 @@ static void cpuidle_idle_call(void)
/* give the governor an opportunity to reflect on the outcome */
if (cpuidle_curr_governor->reflect)
cpuidle_curr_governor->reflect(dev);
+ trace_power_end(0);
}

/**

2009-09-19 17:02:10

by Arjan van de Ven

[permalink] [raw]
Subject: [tip:perfcounters/core] perf: Add timechart help text and add timechart to "perf help"

Commit-ID: 151750cec5db3c7ea45255d2901e581e2162317a
Gitweb: http://git.kernel.org/tip/151750cec5db3c7ea45255d2901e581e2162317a
Author: Arjan van de Ven <[email protected]>
AuthorDate: Sat, 19 Sep 2009 13:36:04 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sat, 19 Sep 2009 18:57:53 +0200

perf: Add timechart help text and add timechart to "perf help"

As suggested by Ingo, add a timechart man page help text, as well
as add it to the "perf help" overview.

Signed-off-by: Arjan van de Ven <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Paul Mackerras <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
tools/perf/Documentation/perf-timechart.txt | 35 +++++++++++++++++++++++++++
tools/perf/command-list.txt | 1 +
2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
new file mode 100644
index 0000000..61e0104
--- /dev/null
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -0,0 +1,35 @@
+perf-timechart(1)
+=================
+
+NAME
+----
+perf-timechart - Tool to visualize total system behavior during a workload
+
+SYNOPSIS
+--------
+[verse]
+'perf timechart' {record}
+
+DESCRIPTION
+-----------
+There are two variants of perf timechart:
+
+ 'perf timechart record <command>' to record the system level events
+ of an arbitrary workload.
+
+ 'perf timechart' to turn a trace into a Scalable Vector Graphics file,
+ that can be viewed with popular SVG viewers such as 'Inkscape'.
+
+OPTIONS
+-------
+-o::
+--output=::
+ Select the output file (default: output.svg)
+-i::
+--input=::
+ Select the input file (default: perf.data)
+
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 3133c74..00326e2 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -8,5 +8,6 @@ perf-sched mainporcelain common
perf-record mainporcelain common
perf-report mainporcelain common
perf-stat mainporcelain common
+perf-timechart mainporcelain common
perf-top mainporcelain common
perf-trace mainporcelain common

2009-09-19 17:02:21

by Arjan van de Ven

[permalink] [raw]
Subject: [tip:perfcounters/core] perf utils: Use a define for the maximum length of a trace event

Commit-ID: ec60a3fe478c0fc6d109eb5840b435ecee4d132b
Gitweb: http://git.kernel.org/tip/ec60a3fe478c0fc6d109eb5840b435ecee4d132b
Author: Arjan van de Ven <[email protected]>
AuthorDate: Sat, 19 Sep 2009 13:36:30 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sat, 19 Sep 2009 18:57:53 +0200

perf utils: Use a define for the maximum length of a trace event

As per Ingo's review: use a #define rather than an open coded constant
for the maximum length of a trace event for storing in the perf.data file.

Signed-off-by: Arjan van de Ven <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Paul Mackerras <[email protected]>
LKML-Reference: <[email protected]>
[ add a few comments to nearby functions ]
Signed-off-by: Ingo Molnar <[email protected]>


---
tools/perf/util/header.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ef91145..bb4fca3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -7,9 +7,8 @@
#include "header.h"

/*
- *
+ * Create new perf.data header attribute:
*/
-
struct perf_header_attr *perf_header_attr__new(struct perf_counter_attr *attr)
{
struct perf_header_attr *self = malloc(sizeof(*self));
@@ -43,9 +42,8 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
}

/*
- *
+ * Create new perf.data header:
*/
-
struct perf_header *perf_header__new(void)
{
struct perf_header *self = malloc(sizeof(*self));
@@ -86,9 +84,11 @@ void perf_header__add_attr(struct perf_header *self,
self->attr[pos] = attr;
}

+#define MAX_EVENT_NAME 64
+
struct perf_trace_event_type {
u64 event_id;
- char name[64];
+ char name[MAX_EVENT_NAME];
};

static int event_count;
@@ -96,7 +96,7 @@ static struct perf_trace_event_type *events;

void perf_header__push_event(u64 id, const char *name)
{
- if (strlen(name) > 64)
+ if (strlen(name) > MAX_EVENT_NAME)
printf("Event %s will be truncated\n", name);

if (!events) {
@@ -110,7 +110,7 @@ void perf_header__push_event(u64 id, const char *name)
}
memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
events[event_count].event_id = id;
- strncpy(events[event_count].name, name, 63);
+ strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
event_count++;
}